TDD 방법론 사용 이유

TDD(Test Driven Development, 테스트 주도 개발) 개발 프로세스에서 테스트를 먼저 진행 후 테스트에 통과한 코드를 후에 작성하는 방법론이다. 이 방식은 개발 초기 단계에서 버그를 발견하고 수정하는데 도움을 준다.

https://f-lab.kr/insight/understanding-and-practicing-tdd

 

TDD는 개발자가 기능을 구현하기 전에 요구 사항을 명확하게 이해하도록 강제하며, 이는 결과적으로 더 깨끗하고 유지보수하기 위운 코드(작동하는 깔끔한 코드 : 론 제프리즈)로 이어진다. 

예전에 기능 구현을 하고 배포 몇일 전 테스트를 진행하는데 생각지도 못한 경우가 발생해 배포가 미루어진 적이있다. TDD를 적용을 했다면 코드를 짜기 전에 더 많은 경우에 대해 생각할 수 있었을 것이고 배포가 미루어지는 일은 없었을 것이다.

https://www.google.com/url?sa=i&url=https%3A%2F%2Fblog.testworks.co.kr%2Fwhat-covid-19-teaches-us-about-software-dev-testing-kor%2F&psig=AOvVaw04zTrvd5RvUpUGniwoTr1z&ust=1725250719720000&source=images&cd=vfe&opi=89978449&ved=0CBQQjRxqFwoTCJDY2vfxoIgDFQAAAAAdAAAAABAE

위에 사진에서 x축은 소프트웨어의 생명주기, y축은 버그를 고치는 비용이다. Code 단계 이전 테스트를 통해 많은 비용을 아낄수 있는 것을 확인 할 수 있고 TDD 방법론은 적용하는 이유를 직관적으로 잘 설명해주는 것 같다.   

 

AAA(Arrange - Act - Assert)  & Given - When - Then 차이

두 패턴은 유사하지만 유일한 차이점은 비개발자가 Given - When - Then구조를 더 읽기 쉽다는 것이다.(뭔가 대단한게 있을 줄 알았는데....)

Junit5 Annotation

- @Test : 테스트 Method임을 선언

- @BeforeEach : 모든 테스트 실행 전에 실행할 테스트(Junit4 -> @Before)

- @AfterEach : 모든 테스트 실행 후에 실행할 테스트(Junit4 -> @AfterEach)

- @BeforeAll : 현재 클래스 실행전 제일 먼저 실행할 테스트(Junit4 -> @BeforeClass)

- @AfterAll : 현재 클래스 종료 직수 실행할 테스트(Junit4 -> @AfterClass)

- @Disabled : 이 클래스나 테스트를 사용하지 않음(Junit4 -> @Ignore)

Junit5 Assertion

- assertThat : junit4에서 사용. 현재는 deprecated. Junit5에서 assertThat 사용법 -> https://jsparrow.github.io/rules/replace-j-unit-assert-that-with-hamcrest.html#tags

- assertEquals : 두 값을 비교하여 일치 여부 판단

- assertTrue : 특정 조건이 true인지 판단

- assertFalse : 특정 조건이 false인지 판단

교재 : 자바와 Junit을 활요한 실용주의 단위 테스트

 

제 1 부 1장

책에 있는 간단한 기본 예제로 시작해보겠다

 

/src/main/iloveyouboss/Scoreable.java

package org.example.junit.iloveyouboss;

@FunctionalInterface
public interface Scoreable {
    int getScore();
}

/src/main/iloveyouboss/ScoreCollection.java

package org.example.junit.iloveyouboss;

import java.util.ArrayList;
import java.util.List;

public class ScoreCollection {
    private List<Scoreable> scores = new ArrayList<>();

    public void add(Scoreable scoreable) {
        scores.add(scoreable);
    }

    public int arithmeticMean() {
        int total = scores.stream().mapToInt(Scoreable::getScore).sum();
        return total / scores.size();
    }
}

Intellij에서 친절하게 단위 테스트 클래스를 만들어준다.

단위 테스트를 하고 싶은 클래스명 위에 커서를 두고 alt + enter를 누른다.

create test를 누르고 테스트할 메서드를 체크하면 자동으로 테스트 클래스를 생성해준다.

 

우선은 ansersArithmeticMeanOfTwoNumbers 메스드를 만들어서 테스트를 진행했다.

/src/test/iloveyouboss/ScoreCollectionTest.java

package org.example.junit.iloveyouboss;

import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

public class ScoreCollectionTest {

    @Test
    public void answersArithmeticMEanOfTwoNumbers() {
        // arrange
        ScoreCollection collection = new ScoreCollection();
        collection.add(() -> 5);
        collection.add(() -> 7);

        // act
        int actualResult = collection.arithmeticMean();

        // assert
        assertThat(actualResult, equalTo(6));
    }
}

책은 junit4 기준이고 나는 junit5를 사용하고 있다. 처음에 asserThat과 equalTo 메서드를 사용하려하니 아래에 빨간줄이 생겼다. hamcrest에 해당하는 메서드를 static import 하니 사용할 수 있었다. hamcrest말고도 활용할 수 있는게 있었는데 무슨 차이인지 현재는 모르지만 나중에 포스팅 해야겠다.

+ Recent posts