Junit5 사용하기

Minky·2021년 10월 1일
1

기존 프로젝트에서는 단위테스트를 위해 Junit4를 사용중이였다.
새 프로젝트를 진행하면서, spring boot 2.5로 버전업 하게되었고 자연스레 Junit5를 접해볼 수있는 기회가 되었다. 그래서 시작전 기본적으로 알아야 할것들을 기록하려한다.



목표

  • TDD 가볍게 짚고 넘어가기
  • Junit이란
  • Junit5 vs Junit4
  • Junit5 기본문법

TDD란?


TDD(Test Driven Development)란 개발자라면 너무나도 많이 들어봤을 말이다.
'테스트 주도 설계'라고 하여 테스트를 먼저 만들고 테스트를 통과하기 위해 코드를 짜며 실제 서비스 될 코드를 작성하는 개발 방법론중 하나이다.

장점은 객체지향적인 코드를 개발 할 수있고, 설계 수정 및 디버깅 시간의 단축, 유지보수 용이, 오버 엔지니어링 방지 등이 있다.
단점으로는 개발 시간 증가, 어려움이라고한다.

나 역시도 신입때부터 사수분이 TDD를 도입하였고, TDD 컨퍼런스 참가 등 3년간 TDD 방식으로 개발하고 있다 생각하지만 아직까지 어렵고 이렇게 하는게 맞을까? 라는 고민을 많이 하고있다.😭
(일정이 촉박할때는 많이 건너뛰기도....)

어쨌든!
TDD를 위해, 그리고 그 첫번째(?) 단계, 또는 그 일부인 단위테스트를 편하게 작성할 수 있게 제공해주는 프레임워크가 JUnit이다.

JUnit이란?

위에서 말했다시피 단위테스트를 지원하는 테스팅 프레임워크이다.
정확히 말하면 java언어를 지원하는 프레임워크가 Junit이고, 이런 테스팅 프레임워크를 통칭하여 xUnit이라고 한다.
C면 Cunit, Python은 PyUnit 등.. 다양한 언어를 지원하는 프레임워크가 존재한다고 한다!

  • 단정문(Assert)로 수행결과를 판별
  • Annotation(@)으로 간결하게 사용 가능. (junit4부터)

JUnit4 vs JUnit5

Junit4와 Junit5에는 여러 차이점이 있다.

1. 구성이 다르다.
JUnit4 같은 경우는 All in One 즉 하나의 라이브러리만 추가하면 된다.
그에 반해 JUnit5는 아래와 같이 3개의 모듈로 나눠져있다.

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

각각의 모듈 패키지 설명은 많은 블로그들에 정리가 잘 되있다.

2. java 버전 지원

  • JUnit4는 java4 이상
  • JUnit5는 java8 이상

3. Spring Boot 기본 제공 버전

  • JUnit4는 Spring Boot 2.1 버전까지 기본 제공
  • JUnit5는 Spring Boot 2.2 이후버전 부터 기본 제공.
    따라서 2.2버전 이후로는 다른 설정 없이 기본 starter-test로 의존성 추가하면 된다.

4. 어노테이션의 차이
예를 들면, JUnit4에서는 테스트가 수행되기 전 실행하는 메소드를 @Before로 정의했다면, JUnit5에서는 @BeforeEach로 정의한다.

이런식으로 기존 JUnit4에서 사용하던 다양한 어노테이션과 차이가 있다.
차이점 또한 친절하고 자세하게 다른 블로그를 참고하면된다.

이 글에서는 아 차이점이 있구나.. 정도로 넘어가고, 아래에서 JUnit5에서 자주쓰일, 달라진 어노테이션을 공부하고 적용하는것이 목표다!

JUnit5 기본 문법

@ExtendWith(MockitoExtension.class)
mokito를 사용하기위함. (JUnit4의 @RunWith(SpringRunner.class) 와 같음).
Junit 5부터는 좀더 강력한 확장어노테이션인 ExtendWith를 사용한다고 한다.

