티스토리 뷰

JAVA

[JAVA] JUnit 테스트

DevBee 2021. 4. 20. 23:55

단위 테스트(Unit Test)

개발 단계에서 각 모듈의 개발이 완료되는 시점에 실행하는 테스트입니다. 모듈이란, 프로그램 내의 하나의 기능을 말합니다. 즉, 하나의 기능만이 제대로 동작하는지를 확인하는 테스트입니다. (보통 모듈의 단위는 하나의 메소드가 됩니다.) 따라서 단위 테스트를 모듈 테스트(Module Test)라고도 합니다. 모듈이 개발 완료되는 시점에 개발자가 명세서 기반으로 정확하게 개발을 했는지 테스트하게 됩니다.

 

단위 테스트에는 화이트박스 테스트와 블랙 박스 테스트 기법을 이용하여 진행할 수 있습니다. 주로 화이트박스 테스트 기법을 이용합니다.

 

✔️화이트박스 테스트

: 응용 프로그램의 내부 구조, 동작을 소스 코드 단위로 검사하는 테스트 방식으로 개발자 관점의 단위 테스트 기법입니다.

 

✔️블랙박스 테스트

: 소프트웨어의 내부 구조나 동작 방식을 알지 못한 상태로 기능을 검사하는 방식으로 사용자 관점의 단위 테스트 기법입니다.

 

모듈을 테스트 하기 위해 해당 모듈을 실행할 수 있는 환경 구성이 필요합니다. 다시 말해 테스트할 모듈을 호출하여 실행하는 상위 모듈과 테스트하려는 모듈이 호출하는 하위 모듈이 필요한데 이 모듈들이 모두 존재한다는 보장이 없기 때문에 가상의 모듈을 만들어서 테스트를 진행하게 됩니다.

 

✔️테스트 드라이버 (Test Driver)는 테스트 대상이 되는 모듈을 호출하여 대상 모듈의 실행 결과를 받는 가상의 상위 모듈입니다.

 

✔️테스트 스텁 (Test Stub)는 호출하는 상황의 대상 모듈을 테스트하기 위한 가상의 모듈로 테스트 대상이 되는 모듈의 하위 가상 모듈을 말합니다.

 

통합 테스트(Integration Test)

모듈을 통합하는 과정에서 모듈 간 호환성의 문제를 찾아내기 위해 수행되는 테스트입니다. 다시 말해 모듈 간의 인터페이스가 제대로 작동하는지를 테스트하게 됩니다.

 

통합 테스트 기법은 다음과 같습니다.

 

✔️빅뱅 통합

: 개별적인 모듈에 대해 단위 테스트를 수행한 후에 전체 시스템에 대해 한번에 통합 테스트를 수행하는 것을 말합니다. 단시간에 테스트가 가능하나 오류가 발생할 경우 오류가 발생한 모듈 및 원인을 찾기가 어렵습니다.

 

✔️상향식 통합

: 하위 모듈을 먼저 통합하고 상위에 있는 모듈들을 통합하는 방식으로 테스트 드라이버가 필요합니다. 하위에 있는 모듈들을 충분하게 테스트할 수 있다는 장점이 있고 테스트 스텁을 제공하는 비용이 들지 않는다는 장점이 있지만 설계 오류를 조기에 발견하기 어렵다는 단점이 있습니다.

 

✔️하향식 통합

: 시스템을 구성하는 모듈들의 계층 구조에서 가장 상위에 있는 모듈부터 시작하여 하위에 있는 모듈들을 점진적으로 통합하는 방식을 말하며 테스트 시 하위 모듈을 대치할 테스트 스텁이 필요합니다. 설계상의 오류를 빨리 발견할 수 있다는 장점이 있지만 많은 수의 테스트 스텁이 필요하고 블랙박스 테스트만 사용할 경우 하위 모듈이 충분히 테스트되지 않을 수 있다는 단점이 있습니다.

 

✔️샌드위치 통합

: 상향식, 하향식 통합 방식을 절충하여 통합하는 방식으로 모듈별로 어떤 경우에는 테스트 드라이버를 생성해서 상향식으로, 어떤 경우에는 테스트 스텁을 생성해서 하향식으로 테스트하는 방식입니다.

 

JUnit이란?

자바프로그래밍 언어용 유닛 테스트 프레임워크입니다. maven이나 gradle을 사용하여 라이브러리를 추가하거나 이클립스 등에서 제공되는 JUnit 라이브러리를 추가할 수 있습니다.

 

저는 gradle을 사용하여 JUnit 라이브러리를 추가하였습니다. JUnit5를 기준으로 작성되었습니다.

 

[build.gradle 파일]
...
test {
    useJUnitPlatform()
}
...
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
    testRuntimeOnly
'org.junit.jupiter:junit-jupiter-engine:5.3.1'
}

예제로 사용할 Calculator 클래스를 생성하고 sum이라는 메소드를 하나 만들겠습니다.

 

public class Calculator {
    public int sum(int num1, int num2) {
        return num1 + num2;
    }
}

 

