[테스트] JUnit 과 AssertJ

2020. 4. 23. 17:21TIL/자바

항상 System.out을 이용하여 로직이 잘 돌아가는지 확인을 했었던 나는,

최근 테스트 코드가 무엇이고 이것이 얼마나 중요한지에 대해 알게 되었다. 

 

먼저, 기존의 Main메소드를 통한 테스트가 어떠한 문제점이 있는지 알아보았다.

  • production code와 test code가 클래스 하나에 존재하게 된다. 이것은 클래스의 크기를 커지게 만들고, 복잡도 또한 높이게 된다.
  • Test Code가 실 서비스에 같이 배포된다.
  • Main 메소드 하나에서 여러개의 기능을 테스트하게 된다. 이로써 결과물을 분석하는데에도 복잡도가 증가한다.
  • 메소드 이름을 통해 어떤 부분을 테스트하는지에 대한 의도를 드러내기 힘들다.
  • 테스트 결과를 사람이 수동으로 확인해야한다.

마지막 이유 하나만으로도 충분히, 테스트 코드의 중요성이 와닿는다. 

알고리즘 문제를 풀 때에도 확인해야 할 로직이 조금만 늘어나면, 그 과정을 System.out을 통해 확인하는데에 여간 귀찮은것이 아니었다.

또한 그 결과물들이 내가 예상한 값이 맞는지 직접 하나하나 확인해야 했다.

 

간단한 알고리즘 문제를 푸는데 있어서도 이렇게 번거로운데,

실제로 큰 규모의 프로젝트를 만들시에는 얼마나 더 번거로울까?

 

 

다루어야 할 내용이 산더미지만, 나는 내가 진행하고 있는 수준에서 글을 써두고 계속해서 글을 업데이트 해나갈 생각이다.

먼저, 자바에서 테스트를 하기 위해서 사용한 준비물은 JUnit과 AssertJ였다.

JUnit은 @Test, @Before, @After, @BeforeClass, @AfterClass, @Ignore  여섯가지의 어노테이션을 이용하여 단위테스트를 진행하는 라이브러리 이다. 각각의 역할은 다음과 같다.

 

  • @Test : 단위테스트를 수행 할 메소드를 나타내고, 항상 public void 형태이다.
  • @Before, @After : 단위테스트 전, 후에 한 번씩 실행되므로 중복 코드를 제거하기 위해 사용한다.
  • @BeforeClass, @AfterClass : Test Class 전후처리를 담당하고, public static void 형태를 갖는다.
  • @Ignore : 특정 환경에서만 테스트할 때 제외시키기 위한 어노테이션이다.

AssertJ는 많은 assertion을 메소드 체이닝이 가능하도록 제공하는 라이브러리이다.

Junit의 assert보다 훨씬 테스트 코드의 가독성을 높여주고, 각자 좋아하는 IDE에서 사용하기도 굉장히 쉽다.

개발자가 테스트하면서 필요하다고 생각할만한 모든 기능이 들어있다고 보면 된다고 한다.

아직 생각이 짧은 나는 뭐가 그렇게 많을지 상상도 못하고 있다.

잘 정리하신 분의 예제를 참고해보았다.

 

assertThat("Hello, world! Nice to meet you.") // 주어진 "Hello, world! Nice to meet you."라는 문자열은
				.isNotEmpty() // 비어있지 않고
				.contains("Nice") // "Nice"를 포함하고
				.contains("world") // "world"도 포함하고
				.doesNotContain("ZZZ") // "ZZZ"는 포함하지 않으며
				.startsWith("Hell") // "Hell"로 시작하고
				.endsWith("u.") // "u."로 끝나며
				.isEqualTo("Hello, world! Nice to meet you."); // "Hello, world! Nice to meet you."과 일치합니다.

 

assertThat(3.14d) // 주어진 3.14라는 숫자는
				.isPositive() // 양수이고
				.isGreaterThan(3) // 3보다 크며
				.isLessThan(4) // 4보다 작습니다
				.isEqualTo(3, offset(1d)) // 오프셋 1 기준으로 3과 같고
				.isEqualTo(3.1, offset(0.1d)) // 오프셋 0.1 기준으로 3.1과 같으며
				.isEqualTo(3.14); // 오프셋 없이는 3.14와 같습니다

멍청한 나도 두 예제를 통해 AssertJ의 위력을 한번에 느낄 수 있었다. 

위에 나와있지 않은 내가 테스트 코드를 연습하는 동안사용한 AssertJ의 메소드는 아래와 같다.

assertThat(car.isWinner(WINNER_POSITION)).isTrue(); // boolean을 판별해줌
assertThat(car).isNotNull(); // 객체의 null여부를 판별해줌
assertThat(RandomNumberGenerator.generateRandomNumber()).isBetween(0, 9); //랜덤 숫자가 0부터 9까지의 숫자인지 판별해줌

 

 

이외에도 무궁무진한 내용이 많다는 것을 여러 블로그를 통해 알 수 있었지만, 

굳이 지금 정리하지 않는 이유는 내가 직접사용했을때 그 의미가 커질것 같기 때문이다. 

계속해서 테스트 코드를 작성하는 개발을 연습할 것이기 때문에, 그때마다 알게되는 새로운 내용들을 이곳에 정리해야겠다. 

 

+ 5/27
전혀 셋팅이 안되어있는 상태에서 asserj를 사용하려고하니 당연히 오류를 냈다. 메소드 체이닝에 대해서만 정리하고 정작 사용하기 위한 과정을 정리하지 않은 것이 정말 ... 아직 한참 모자라다. 

assertj를 사용하기 위해서는 먼저 라이브러리 의존성을 추가해야한다. 

gradle의 경우

testCompile 'org.assertj:assertj-core:3.6.2'

maven의 경우

<dependency>
  <groupId>org.assertj</groupId>
  <artifactId>assertj-core</artifactId>
  <!-- use 2.6.0 for Java 7 projects -->
  <version>3.6.2</version>
  <scope>test</scope>
</dependency>

 

의존성을 추가한 다음엔 assertj의 다양한 메소드를 사용하기 위해서 아래와 같이 import문을 작성한다.

import static org.assertj.core.api.Assertions.*;

 

두 단계를 거치고 나면 이전에 정리했던 assertj의 여러 메소드를 체이닝 하여 사용할 수 있게 된다. 

 

 

 

 

 

 

'TIL > 자바' 카테고리의 다른 글

[자바] 로또 게임 구현  (0) 2020.05.18
[자바] Java와 JVM  (0) 2020.05.06
[자바] getter메소드 사용을 지양하자  (0) 2020.04.25
[자바] 레이싱 게임 구현  (0) 2020.04.22
[자바] 코드 컨벤션  (0) 2020.04.06