- Published on
9장. 단위 테스트
9장. 단위 테스트
TDD 법칙 세 가지
- 실패하는단위 테스트를 작성할 떄 까지 실제코드를 작성하지 않는다.
- 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다
- 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.
위 세 가지 규칙을 따르면 개발과 테스트가 대랴 30초 주기로 묶입니다.
이렇게 개발하면 실제 코드를 사실상 전부 테스트하는 테스트 케이스가 나오게 됩니다. 하지만 실제 코드와 맞먹을 정도로 방대한 테스트 코드는 심각한 관리 문제를 유발하기도 합니다.
깨끗한 테스트 코드 유지하기
지저분한 테스트 코드는 테스트 코드를 짜지 않는 것 보다 못합니다.
실제 코드가 변경되면 테스트 코드도 변해야 하는데 테스트 코드가 지저분할 수록 코드를 변경하기가 어렵기 때문입니다.
그렇다고 테스트 코드를 짜지 않으면 어떤 사이드 이펙트가 존재할지 모르기 때문에 코드를 수정하기가 어렵습니다. 즉 결함율이 높아집니다.
테스트 코드도 실제 코드 못지 않게 깨끗하게 작성해야 합니다.
테스트는 유연성, 유지보수성, 재사용성을 제공한다
테스트 케이스가 없다면 모든 변경이 잠정적인 버그이지만, 테스트 케이스가 존재한다면 두려울게 없습니다.
변경 후 기존의 로직이 잘 돌아가는지 전체 테스트 케이스를 실행해보면 바로 알수 있으니까요.
깨끗한 테스트 코드
깨끗한 테스트 코드를 만드기 위해서는 가독성이 매우 중요합니다. 어쩌면 가독성은 실제 코드보다 테스트 코드에 더더욱 중요합니다.
@Test
void test() {
// Given: 테스트 자료 만들기
// When: 테스트 자료를 조작
// Then: 조작한 결과를 검증
}
테스트 케이스 외에 필요한 작업은 함수로 추출하여 테스트 케이스 내부는 깔끔하게 유지하고, 위 처럼 3단계로 분리하여 작성하면 코드를 빠르게 이해할 수 있으며 가독성이 좋아집니다.
이중 표준
테스트 케이스는 간결하고, 표현력이 풍부해야 하지만, 실제 코드만큼 효율적일 필요는 없습니다.
실제 환경과 테스트 환경은 요구사항이 판이하게 다릅니다.
하나의 테스트 케이스에서 모든 함수를 테스트 하기 보다는 각 함수 별로 테스트 케이스를 각각 만드는 것이 좋습니다.
실제 코드에서는 안되지만 테스트 코드에서는 전혀 문제가 없는 방식을 이중 표준이라고 합니다.
테스트 당 assert 하나
Junit으로 테스트를 짤 때는 함수마다 assert 문을 하나만 사용해야 한다고 주장한 학파가 있습니다.
확실히 테스트 당 assert를 하나만 사용하면 각 테스트 코드를 이해하기가 쉽습니다.
하지만 그러면 중복이 많아집니다. 중복 또한 Template Method 패턴을 이용하여 제거할 수 있지만, 배보다 배꼽이 더 큰 느낌이 듭니다.
테스트 당 개념 하나
테스트 케이스 당 assert를 하나만 넣는 지침은 좋습니다.
하지만 그 보다는 테스트 함수마다 한 개념만 테스트 하라
라는 규칙이 조금 더 나은 것 같습니다.
FIRST
- Fast: 테스트는 빨라야 함. 그래야 자주 돌려 볼 수 있기 때문
- Independent: 각 테스트는 서로 의존하면 안됨. 즉, 독립적으로 실행이 가능해야 함
- Repeatable: 테스트는 어떤 환경에서도 반복 가능해야 함
- Self-Validating: 테스트는
bool
값으로 결과를 내야 함. 테스트 결과를 로그로 확인 하는 등의 방식은 좋지 않음 - Timely: 테스트는 적시에 작성해야 함. 단위 테스트라면 실제 코드를 구현하기 직전에 테스트 코드를 작성