JUnit 단위 테스트

2022. 9. 7. 03:17자바 & Spring

많은 테스트코드를 작성할수록, 견고한 서비스를 만들 수 있다는 말을 들었다. 

큰 서비스를 다루는 회사 대부분이 테스트코드 작성 경험을 요구하고 있고, 그만큼 테스트코드는 개발자에게 빠질 수 없는 요소가 되었다.

이번 포스팅은 단위테스트에 대한 내용이다.

 

단위테스트

단위테스트는 어플리케이션에 있는 개별적인 코드, 모듈이 예상대로 잘 작동하는지 단위별로 쪼개서 테스트하는 것이다.

주로 모든 함수와 메서드에 대해 실시한다.

 

왜 굳이 단위테스트를 해야 할까? 단위테스트를 쓰지 않는다면?

단위테스트를 쓰지 않고 System.out.println() 으로 출력된 값을 내가 확인하면서 테스트를 한다고 해보자. 

  1. 코드를 작성하고 ,프로그램 (톰캣) 실행
  2. postman 으로 HTTP 요청
  3. 요청 결과를 출력해 그 값을 눈으로 검증
  4. 결과가 다르면 프로그램을 중지하고 다시 코드를  수정.

테스트 결과가 예상과 다르면 1~4번 과정을 반복해야 한다.

톰캣을 실행하는데도 시간이 꽤 걸리고, Println()으로 출력해서는 규모가 커질수록 너무 번거롭고 골치 아플 것이다. 또 println()으로 나온 값을 눈으로 검증해야 하는데, 테스트코드를 작성하면 사람이 눈으로 검증하지 않고 자동으로 검증을 해준다.

이것이 단위테스트의 강점이다.

 

 

단위테스트가 주는 이점

  • 개발단계 초기에 오류를 발견하게 도와준다.

테스트를 제대로 하지 않고 1 부터 10 까지의 기능을 개발했는데 중간에 3부터 오류가 생겨서 4~10의 내용이 전부 틀어져버리게 된다면? (영향을 준다는 가정 하에서)

기능의 모든 메서드에 대해 단위테스트를 한다면 3에서 오류가 생겼을 때, 3을 고친 후 4를 작성할 것이다.

 

  • 기존 기능이 잘 작동하는 것을 보장해준다.

기존 서비스를 확장해 A라는 기능에 B라는 기능을 더했더니, 기존에 잘되던 A기능에 문제가 생긴것을 발견했다.

기능을 하나 하나 추가할 때마다 모든 경우를 테스트 할 수는 없다. 이렇게 기능이 추가될 때, 기존기능이 잘 작동된다는 것을 보장해주는 것이 테스트 코드이다. 

A라는 기존 기능과 더불어 여러 경우에 대해 테스트코드를 작성해 놓았다면 이를 수행만 하면 문제를 조기에 찾을 수 있다. 이 말은 확장에 강하다는 말이고 결과적으로 객체지향적인 프로그래밍을 할 수 있게 도와준다.

 

이처럼 많은 기능을 추가하고, 확장하는 서비스 기업에서는 필수적인 기술이 되었다.

 

프레임워크

단위테스트 코드 작성을 도와주는 프레임워크들에는 xUnit 이라는 것들이 있다. Java 에서는 JUnit을 사용한다.

버전은 JUnit5 까지 나왔다.

 

다음은 JUnit4 를 사용한 단위테스트 코드 작성 예시이다.

 

내가 팀 프로젝트로 했던 웹 어플리케이션에 단위테스트 코드를 추가 작성해보았다.

(url : https://github.com/HealthCare-Web-App/BackEnd

 

단위테스트 시 함수이름은 영어뿐만이 아니라 한글로도 작성이 가능해서 신기했다. (package, import 는 너무 길어져서 생략!)

 

실습

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class UserServiceTest {
    @Autowired
    UserService userService;

    @Test
    public void userId로_찾기() throws Exception{
        User user = new User("id11","pw1","닉네임11");
        userService.save(user);
        User findUser = userService.findOne(user.getId());

        assertEquals(findUser.getId(), user.getId());
    }


    @Test(expected = DuplicateUserException.class)
    public void 중복검증() throws Exception{
        User user1 = new User("id1","pw1","짱구");
        userService.save(user1);
        User user2 = new User("id2","pw1","짱구");
        userService.duplicateCheck(user2.getLogin_Id(), user2.getNickname());

        fail("닉네임 중복!");
    }


    @Test(expected = NoUserIdException.class)
    public void 없는_회원을_조회() throws Exception{
        User findUser = userService.findOne(123L);
        fail("없는 유저입니다.");
    }

}

우선 간단하게 3개의 테스트코드만 포스팅했다.

 

1. 유저의 식별자인 userId값으로 유저가 잘 찾아지는지

userService.findbyUserId() 함수를 검증

 

2. 유저가 회원가입을 하게 되면, 로그인 아이디나 닉네임이 겹치면 다시 만들게 되어있다.

DuplicateUserException 오류를 뿌리는지 검증

 

3. 프론트단에서 요청을 보낸 유저의 식별자가(userId) 가 DB 상에 없는 경우 유저가 없다고 오류를 내게 만들었다.

NoUserIdException 오류를 뿌리는지 검증

 

결과



3개 테스트를 모두 통과하였다.

 

느낀점

내껀 큰 프로젝트가 아니라 확 체감이 오지는 않지만, 테스트를 자동으로 검증해준다는게 정말 편리한 것 같다.

위처럼 여러 개의 함수를 작성해놓고 상위의 클래스만 실행해도 그 안의 모든 함수들의 테스트 성공, 실패 여부를 알 수가 있으니 직접 테스트코드를 작성해서 눈으로 검증하는 건 한계가 있다고 볼 수 밖에. 규모가 큰 서비스에서는 필수라 할 수 있겠다.

앞으로는 테스트코드를 작성하는 습관을 길러야겠다.

'자바 & Spring' 카테고리의 다른 글

빈 생명주기 콜백  (0) 2022.10.26
컴포넌트 스캔, 의존관계 자동 주입  (2) 2022.09.25
싱글톤(singleton) 패턴  (0) 2022.09.24
Spring 특징과 장점  (0) 2022.09.17
타임리프(thymeleaf)  (0) 2022.05.04