테스팅은 SW 개발의 필수적인 부분으로, 전문적으로 테스트만을 담당하는 직군이 존재할 정도로 그 중요성이 크다. 특히 TDD(Test Driven Development)나 BDD(Behavior Driven Development)와 같은 현대적인 개발 방법론들은 테스팅을 개발 과정의 핵심으로 두기도 한다. 그러나 모든 개발자가 테스트 전문가가 될 필요는 없다. 특히 애플리케이션 개발 시 기능별로 정확하게 동작하는지 검증하는 단위테스트는 개발자 간단히 수행할 수 있으며, 이는 SW 품질을 보장하는데 아주 중요한 역할을 한다.
이번 포스트에서는 Java 개발자들에게 가장 친숙한 단위테스트 프레임워크인 junit의 필요성과 간단한 사용법에 대해 살펴보자.
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int divide(int a, int b) {
return a / b;
}
}
일반적으로 이 코드가 잘 동작하는지 확인하려면 호출해서 결과를 출력해 보게 된다.
public static void main(String[] args) {
Calculator calculator = new Calculator();
int result = calculator.add(10, 20);
System.out.println(result); // 결과가 30이군!
}
문제는 테스트 실행 결괏값을 텍스트로 확인해야 하고 또 시간이 지나면 결괏값이 무엇을 의미하는지 소스 코드를 분석해야 알 수가 있다. 즉 테스트 과정에서 시간이 너무 많이 걸리게 되고 자동화가 어렵다. 결과적으로 테스트를 등한시하게 된다. 이를 개선해서 테스트를 자동화하기 위한 도구가 JUnit이다.
기본 annotation
life cycle annotation
JUnit은 여러 annotation으로 테스트의 라이프사이클을 정의하는데 @Test와 @BeforeAll, @AfterAll, @BeforeEach, @AfterEach가 있다.
annotation
description
@Test
가장 많이 사용되는 애너테이션으로 대상 메서드가 단위테스트를 수행하는 테스트 메서드임을 나타냄
@BeforeEach, @AfterEach
각각의 @Test 전/후에 공통적으로 처리할 사전/사후 작업 메서드 정의
@BeforeAll, @AfterAll
모든 @Test에 거쳐 한번 만 필요한 사전/사후 작업 메서드 정의. static 메서드에 작성
@DisplayName
@Test가 선언된 메서드의 검증 내용(목적)을 메서드 이름으로 사용하면 나중에 테스트 내용을 이해하기 용이하다. 하지만 메서드의 이름은 자바의 naming rule 상 필요한 내용을 작성하기에 한계가 많다. 이런 경우 @DisplayName을 이용하면 문자열 형태로 테스트 내용을 작성할 수 있다.
@Test
public void 두수를더해서나오는합을검증() {
Calculator calculator = new Calculator();
int result = calculator.add(1, 2);
assertEquals(3, result);
}
@Test
@DisplayName("두 수의 합을 검증:예) 1+2=3")
public void addTest2() {
Calculator calculator = new Calculator();
int result = calculator.add(1, 2);
assertEquals(4, result);
}
간단한 단위테스트
기본 설정
junit을 사용하기 위해서는 여러 가지 의존성이 필요한데 Junit Jupiter (Aggretator)를 사용하면 한 번에 다 가져올 수 있다.