JUnit을 이용한 단위 테스트
테스트코드
테스트 코드는 소프트웨어가 제대로 동작하는지 확인하기 위해 작성하는 코드입니다. 이 코드는 예상한 결과가 맞게 나오는지를 자동으로 검증해줍니다.
테스트 코드를 작성해야하는 이유
버그 방지: 코드를 변경할 때 예상치 못한 버그를 사전에 발견하여 수정할 수 있습니다.
리팩토링 지원: 코드를 개선할 때 기존 기능이 제대로 동작하는지 확인하고 안전하게 변경할 수 있습니다.
문서화: 코드의 동작을 명확하게 문서화하여 다른 개발자들이 이해하기 쉽게 합니다.
자동화된 검증: 반복적인 테스트 과정을 자동화하여 개발 효율성을 높입니다.
코드 품질 향상: 코드의 신뢰성과 유지보수성을 개선할 수 있습니다.
테스트 주도 개발(TDD)
테스트 주도 개발(Test Driven Development, TDD)은 코드를 작성하기 전에 테스트를 먼저 작성하는 개발 방법론입니다.
일반 개발 방식과 TDD 개발 방식의 차이
- 일반 개발 방식
일반적인 개발 방식은 보통 요구사항 분석 -> 설계 -> 개발 -> 테스트 -> 배포의 순서로 진행됩니다. 이 방식은 초기에 요구사항이 명확하지 않거나 중간에 변경될 수 있어, 완벽한 설계를 하기 어렵고 잠재적인 위험이 있습니다. 중간에 요구사항이 변경되면 코드를 수정하고 추가하면서 불필요한 코드가 쌓일 수 있으며, 이는 나중에 코드를 유지보수하고 재사용하기 어렵게 만들 수 있습니다.
- TDD 개발 방식
TDD와 일반적인 개발 방식의 가장 큰 차이점은 테스트 코드의 작성 단계입니다. TDD는 설계 단계에서 목적과 무엇을 테스트해야 할지 미리 테스트케이스를 작성하는 단계를 거칩니다.
TDD의 과정
테스트 작성: 기능이나 요구사항을 테스트하는 테스트 케이스를 작성합니다. 이 단계에서는 해당 기능이 실패할 것을 예상합니다.
- 코드 작성: 최소한의 코드만 작성하여 1번에서 작성하였던 실패하는 테스트를 통과할 수 있도록 만듭니다. 이 과정에서 기능을 추가하거나 수정합니다.
- 리팩토링: 작성한 코드를 개선하고 중복을 제거합니다. 이 과정에서 코드의 구조를 더 명확하고 유지보수하기 쉽도록 개선합니다.
TDD의 핵심은 코드를 작성하기 전에 테스트를 먼저 작성하여 요구사항이나 기능의 목적을 명확하게 이해하고 검증하는 것입니다. 이 방식은 초기 설계 단계부터 테스트가 포함되어 있어 변경 사항에 대응하기 용이하며, 코드의 품질과 유지보수성을 높이는 데 도움을 줍니다.
JUnit
JUnit은 자바 애플리케이션의 테스트를 위한 표준 프레임워크입니다.
JUnit의 기본 어노테이션
@Test : 테스트 메서드 정의
@BeforeEach : 테스트 메소드들이 실행되기 전에 매번 실행되는 메소드로 지정
@BeforeAll : 전체 테스트가 실행되기 전 딱 한번만 실행
@AfterEach : 테스트 메소드들이 실행되고 난 후 매번 실행되는 메소드로 지정
@AfterAll :전체 테스트가 끝난 후 한번 실행
AssertJ
AssertJ는 JUnit과 함께 사용되어 객체나 결과를 검증하는 데 유용한 메서드를 제공합니다
assertArrayEquals(a,b) : 배열 a,b 일치함 확인
assertEquals(a,b) : 객체 a,b 같은 값 가지는지 확인
assertEquals(a,b,c) : 객체 a,b 값이 일치함을 확인(c는 오차범위)
assertSame(a,b) : 객체 a,b가 같은 객체임을 확인
assertTrue(a) : 조건 a가 참인지 확인
assertNotNull(a) : 객체 A가 null이 아님 확인
예시: 간단한 단위 테스트
다음은 간단한 계산기(Calculator) 클래스와 이를 테스트하기 위한 테스트 코드의 예시입니다. 이 예시는 JUnit을 사용하여 기본적인 덧셈, 뺄셈, 나눗셈 기능과 예외 상황을 테스트합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public int divide(int a, int b) {
return a / b;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class CalculatorTest {
// 덧셈 테스트
@Test
void additionTest() {
Calculator calculator = new Calculator();
int result = calculator.add(2, 3);
assertEquals(5, result, "2 + 3은 5여야 합니다.");
}
// 뺄셈 테스트
@Test
void subtractionTest() {
Calculator calculator = new Calculator();
int result = calculator.subtract(5, 3);
assertEquals(2, result, "5 - 3은 2여야 합니다.");
}
// 나눗셈 테스트
@Test
void divisionTest() {
Calculator calculator = new Calculator();
int result = calculator.divide(6, 3);
assertEquals(2, result, "6 / 3은 2여야 합니다.");
}
// 0으로 나누기 테스트
@Test
void divisionByZeroTest() {
Calculator calculator = new Calculator();
// 0으로 나눌 때 ArithmeticException이 발생하는지 테스트
assertThrows(ArithmeticException.class, () -> calculator.divide(6, 0), "0으로 나누면 ArithmeticException이 발생해야 합니다.");
}
}