Testing - 단위 테스트 (JUnit)

귀찮Lee·2022년 7월 17일
0

Spring

목록 보기
25/30

◎ 테스트

  • 테스트

    • 어떤 대상에 대한 일정 기준을 정해놓고, 그 대상이 정해진 기준에 부합하는지 부합하지 못하는지를 검증하는 과정
    • 목적 : 테스트 대상이 검증 과정에 잘 통과하게 만들어 최대한 더 나은 결과를 얻기 위해 (모든 테스트가 100% 완벽할 수는 없지만, 더 좋은 결과를 얻기 위해
    • Postman을 이용하여 결과를 확인하는 것도 테스트의 일종, 하지만 테스트 해야 할 내용이 많아지기 때문에 자동화가 필요.
  • 테스트의 종류 (단위 기준)

    • 기능 테스트

      • 사용자 입장에서 어플리케이션이 제공하는 기능이 올바른지 테스트 (연관 대상이 많음; 외부 API, ...)
      • 테스트 주체가 주로 개발자가 아닌 제3자이다.
    • 통합 테스트

      • 개발자 또는 개발팀이 테스트의 주체가 됨
      • 클라이언트 툴 없이 테스트 코드를 이용해 테스트함
      • 어플리케이션에 여러 계층이 연관되어 있어 특정 부분에 독립적인 테스는 할 수 없음
    • 슬라이스 테스트 (부분 통합 테스트)

      • 어플리케이션을 특정 계층으로 쪼개어 테스트 (API 계층, 서비스 계층, 데이터 엑세스 계층)
      • 테스트 범뤼를 어느 정도 좁히는 것이 가능
      • Mock 객체를 이용하여 계층별로 끊어서 테스트 가능
    • 단위 테스트

      • 비즈니스 계층(서비스 계층, 공통 기능)을 메서드 단위로(작은 단위로) 독립적으로 테스트
      • 다른 계층은 DB, HTTP 등과 연결되어 있으므로, 단위 테스트라 보기 힘들다.

◎ 단위 테스트

  • 단위 테스트

    • 비즈니스 계층(서비스 계층, 공통 기능)을 메서드 단위로(작은 단위로) 독립적으로 테스트
    • 단위 테스트 코드는 대부분 메서드 단위로 작성
    • 데이터베이스의 상태가 테스트 이 전과 이 후가 동일하게 유지될 수 있다면 데이터베이스가 연동된다고 해도 단위 테스트에 포함될 수 는 있다. (단, 최대한 독립적이고, 작은 단위인 것이 더 좋음)
  • 단위 테스트의 필요성

    • 매번 특정 과정을 거쳐 요청 테스트 하는 것은 번거롭기 때문에 자동화가 필요
    • 작은 단위에서의 테스트는 버그를 미리 찾기 용이함
    • 테스트 케이스가 잘 짜여있다면, 버그 리포트를 전달 받았을때, 단계적으로 찾아가기가 용이
  • 단위 테스트의 원칙 (F.I.R.S.T)

    • Fast : 작성한 테스트 케이스는 빨라야 한다 (느려서 돌리기 힘들다면, 문제를 찾기가 힘듦)
    • Independent : 테스트 케이스는 각각 독립적이어야 한다. (통과 여부가 테스트 순서에 상관없어야 한다.)
    • Repeatable : 어떤 환경에서도 반복해서 실행이 가능해야 된다. (외부 리소스와 연동 경우에는 끊어서 테스트 하는것이 바람직함)
    • Self-validating : 자체적으로 검증 결과를 보여주어야 함
    • Timely : 단위 테스트는 테스트 하려는 기능 구현을 하기 직전에 작성해야 한다 (TDD 참고)

◎ JUnit

  • JUnit

    • Java 언어로 만들어진 애플리케이션을 테스트 하기 위한 오픈 소스 테스트 프레임워크
    • 이외 TestNG 라는 테스트 프레임워크도 있음
  • JUnit 기본 작성법

    import static org.junit.jupiter.api.Assertions.assertEquals;
    
    public class HelloJUnitTest {
        @DisplayName("Hello JUnit Test")  // 테스트 실행시 표기
        @Test
        public void assertionTest() {
            String expected = "Hello, JUnit";
            String actual = "Hello," + " JUnit";
    
            assertEquals(expected, actual); // 값 검증 메서드
        }
    }
  • JUnit 검증 메서드 (Assertion 메서드)

    • assertEquals(expected, actual) : 두 값이 같은지 판단
    • assertNotEquals(expected, actual) : 두 값이 다른지 판단
    • assertNotNull(actual, "Message") : 해당 값(actual)이 Null인지 판단
    • assertThrows(Exception.class, () -> doSomething()) : 해당 Exception이 생기는지 판단
    • assertDoesNotThrow(() -> doSomething()) : 예외가 발생 안하는지 판단
    • 추가 자료
  • JUnit Assumption 메서드

    • 특정 경우에서만 테스트를 실행
    @DisplayName("Assumption Test")
        @Test
        public void assumptionTest() {
            assumeTrue(System.getProperty("os.name").startsWith("Windows")); // os가 윈도우일때만 해당 테스트를 진행
    //        assumeTrue(System.getProperty("os.name").startsWith("Linux"));
            System.out.println("execute?");
            assertTrue(processOnlyWindowsTask());
        }
  • 테스트 케이스 전처리, 후처리

    • @BeforeEach : 해당 클래스의 각 테스트를 실행하기전, 해당 메서드를 실행
    • @Before : 해당 클래스의 테스트를 실행하기전, 딱 한번 실행
    • @AfterEach : 해당 클래스의 각 테스트가 끝날때마다 해당 메서드를 실행
    • @After : 해당 클래스의 테스트들이 모두 끝나고, 딱 한번 실행
    public class BeforeEachTest {
    
        @BeforeEach
        public void init() {
            System.out.println("Pre-processing before each test case"); // 총 두번 호출됨
        }
    
        @DisplayName("@BeforeEach Test1")
        @Test
        public void beforeEachTest() {}
    
        @DisplayName("@BeforeEach Test2")
        @Test
        public void beforeEachTest2() {}
    }
profile
배운 것은 기록하자! / 오류 지적은 언제나 환영!

0개의 댓글