번외로, JUnit4같은 경우 통합테스트를 위해 @SrpingBootTest를 사용할 경우 @RunWith(SpringRunner.class)을 꼭 추가해줘야 하는데, JUnit5같은 경우는 이미 @SpringBootTest안에 있으므로 추가하지 않아도 된다.

@Test
JUnit5는 기본적으로 'no access modifier'를 Public으로 간주하여 public없이 정의 된 테스트 케이스를 허용한다고 한다.

@BeforeEach / @AfterEach
각 테스트 메서드를 실행하기 전/후에 실행된다.
5개의 테스트가 있는경우 각 어노테이션이 달린 메소드는 각 테스트 케이스 별로 5번 실행된다.

@BeforeAll / @AfterAll
테스트 클래스의 모든 테스트 메서드가 실행되기 전/후에 실행된다.
Each와 다르게 테스트 클래스 당 한번 실행된다.

@Disabled
JUnit4의 @Ignore. 테스트 케이스 diable 처리

@Tag
JUnit4의 @Category. 테스트 필터링.
실행할 테스트를 포함하거나 해당 카테고리에 따라 필터링하여 제외할 수 있다.

@DisplayName
test runner에 출력될 이름을 지정할 수있다.
따라서 기존 junit4에서는 메서드 이름이 곧 테스트 케이스명 이였는데, 이름이 길어지는 단점을 보완하고 메서드를 한글로 작성하던 찜찜함을 덜 수있다.

@ParameterizedTest @ValueSource
데이터 변형이 있는 메소드를 여러번 실행할때 사용됨.

@DisplayName("공백 문자열 테스트")
@ParameterizedTest(name = "문자열 {0}으로 조회")
@ValueSource(strings = " ", "")
public void isBlankStringTest(String source) {
  boolean isBlank = service.isBlank(source);
  assertTrue(isBlank);
}

Assertion

  • JUnit4의 다양한 assertion method와 lamda를 함께 사용할 수 있다.
	assertAll("assertionGroup1",
 	 () -> assertEquals(expected, actual),
 	 ...    
	)
  • assertThrows
    발생할 예외 비교.
@Test
    void exceptionTesting() {
        Exception exception = assertThrows(ArithmeticException.class, () ->
                calculator.divide(1, 0));

        assertEquals("/ by zero", exception.getMessage());
    }

등 너무나도 많다.

아래와 같이 너무나도 잘 설명되있는 블로그들이 많고, 직접 테스트케이스를 작성해가며 계속해서 정리를 해나가야겠다!

주의사항

현재 스프링에서는 DI 할 수있는 여러 방법 중 하나인 @Autowired를 지양하고있다. (이부분도 블로그에 정리해야겠다)
하지만 JUnit5에서는 @SpringBootTest 를 할때, DI를 @Autowired로 해줘야한단다.

해당 내용은 아래의 블로그를 참고했다.
https://velog.io/@sdp1123/JUnit5-%EC%83%9D%EC%84%B1%EC%9E%90-%EC%A3%BC%EC%9E%85-%EC%98%A4%EB%A5%98
https://pinokio0702.tistory.com/189?category=414017


참고

https://reflectoring.io/unit-testing-spring-boot/
https://junit.org/junit5/docs/current/user-guide/
http://junit.sourceforge.net/javadoc/org/junit/Assert.html
https://gmlwjd9405.github.io/2018/06/03/agile-tdd.html
https://nesoy.github.io/articles/2017-02/JUnit
https://jessyt.tistory.com/86
https://jade314.tistory.com/entry/Junit-5
https://do-study.tistory.com/98
https://donghyeon.dev/junit/2021/04/11/JUnit5-%EC%99%84%EB%B2%BD-%EA%B0%80%EC%9D%B4%EB%93%9C/

profile
소통하는 Web Developer가 되고 싶습니다 :)

0개의 댓글