Spring-boot 2 이제 JUnit5 지원한다.

정확하게 이야기하면 Spring-boot 2.2 버전부터.

이전에 JUnit5를 Spring-boot 2.x 버전에서 사용할 수 있다고 글에서 봐서 써볼려고 했다. 하지만 Surefire 관련된 dependency가 해결이 안되어 있었다. 이걸 기억해서 매번 그걸 exclude 시킬 수는 없는 노릇.

JUnit4에서 테스팅 framework의 고전이 걍 끝났나 싶었다. 더 이상 뭘 한다는 이야기를 못들어서. JUnit5 이야기를 듣고, 반갑긴 했지만 결국에는 제대로 써먹기에는 무리!

주로 개발하는 Framework 환경이 Springboot 환경인데, 어슬프게 지원되면 내가 짠 코드의 문제인지 프레임워크 설정 문제인지 가늠이 안되니까. 좋은 시도를 하고 있구나 정도로 받아들였는데, 최근에 프로젝트를 셋업 과정에서 2.2 버전에서는 기본으로 잘 지원하는걸 알게됐다. 이제 본격적으로 이 테스트 코드를 작성하면 되나? 테스트 코드를 새로 짜는 기회보다는 수정할 일들이 최근에는 더 많아서. 새롭게 작성하는 기회가 생긴다면 좀 더 추가적으로 정리해봐야겠다.

Something new in JUnit5

가잔 큰 차이점은 기존 Junit4와는 달리, Jupiter라는 새로운 package naming을 갖는다. 그리고 모듈화를 통해 Runtime 환경과 테스트 라이브러리가 분리되어 보다 다양한 환경에서 제공될 수 있는 기반을 제공한다. 뭐 좀 더 널리 활용되길 기대하는 마음이 한가득이라는 것은 모든 소프트웨어를 만드는 사람의 입장이 같은 것 같다.

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

Vintage는 JUnit3,4와의 호환성을 위해 존재한다. 이전 테스트 환경에서 돌리고 싶다면 이 Vintage 설정을 다로 잡아야 한다.

Annotation

Lifecycle을 관리하는 Annotation들의 이름이 바뀌었다.

  • BeforeClass -> BeforeAll
  • AfterClass -> AfterAll
  • Before -> BeforeEach
  • After -> AfterEach

이름만 바뀌었지 하는 짓은 같다.

DisplayName annotation

이번에 추가된 신규 annotation 가운데 테스트의 의미를 아예 자연어로 기술할 수 있도록 도와준다.


@DisplayName("테스트 깨지면 안됨")

void shouldItNotBeBroken() {

...

}

이렇게 작성해서 테스트가 돌면, “테스트 깨지면 안됨” 이라는 자연어로 IntelliJ 테스트 결과에 잘 표시된다. 테스트 메소드 이름이 의미를 잘 전달하도록 해야, 테스트 자체의 유지보수가 가능하다고 이야기를 쭉 해왔는데, 다른 위치에 테스트의 Semantic을 기록한다는게 테스트 메소드 이름의 유지 보수에 과연 도움이 될지는 의구심이 있다. 적절한 중요의 미를 살리면 확실히 도움이 되긴 할거다. 아마도 누군가는 무조건 @DisplayName(“…”)를 적어야 한다고 Governance 하는 인간들이 언젠가는 등장하지 않을까?

Spring integrated tests

Spring 환경에서 Integration 테스트 혹은 Unit test를 할 때 @RunWith(SpringRunner.class) Annotation을 사용했다. 5에서는 기반 환경을 지칭할 때 @ExtendWith(SpringExtension.class)를 사용해서 테스트를 작성하면 된다.

 

Exceptional Tests

이전 모델에서는 Exception 발생 케이스에 대한 테스트를 위해서는 “expected”라는 변수를 통해 @Test Annotation을 테스트 수준에서 설정했다. 5에서는 “assertThrows()”라는 신규 assert 메소드를 이용해서 발생하는 Exception을 잡고, 그 Exception이 우리가 기대하는 Exception과 동일한지를 평가하는 방식으로 변경되었다. 기존에 Exception을 테스트했던 코드들이 좀 많다면 유지보수하는데 애를 먹을지도…

이것 이외에 추가된 assertAll, assertTimeout 메소드들은 앞으로 테스트를 작성할 때 상당히 도움이 될 것 같다. 이 링크에서 상세한 사용법을 확인할 수 있다.