본문 바로가기

Java

TDD방법론 - 암호검사기1(전체적인 틀)

- 기존 개발방식: 설계-구현-테스트

한번에 작성한 구현코드가 많은경우 오류발생시 디버깅시간도 길어진다.

구현시간보다 디버깅시간이 더 길어질때도 많다.

POJO클래스가 아닌 톰캣이나 Spring기반 클래스일경우 매번 서버연결의 과정도 거쳐야한다.

- TDD(Test-Driven-Development): 테스트케이스를 먼저 작성, 실제 구현으로 테스트를 통과하게 짜기 전에

일단 테스트를 통과하게끔 값을 직접 지정한다.

 

TDD예제: 암호 검사기 구현하기

규칙:

- 길이가 8글자 이상

- 0~9사이의 숫자를 포함

- 대문자 포함

3개조건 모두 충족시 암호등급 '강함'

2개조건 충족시 '보통'

1개조건 or 충족하는 조건이 없을때 '약함'

 

테스트 1: 가장 쉽거나 가장 예외적인 상황부터 테스트

 - 모든 규칙 충족할 경우

 - 모든 규칙을 충족하지 않을 경우

모든 규칙을 충족하지 않는 테스트를 통과시키려면 각 조건을 검사하는 코드를 모두 구현해야하기 때문에

사실상 구현-테스트 순서와 다를게 없다.

모든 규칙을 충족할 경우는 각 조건의 구현은 비워두고 '강함'에 해당하는 값을 리턴하게만 만들면 

테스트는 통과할수 있다.

 

import org.junit.jupiter.api.Test;

import
 static org.junit.jupiter.api.Assertions.*;
 
public class PasswordStrengthMeterTest {
    @Test
@DisplayName("모든 규칙을 충족하는 경우")
    void meetsAllCriteria_Then_Strong() {
        PasswordStrengthMeter meter = new PasswordStrengthMeter();
        결과 = meter.meter("12!@abAB");
        assertEquals(기대값, 결과);
 
    }
 
cs

 

구현클래스와 메소드의 이름만 정하고 테스트케이스의 틀을 잡는다.

 

다음으로 meter메소드의 리턴타입을 결정해야 한다.

약함 보통 강함을 0, 1, 2 이런식을 int값을 부여해서 쓸 수도 있지만 직관성이 떨어지므로

좀더 직관적인 enum타입을 생성해서 사용한다.

 

public enum PasswordStrength {
   STRONG, NORMAL, WEAK
}
 
cs

 

import org.junit.jupiter.api.Test;
 
import static org.junit.jupiter.api.Assertions.*;
 
public class PasswordStrengthMeterTest {
    @Test
@DisplayName("모든 규칙을 충족하는 경우")
    void Strong() {
        PasswordStrengthMeter meter = new PasswordStrengthMeter();
        PasswordStrength result = meter.meter("12!@abAB");
       assertEquals(PasswordStrength.STRONG, result);
 
    }
}
 
cs

 

이제 컴파일을 하기위해 PasswordStrengthMeter클래스(추후 구현부가될)와 이 클래스의 메소드 meter()를 만들어준다.

 

public class PasswordStrengthMeter {
    public PasswordStrength meter(String s) {
        return null;
    }
}
 
 
cs

 

현재 목적은 실행이 불가능한 코드를 실행할수 있게끔만 해주는것이다.

 

실패

 

 

실행결과는 당연히 실패...여기서 테스트결과를 성공시키기 가장 단순한 방법으로 간다.

오류메시지에 따르면 return값만 STRONG enum타입이면 테스트는 성공할것이다.

 

public class PasswordStrengthMeter {
    public PasswordStrength meter(String s) {
        return PasswordStrength.STRONG;
    }
}
 
cs

 

return값만 null에서 STRONG으로 수정했다.

 

(어쨌든)성공

 

핵심은 로직 구현 전에 테스트코드가 통과될수 있게 최소한의 코드만 작성하는것이다.