코드에대한 문서화
코드에 대한 결함을 발견하기 위함
리팩토링 시 안정성 확보
Test Driven Development
프로덕션 코드보다 테스트코드를 먼저 작성하는 개발 방법
TFD(Test First Development) + Refactoring
기능 동작을 먼저 검증 (메소드 단위)
Behavior Driven Development
시나리오 기반으로 테스트코드를 작성하는 방법
하나의 시나리오는 Given / When / Then 구조
비밀번호는 최소 9자 이상 15자 이하
비밀번호가 9자 미만 또는 15자 초과인경우 Exception ㅂ라생
경계조건 확인
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
testImplementation 'org.assertj:assertj-core:3.23.1'
}
test {
useJUnitPlatform()
}
테스트코드의 패키지의 위치와, main 소스의 패키지의 위치가 동일하게 생성되면 좋다
테스트코드에서 요구조건을 먼저 실현하고, 실현한 요구조건에서 실제 코드에 반영되지 않은 부분들을 하나씩 만들어가며 작업
package org.example;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThatCode;
/**
* 비밀번호는 최소 9자 이상 15자 이하
* 비밀번호가 9자 미만 또는 15자 초과인경우 Exception ㅂ라생
* 경계조건 확인
*/
public class PasswordValidatorTest {
@ DisplayName ( "비밀번호가 최소 9자 이상 15자 이하면 정상" ) // 테스트 의도
@ Test
void validatePasswordTest () {
assertThatCode (() -> PasswordValidator. validate ( "123456789" ))
. doesNotThrowAnyException ();
}
}
작성 한 후, PasswordValidator 클래스에 붉은줄이 생성됨
PasswordValidator를 main source에 생성
PasswordValidator 클래스에 validate 메소드를 생성
package org.example;
public class PasswordValidator {
public static void validate (String password ) {
}
}
테스트 진행 -> 성공
입력된 문자열이 9자 이상 15자 이하인지 확인하고, 아니라면 Exception 발생 코드 작성
package org.example;
public class PasswordValidator {
public static final String WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE = "비밀번호는 최소 9자 이상 15자 이하입니다." ;
public static void validate (String password ) {
int length = password. length ();
if (length < 9 || length > 15 ) {
throw new IllegalArgumentException (WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE);
}
}
}
위와 같은방법으로, TestCode에서 먼저 시도하고 실제 코드에 하나씩 반영하는 방법
이미 Exception 관련 내용을 작성했기 때문에 크게 수정 할 내용이 없다 조건만 테스트
public class PasswordValidatorTest {
@ DisplayName ( "비밀번호가 9자 미만인 경우 Exception 발생" )
@ Test
void validatePasswordShortExceptionTest () {
assertThatCode (() -> PasswordValidator. validate ( "1234" ))
. isInstanceOf (IllegalArgumentException.class)
. hasMessageContaining (PasswordValidator.WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE);
}
}
위와 같은방법으로, TestCode에서 먼저 시도하고 실제 코드에 하나씩 반영하는 방법
이미 Exception 관련 내용을 작성했기 때문에 크게 수정 할 내용이 없다 조건만 테스트
public class PasswordValidatorTest {
@ DisplayName ( "비밀번호가 15자 초과인 경우 Exception 발생" )
@ Test
void validatePasswordLongExceptionTest () {
assertThatCode (() -> PasswordValidator. validate ( "1234512345123456" ))
. isInstanceOf (IllegalArgumentException.class)
. hasMessageContaining (PasswordValidator.WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE);
}
}
우리의 요구조건에 부합하는 비밀번호의 길이는 9자 이상 15자 이하이다.
위의 조건에대한 경계값은 비밀번호가 8자, 혹은 16자 일 경우이다
경계값에 대한 테스트를 추가 해 주면 좋은 테스트를 작성할 수 있다.
@Parameterize 를 추가하여 테스트 해 보자
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.0'
public class PasswordValidatorTest {
@ DisplayName ( "경계조건에 대해 테스트" )
@ ParameterizedTest
@ ValueSource ( strings = { "12345678" , "1234567890123456" })
void validatePasswordBoundaryTest (String password ) {
assertThatCode (() -> PasswordValidator. validate (password))
. isInstanceOf (IllegalArgumentException.class)
. hasMessageContaining (PasswordValidator.WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE);
}
}
ValueSource 내에 들어가있는 값들을 자동으로 바꿔가며 실행시켜 준다
ValueSource 내에 선언된 데이터를 함수에서 하나씩 받아 줄 수 있다
실행을 해 보면, 다른 테스트와는 다르게 테스트가 두번 돌아간다