공부 - 언어, 프레임워크/java

[JUnit] 단위 테스트

아직해떴다 2020. 3. 29. 20:38

1. JUnit이란?

Java에서 사용하는 기능 단위별 테스트를 위한 라이브러리다.

* Java를 배우는 학부생들이라면 한번즘 접했을거라 생각된다.

 

2. 중요한가?

궁극적인 목표를 보고 생각한다면, JUnit과 유사한 기능들을 가진 툴/라이브러리들이 중요한 것은 아니다. 

중요한 것은 소프트웨어 개발 과정 중에 정리된 케이스로 테스트를 진행한다는 단계가 있다는 것이다.

문서로 잘 정리할 귀찮음을 감수할 자신이 있거나 혹은 자기 입맛에 맞는 테스팅 툴을 개발할 수 있다면 그걸로 상관없다.

* 자바로 개발하다가 파이썬으로 개발할 일이 생긴다면 어차피 JUnit은 쓸 수도 없다. 

 

3. 사용 방식 

테스트할 기능(method)를 대상으로 "예상되는 결과""method 호출 시 실제 반환 결과"를 비교하는 것이다. 

* 단위 테스팅 툴을 사용하지 않는 기업에서는 기능을 통째로 실행하거나 하위 기능을 복붙해서 실행하는 방식으로 많이 개발한다. 당장 내가 다녀본 회사나 주변 지인들이 있는 곳 대부분이 그렇게 하고 있다. (규모가 있거나 여유가 있는 곳이 아니면 대부분 이런 식으로 진행할 것이다.)

 

4. 환경 및 dependency

Spring boot + gradle

org.springframework.boot:spring-boot-starter-test

내가 주로 개발하는 환경이 Spring이어서 이렇게 설정한 것이지 JUnit만 사용할 거라면 JUnit라이브러리만 import하면 된다.

 

5. Spring boot 구성도

Spring boot 구성

Spring 환경에서 개발을 하다보면 src하위에 자동으로 생성되는 test 폴더를 본 적이 있을 것이다. 

개발된 기능의 test용 코드를 관리하라고 주는 별도의 경로이니, Spring에서 진행중이라면 활용하자.

 

테스트의 대상은 servicelogic/tdd/Service/impl에 위치한 TddServiceImpl이고, 

테스트 실행은 test폴더 하위에 있는 servicelogic/tdd/controller에 위치한 TddControllerTest이다. 

실행 방법은 TddControllerTest에서 TddServiceImpl의 method를 호출하여 TddControllerTest에 설정된 예상된 결과와 비교하는 것이다. 

 

6. 소스 코드 

A. TddServiceImpl : 서비스 로직이 위치할 코드

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Service
public class TddServiceImpl implements TddService {
 
    @Override
    public List selectTest() throws Exception {
 
        System.out.println("TddServiceImpl > selectTest");
 
        List<Integer> temp = new ArrayList<Integer>();
        temp.add(1);
        temp.add(2);
        temp.add(3);
        temp.add(4);
        temp.add(5);
 
        return temp;
    }
}
 
 
 

테스트 용 결과값으로 [1,2,3,4,5] 가 저장된 List를 반환해준다. 

 

B. TddControllerTest : 서비스 로직을 테스트할 코드 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class TddControllerTest {
 
    @Autowired
    TddService tddService;
 
    @Test
    public void test_Call() throws Exception {
        List testResult = new ArrayList();
        testResult.add(1);
        testResult.add(2);
        testResult.add(3);
        testResult.add(4);
        testResult.add(5);
        assertEquals(testResult, tddService.selectTest());
    }
    
}
 
 

TddServiceImpl의 반환값과 비교할 값을 설정한 후, 대상 method를 호출하여 비교한다. 

 

17번째 줄의 assertEquals 함수가 JUnit에서 제공되는 비교 함수이다. 

만약 반환값의 특정 키값만 확인하고 싶을 때와 같이 값 이외의 다른 것을 비교하고 싶다면, 테스팅 코드 내에 원하는 조건을 추가해 확인할 수 있다.

또한 같은 코드에 여러 테스팅 호출 함수를 작성하더라도, 원하는 method만을 별도로 실행할 수 도 있다. (이게 단위 테스트 강점이 아닐까)

 

7. 정리

서버 API를 개발할 때, 하나의 API를 대상으로 개발할수록 점점 기능이 쌓여간다.

API내에 백엔드에서 사용할 데이터가 발생하고 저장되며 별도의 처리를 하게 된다. 

이렇게 쌓여갈 때 마다 테스트하기 점점 힘들어지고 소스코드 몇 줄 추가하여 거기만 테스트 하려고 하면 그 전에 구현된 전체 로직을 계속 반복 실행하며 쌓여가는 로그를 쳐다보고 있어야 한다. 

학부생 때 처음이자 마지막으로 써봤던 JUnit을 이제와서 찾게 된 것은 사실 실무에서 이러고 있는게 너무 귀찮고 짜증나서이다. 

가끔 API 호출 조건 자체가 까다로울 때가 있는데, 그럴 땐 진짜 환장한다. (호출 시 파라미터가 암호화가 되어있다던가)

 

Agile 개발론 중에는 TDD(Test Driven Development - 테스트 주도적 개발)라는 것이 있다. (사실 아는게 이거밖에 없다.)

TDD를 지향하기 위해서 테스트 케이스를 정형화하고 테스트 실행에 쉽게 접근할 수 있어야 하는 법인데, 그 대표적인 방식이 바로 단위 테스트이다. 

 

학생땐 이걸 왜 배우나 했지... 어허허 

학생 때 배우는 거 쓸모 없다는 사람 많지만 절대 그렇지 않으니까 공부 열심히 하자.