본문 바로가기
카테고리 없음

[TDD] 테스트 코드 작성의 필요성과 작성 방법

by cook_code 2023. 3. 28.
반응형

테스트 코드를 작성하는 이유?


1. 문서화 역할
2. 코드에 결함을 발견하기 위함
3. 리팩토링 시 안정성 확보
4. 테스트 하기 쉬운 코드를 작성하다 보면 더 낮은 결합도를 가진 설계를 얻을 수 있음

TDD


• Test Driven Development (테스트 주도 개발)
• 프로덕션 코드보다 테스트 코드를 먼저 작성하는 개발 방법
• 기능 동작을 검증 (메서드 단위)



BDD

  
• Behavior Driven Development (행위 주도 개발) 
• 행위에 대한 테스트 코드를 작성하는 개발 방법  
• 유저 시나리오 동작을 검증 (시나리오 단위)
• 하나의 시나리오는 Given, When, Then 구조를 가짐


1. BDD의 정의 

책임 관계자의 관점에서 보는 애플리케이션의 행위(동작) 중 가치있는 기능부터 개발하는 방식 

2. BDD의 특징 

1) 사용자(고객)에 좀 더 가까운, 고객이 요구하는 고수준의 기능을 우선적으로 고려한다.

2) 무엇을 테스트 할 것인가?

"현재 시스템에 들어 있지 않은 기능 중 가장 먼저 구현되어야 하는 기능은 무엇인가?"

3) 선조건, 동작, 결과를 구분지어 생각하도록 유도

(given/when/then)

 

비밀번호 유효성 검증기

  • 테스트 코드 
package org.example;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import static org.assertj.core.api.Assertions.assertThatCode;

public class PasswordValidatorTest {
    /*
    * 비밀번호 유효성 검증기
    - 요구사항
    1. 비밀번호는 최소 8자 이상 12자 이하여야 한다.
    2. 비밀번호가 8자 미만 또는 12자 초과인 경우 IllegalArgumentException 예외를 발생시킨다.
    3. 경계조건에 대해 테스트 코드를 작성해야 한다.
    */

    @DisplayName("비밀번호는 최소 8자 이상 12자 이하면 에러가 발생하지 않는다.")
    @Test
    void validatePasswordTest(){
        assertThatCode(()-> PasswordValidator.validate("serverWizard"))
                .doesNotThrowAnyException();
    }
    @DisplayName("비밀번호가 8자 미만 또는 12자 초과하는 경우, IllegalArgumentException 에러가 발생한다.")
    @ParameterizedTest
    @ValueSource(strings = {"aabbccc", "aabbccddeeffg"})
    void validatePasswordTest2(String password){
        assertThatCode(()->PasswordValidator.validate(password))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessage("비밀번호는 최소 8자 이상 12자 이하여야 합니다.");
    }

}
  • 클래스 구현
package org.example;

public class PasswordValidator {
    public static final String WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE = "비밀번호는 최소 8자 이상 12자 이하여야 합니다.";

    public static void validate(String password) {
        int length = password.length();
        if (length < 8 || length > 12) {
            throw new IllegalArgumentException(WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE);
        }
    }
}

 

테스트 코드 작성 방법

 

1. 어노테이션 활용

@DisplayName("테스트 코드 역할 설명")

@Test -> 테스트를 수행할 메소드 

@Before : 각 테스트 메소드 수행 전에 호출

@After : 각 테스트 메소드 수행 후에 호출

ex) 8자리, 12자리 패스워드 

2. TDD 3원칙

  • 원칙 1 ; 실패하는 단위 테스트를 작성할 때까지 프로덕션 코드를 작성하지 않는다. 
  • 원칙 2 : 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다. 
  • 원칙 3 : 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다. 

3. AssertJ의 활용

import static org.assertj.core.api.Assertions.assertThat;
 @DisplayName("비밀번호는 최소 8자 이상 12자 이하면 에러가 발생하지 않는다.")
    @Test
    void validatePasswordTest(){
        assertThatCode(()-> PasswordValidator.validate("serverWizard"))
                .doesNotThrowAnyException();
    }
  • assertThatCode : 예외가 발생하지 않으면 이 메소드는 실패하지 않는다. 

 

TDD 유의사항

  • 테스트 케이스는 이름이 중요하다.
  • 더 이상 제대로 동작하지 않는 테스트 케이스는 제거한다. 
  • TDD는 자동화된 테스트를 만드는 것이 최종 목표가 아니다. 
  • 모든 상황에 대한 테스트 케이스를 만들 필요는 없다. 
  • 여러 개의 실패하는 테스트 케이스를 한 번에 만들지 않는다. 
  • 하나의 테스트 케이스는 하나만 테스트하도록 작성한다. 
  • 전통적인 테스트 기법을 배워두자.
  • 테스트 케이스는 최대한 고립시킨다. 

(테스트 케이스가 작성되어 있지 않은 다른 모듈 / 데이터베이스 연동 / 외부 시스템 / 콘솔 출력 / 네트워크 등과 서로 영향을 미치지 않도록 한다.)

 

 

참고 서적 및 사이트

 

 

테스트 주도 개발 - YES24

어려움을 겪고 있는 국내의 수많은 Java 개발자들에게 도움을 주기 위해 집필되었다. 쉽고 체계적인 설명과 다양한 예제를 통해 테스트 주도 개발 방법론을 활용하고 있는 국내 개발자들의 문제

www.yes24.com

 

AssertJ 기본 사용법

1. AssertJ란? AssertJ란 asssertion(직역 : 주장)을 제공하는 자바 라이브러리로 에러 메세지와 테스트 코드의 가독성을 높여주는 라이브러리이다. junit5에서 제공하는 Assertions의 assert는 인자 순서 (expect

insight-bgh.tistory.com

 

[Java] JUnit 이란?

JUnit Junit이란 자바 개발자의 93%가 사용하는 단위 테스트 프레임워크이며 Java8 이상부터 지원한다. JUnit5의 경우 2017년 10월에 공개 스프링부트의 경우 2.2버전부터 기본적으로 제공된다. 전처리 작

mungto.tistory.com

 

반응형