이후 테스트 디렉토리 밑에 CalculatorTest라는 테스트 클래스를 생성하고 sum 메소드가 정상 동작하는지 간단하게 확인해보겠습니다. @Test는 각 메소드가 단위 테스트 메소드임을 지정합니다.

 

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class CalculatorTest {

    @Test
    public void sum() {
        Calculator calculator = new Calculator();
        assertEquals(30, calculator.sum(20, 10));
    }
    
}

 

각 테스트 메소드 별로 테스트 결과를 확인할 수 있고 전체 테스트 클래스를 한번에 확인할 수도 있습니다. 테스트 성공의 경우 초록색, 실패의 경우 빨간색으로 표시되어 직관적으로 결과를 확인할 수 있습니다.

 

IntelliJ에서 Gradle 프로젝트 생성 후 테스트를 진행한 결과

 

테스트 결과 확인을 위해 다양한 assertXXX 메소드를 사용합니다.

 

✔️assertArrayEquals(a, b): 배열 a와 b가 일치함을 확인

✔️assertEquals(a, b): 객체 a와 b가 일치함을 확인

✔️assertEquals(a, b, c): 객체 a와 b가 일치함을 확인 (a - 예상값, b - 실제 값, c - 오차범위)

✔️assertSame(a, b): 객체 a와 b가 같은 객체임을 확인

✔️assertTrue(a): 조건 a가 참인가를 확인

✔️assertNotNull(a): 객체 a가 null이 아님을 확인

 

그 외에도 다양한 단정문이 존재합니다. (junit.sourceforge.net/javadoc/org/junit/Assert.html)

 

***JUnit4와 JUnit5 비교***

JUnit4는 하나의 jar 였지만 JUnit5는 3가지 모듈로 이루어져 있습니다.

 

 JUnit5 = JUnit Platform + JUnit Jupiter + JUnit Vintage 

 

✔️JUnit Platform

: JVM에서 동작하는 테스트 프레임워크로, 테스트를 발견하고 계획을 생성하고 결과를 보고하는 TestEngine 인터페이스를 정의합니다.

 

✔️JUnit Jupiter

: JUnit5 TestEngine의 실제 구현체입니다. JUnit5 기반의 테스트를 실행시키기 위한 TestEngine을 Platform에 제공합니다.

 

✔️JUnit Vintage

: TestEngine에서 JUnit3 및 JUnit4 기반의 테스트를 실행하기 위한 기능을 제공합니다.

 

JUnit5의 주요 애노테이션은 다음과 같습니다.

 

애노테이션 설명
@Test 테스트 메서드임을 나타냅니다.
@BeforeEach, @AfterEach 각각의 @Test, @RepeatedTest, @ParameterizedTest, @TestFactory 전, 후에 실행됩니다.
@BeforeAll, @AfterAll 모든 @Test, @RepeatedTest, @ParameterizedTest, @TestFactory 전, 후에 실행됩니다.
@ExtendWith 확장을 선언적으로 등록하는데 사용됩니다.
Spring을 사용하는 경우 @ExtendWith(SpringExtension.class) 와 같이 사용합니다.
@Disabled 테스트 클래스 또는 테스트 메서드를 비활성화 하는데 사용됩니다.
@ParameterizedTest 메서드가 매개변수가 있는 테스트임을 나타냅니다.
@RepeatedTest 메서드가 반복 테스트를 위한 테스트 템플릿임을 나타냅니다.
@TestFactory 메서드가 동적 테스트를 위한 테스트 팩토리임을 나타냅니다.
@TestMethodOrder 테스트 메서드의 실행 순서를 구성하는데 사용됩니다.
@DisplayName 테스트 클래스 또는 테스트 메서드에 대해 사용자 지정 표시 이름을 정해줄 때 사용합니다.

 

JUnit4에서 JUnit5가 되면서 변경되는 애노테이션을 살펴보면 다음과 같습니다.

 

@Before, @After → @BeforeEach, @AfterEach

@BeforeClass, @AfterClass  @BeforeAll, @AfterAll

@Ignore  @Disabled

@Category  @Tag

@RunWith  @ExtendWith

@Rule, @ClassRule  @ExtendWith, @RegisterExtention

Assertion의 위치가 Junit5에서는 org.junit.jupiter.api.Assertions으로 변경되었습니다. AssertJ, Hamcrest, Trust에서 제공하는 org.junit.Assert는 그대로 사용할 수 있습니다.

 

참고

- 화이트박스, 블랙박스 테스트: www.crocus.co.kr/1681

- 단위테스트와 통합테스트: osb0728.tistory.com/26zereight.tistory.com/545

- JUnit Test: www.nextree.co.kr/p11104/, lee-mandu.tistory.com/398?category=633568

- JUnit - Gradle: www.baeldung.com/junit-5-gradle 

- JUnit5: hirlawldo.tistory.com/39

'JAVA' 카테고리의 다른 글

[Java Study 05] 클래스(Class)  (0) 2021.04.24
[JAVA] 객체 지향 프로그래밍(OOP: Object Oriented Programming)  (0) 2021.04.23
[JAVA] 스택(Stack)과 큐(Queue)  (0) 2021.04.18
[JAVA] 리스트 (List)  (0) 2021.04.15
[Java Study 04] 제어문  (0) 2021.04.14
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함