멋사 Backend 86일차 🦁

신재원·2023년 8월 26일

테스트 코드 작성

  • 테스트 코드란 ?
    : 개발 과정에서 작성한 코드의 기능을 검증하고 테스트하는 코드를 말합니다.
  • 테스트 코드를 작성함에 있어 코드 품질을 향상 시킬수 있습니다.

자바에서 테스트 코드 작성시 제공하는 Assertj 메소드는 사진과 같이 두 가지 입니다.

  • 두 가지의 Assertj 라이브리러를 통해 실행 로직을 "검증" 해볼수 있습니다.
  • 두 가지의 경우의 차이점과 왜 org.assertj.core.api.Assertions.assertThat() 가 권장 되는지 작성해 보겠습니다.
    (물론 org.junit.jupiter.api 를 쓰지 말라는 말은 아닙니다.)

제가 작성한 테스트 코드 입니다.

  • JUnit 5 환경에서 Assertions.assertThat() 을 사용해 Json 으로 파싱한 데이터의 값을 검증 하였습니다.
  • 저는 테스트 코드를 작성하면서 습관적으로 Assertions.assertThat() 을 사용했지만, 그 이유를 몰랐으며 궁금증이 생겼습니다.

assertj 와 junit 차이점

1. 사용 방식의 차이

  • org.assertj.core.api.Assertions 사용시 작성 방식입니다.

최종적으로 검증 코드는 아래와 같이 equal 한지 notEqual 한지 작성할수 있습니다.

 @Test
    void 테스트() {
    String name = "신재원";
 	org.assertj.core.api.Assertions.assertThat(name).isEqualTo("신재원");
    org.assertj.core.api.Assertions.assertThat(name).isNotEqualTo("홍길동");
}

  • org.junit.jupiter.api.Assertions 사용시 작성 방식 입니다.

최종적으로 검증 코드는 아래와 같이 괄호 한 묶음에서 값을 비교할수 있습니다.

@Test
    void 테스트() {
       String name = "신재원";
       org.junit.jupiter.api.Assertions.assertEquals(name, "신재원");
}

2. 가독성과 표현력

이제 부터 설명을 작성하는것은 org~ 라이브러리 주소를 빼고 작성하겠습니다.

@Test
    void 테스트() {
       String name = "신재원";
        
       // 1. assertj 사용 
       Assertions.assertThat(name).isEqualTo("신재원");
       
       // 2. junit 사용
       Assertions.assertEquals(name, "신재원");
}

assertj 사용 코드는 가독성과 표현성이 좋습니다. 이유로는 실제 값인 name 변수를 예상값인 신재원 과 검증 하는지 쉽게 유추 할수 있으며 왼쪽에서 오른쪽 으로 자연스럽게 읽히게 됩니다.
(테스트 단계를 체이닝 하여 표현력이 좋아 지게 됩니다)

하지만 junit 을 사용한 코드는 어느 값이 실제값이고, 어느값이 예상값인지 쉽게 유추 하기 어려울수 있습니다.

이와 같이 assertj 를 사용하면 가독성과 표현력이 좋아지게 됩니다.

2. 다양한 검증 메소드

  • (다양한 메소드를 조금은 알고있어야 한다.)

junit 사용

  @Test
    void 테스트() {
        List<String> names = List.of("신재원", "홍길동");

       // true 값 반환 검증
       Assertions.assertTrue(names.containsAll(List.of("신재원", "홍길동")) 
                && names.size() == 2);
       Assertions.assertTrue(names.containsAll(List.of("신재원", "홍길동")));

       // 배열로 변환후 true 값 반환 검증
       Assertions.assertArrayEquals(names.toArray(),
                new String[]{"신재원", "홍길동"});

    }
  • Junit 에서는 간단한 메소드만 제공해주기 때문에, 비교를 하기위해 다양한 조건을 추가해서 작성해줘야 합니다.

assertj 사용

    @Test
    void 테스트() {
        List<String> names = List.of("신재원", "홍길동");

        /* 
        true 값 반환 검증
        containsExactlyInAnyOrder : names 컬렉션 객체에 데이터가
        순서와 상관없이 값만 일치한지 확인
        */
        Assertions.assertThat(names)
                .containsExactlyInAnyOrder("신재원", "홍길동");

        /* 
        containsExactly : names 컬렉션 객체에서 지정한 데이터의
        순서와 값이 일치한지 확인
        */
        Assertions.assertThat(names)
                .containsExactly("신재원", "홍길동");

 /* 
contains : names 컬렉션 객체에서 지정한 데이터가 순서와 상관없이 존재하면 되고,
다른 원소를 더 추가해도 됩니다.
*/
        Assertions.assertThat(names)
                .contains("홍길동", "신재원");
    }
  • assertj 에서는 다양한 메소드를 제공해주기 때문에, 다른 작업이 따로 필요 없으며, 가독성이 좋아지며 통일성이 생기게 됩니다.
    assertj는 정말 다양한 메소드들 제공하기 때문에, assertThat() 작성후 .을 찍어 자동완성 기능을 잘 활용하면 좋습니다.

3. 메소드 체이닝

Assertj 에서는 메소드 체이닝 기능을 제공합니다.

메소드 체이닝이란 간단히 말하여, . 을 통해 Builder 패턴 처럼 사용한다는 것입니다.


  • 아래 코드와 같이 다양한 메소드를 사용 (체이닝)해서 검증코드를 작성 할수 있습니다.
  @Test
    void 테스트1() {
        Assertions.assertThat("Hello jaewon")
                .isNotBlank()
                .contains("Hello")
                .containsOnlyOnce("jaewon")
                .startsWith("Hello");
    }
   @Test
    void 테스트2() {
        Assertions.assertThat(98)
                .isPositive() // 양수인지 확인
                .isGreaterThan(90)
                .isNotEqualTo(99)
                .isLessThan(100)
                .isEqualTo(98);
    }
    

마무리

이러한 3가지의 차이점을 적어서 정리하였지만, assertj 를 사용해야 이유는 정말로 많이 있습니다.
이제부터 assertj 를 사용해야 하는 이유와 방법에 대해 알았으니 테스트 코드 작성시 이유를 리마인드 하면 좋을것 같습니다.

0개의 댓글