한번에 얼마만큼의 코드를 작성 할 것인가?
TDD를 처음 접할 때는 다음 단계에 따라 익히는 것이 추천된다.
예를 들어 암호 강도 측정 기능에서 길이가 8글자 미만이지만 나머지 규칙은 충족하는 상황을 위 단계를 밟아 진행해보자. 먼저 다음 테스트 코드를 추가했다.
@Test
void passTwoReqExceptLengthThenNormal2(){
PasswordStrengthCheck check = new PasswordStrengthCheck();
PasswordStrength result = check.check("ab12!@A");
assertEquals(PasswordStrength.NORMAL, result);
}
딱 이 테스트를 통과할 만큼만 코드를 작성하자.
public class PasswordStrengthCheck {
public PasswordStrength check(String s){
if("ab12!@A".equals(s)) {
return PasswordStrength.NORMAL;
}
return PasswordStrength.STRONG;
}
}
상수를 비교해서 테스트를 통과시켰다. 다음으로 동일한 조건을 검증하기 위한 테스트를 추가한다.
@Test
void passTwoReqExceptLengthThenNormal2(){
PasswordStrengthCheck check = new PasswordStrengthCheck();
PasswordStrength result = check.check("ab12!@A");
assertEquals(PasswordStrength.NORMAL, result);
PasswordStrength result2 = check.check("Ab12!c");
assertEquals(PasswordStrength.NORMAL, result2);
}
새로 추가한 테스트를 통과시키려면 다음과 같이 값 비교를 추가하면 된다.
public class PasswordStrengthCheck {
public PasswordStrength check(String s){
if("ab12!@A".equals(s)) || "Ab12!c".equals(s)) {
return PasswordStrength.NORMAL;
}
return PasswordStrength.STRONG;
}
}
이번에도 상수를 이용해서 통과시켰다. 다음 차례는 상수를 제거하고 일반화하는 것이다. 다음은 위 코드에서 상수를 제거하고 일반화한 결과이다.
public class PasswordStrengthCheck {
public PasswordStrength check(String s){
if(s.length() < 8) {
return PasswordStrength.NORMAL;
}
return PasswordStrength.STRONG;
}
}
몇 차례 상수를 사용해서 테스트를 통과시키고 뒤에 구현을 일반화하는 과정이 처음에는 지루하게 느껴질 수도 있지만, 이런 연습 과정은 나중에 만들어야 할 코드가 잘 떠오르지 않을 때 점진적으로 구현을 진행할 수 있는 밑거름이 된다.
TDD가 익숙해지면 상황에 따라 구현 속도를 조절할 수 있게 된다. 단순 덧셈이나 길이 비교와 같은 명백한 구현은 상수를 사용하지 않고 바로 구현하고 한 번에 구현을 시도했는데 잘 안되면 한발 물러서서 천천히 단계를 밟아나가자.
테스트 통과 후에는 리팩토링을 진행한다. 매번 리팩토링을 진행해야 하는 건 아니지만 적당한 후보가 보이면 진행하는 것이 좋다. 코드 중복은 대표적인 리팩토링 대상이다. 코드가 길어지면 메서드 추출과 같은 기법을 사용해서 메서드 이름으로 코드의 의미를 표현할 수 있다.
TDD를 진행하는 과정에서 지속적으로 리팩토링을 진행하면 코드 가독성 또한 높아진다. 이는 유지보수에 도움이 된다.
일단 동작하는 코드를 만드는 능력은 중요하다. 코드가 동작하지 않으면 아무것도 소용없다.
하지만 소프트웨어의 생존 시간이 길어질수록 소프트웨어를 지속적으로 개선해야 한다.
코드 변경이 어려우면 변화하는 요구를 제때 반영할 수 없게 되며 이는 소프트웨어의 생존과 직결된다. 따라서 코드를 잘 변경할 수 있는 능력 또한 매우 중요하다.
코드를 잘 변경하려면 변경하기 쉬운 구조를 가져야 하는데, 이를 위한 것이 바로 리팩토링이다.
상수를 변수로 바꾸거나 변수 이름을 변경하는 것과 같은 작은 리팩토링은 발견 시 바로 실행한다.
메서드 추출과 같이 메서드의 구조에 영향을 주는 리팩토링은 큰 틀에서 구현 흐름이 눈에 들어오기 시작한 뒤에 진행한다.