[Java] 효율적인 JUnit 사용 방법과 유용한 팁

 

소프트웨어 개발에서 있어서 단위 테스트(Unit Testing)는 중요한 절차입니다. 소프트웨어의 각 유닛(Unit)을 테스트하고, 전반적인 프로젝트 생산성과 유지 보수에 영향을 미치기 때문이죠. 이와 관련하여 이번 글에서는 테스트 주도 개발과 단위 테스트에 대해 간단히 알아보고, 자바 프로젝트에서 사용되는 단위 테스트 도구인 JUnit의 사용 방법과 유용한 팁을 정리해보았습니다.

 

테스트 주도 개발과 JUnit

1) 테스트 주도 개발(TDD)

테스트 주도 개발(Test-driven Development)이란, 테스트 케이스를 작성하고 소스 코드가 이를 통과하는지 반복 확인하며 프로젝트를 진행하는 것을 말합니다. 테스트 주도 개발은 소프트웨어 개발 방법론 중 하나로서 간단히 ‘TDD’라고도 하는데요. TDD는 기능의 구현 목표에 집중하여 개발 생산성을 높이고, 이후 발생할 리팩토링(Refactoring)을 지속할 수 있게 하는 근간이 되기도 합니다.

 

2) 단위 테스트(Unit Testing)

단위 테스트는 소프트웨어의 클래스(Class), 함수(Function) 등 각 단위가 구현 목표에 맞게 동작하는지를 확인하는 단계입니다. 자바 프로젝트에서는 주로 클래스를 기준으로 각 메소드(method)가 예상한 대로 정확히 동작하는지를 파악합니다.

 

3) 자바 단위 테스트 도구(JUnit)

제이유닛(JUnit)은 자바 프로젝트를 위한 단위 테스트 프레임워크(Unit Testing Framework)입니다. 테스트 코드를 작성하기 위해 필요한 다양한 API를 제공하며, 자동으로 테스트를 수행하고 결과를 출력해줍니다. JUnit은 1997년에 출시되어 오래된 역사를 가지고 있으며, 자바 프로젝트의 테스트 주도 개발에 있어서 핵심적인 역할을 하고 있습니다.

 

 

JUnit 버전 및 사용 방법

1) JUnit 버전 및 구성

JUnit은 현재 버전 5까지 발표되었으며, 제이유닛 플랫폼(JUnit Platform), 주피터(JUnit Jupiter), 빈티지(JUnit Vintage) 등 3개의 모듈로 구성되어 있습니다. 이 중에서 JUnit Platform이 핵심 모듈이며, 인텔리제이(IntelliJ), 이클립스(Eclipse), 비주얼 스튜디오 코드(VS Code) 등 대표적인 IDE에 내장되어 있습니다. 그 외 JUnit Jupiter는 프로그래밍 모델과 확장 모델을, JUnit Vintage는 이전 버전의 JUnit을 지원하는 모듈입니다.

 

Junit 버전
<출처: JUnit 5 Tutorial>

 

2) 테스트 케이스 작성 및 실행

JUnit을 사용하려면 먼저 각 클래스 별로 테스트 클래스(Test Class)를 만들어야 합니다. 그다음 테스트 클래스 안에 테스트 메소드를 작성하고 @Test 애노테이션(Annotation)을 붙입니다. JUnit은 @Test Annotation이 붙은 메소드에 대해 자동으로 테스트를 실행하고 결과를 출력하게 됩니다.

 

테스트 케이스 작성
<출처: 곰씨네 IT 블로그>

 

위 코드는 소수(Prime Number)를 생성하는 함수와 짝수(Even Number) 여부를 판별하는 함수에 대한 간단한 테스트 케이스입니다. JUnit 테스트 케이스에서는assertEquals(), assertTure() 등 다양한 assert 메소드를 사용하여 함수 호출 시 기대 값(expected value)과 실제 값(actual value)을 비교하는 방식으로 테스트를 진행합니다.

 

 

JUnit 테스트 케이스 명명 규칙

1) 테스트 케이스 명명 규칙

테스트 케이스 명명 규칙(Test Case Conventions)은 일관성 있게 테스트 케이스를 작성하도록 만든 규칙을 의미합니다. 현재 다양한 규칙이 알려져 있으며, 각 프로젝트에 맞게 별도의 명 명규칙을 지정하여 사용합니다. 테스트 케이스 명명 규칙은 개발 생산성에 영향을 미치기 때문에 프로젝트 진행 시 미리 충분한 검토가 필요 부분이기도 합니다.

 

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

2) 주로 사용되는 명명 규칙

대표적으로 사용되는 테스트 케이스 명명 규칙으로는 여러 가지가 있지만 아래와 같이 크게 3가지 범주로 나눠볼 수 있습니다. (참고: 7 Popular Unit Test Naming Conventions)

  1. Method_State_Expected
  2. Feature to be tested
  3. Given, Should, When, Then 사용

 

첫 번째 명명 규칙은 method 이름을 기준으로 테스트 케이스를 작성하는 것입니다. 직관적으로 어떤 method를 테스트하는 것인지 알 수 있는 장점이 있지만, method 이름이 바뀌면 테스트 케이스명도 바뀌어야 하는 단점이 있습니다. (예시: isAdult_AgeLessThan18_False)

 

두 번째 명명 규칙은 테스트하고자 하는 기능을 기술하듯이 적는 방식입니다. 이 방식을 활용하면 method 변경에 구애받지 않고 리팩토링 작업을 할 수 있습니다. 다만, 영어가 부족하거나 개발 경험이 적으면 테스트 케이스 작성에 어려움을 느낄 수 있으며, 일관성이 떨어져 보일 수도 있습니다. (예시: IsNotAnAdultIfAgeLessThan18)

 

세 번째 명명 규칙은 Given, Should, When, Then 등의 단어를 활용하는 방식입니다. 이 규칙을 사용하면 일관성 있게 테스트 케이스를 작성할 수 있으며, method 이름 변경에 영향을 받지 않을 수 있습니다. 따라서 앞선 두 가지 방식의 단점을 어느 정도 보완한 방식이라고 할 수 있습니다. (예시: Should_ThrowException_When_AgeLessThan18)

 

 

효율적인 JUnit 사용 팁

1) 테스트 케이스 명명 규칙 선정

앞서 대표적인 3가지 테스트 케이스 작성 규칙을 살펴보았는데요. 이 중에서 ‘어떤 방식이 무조건 좋다’라는 것은 없습니다. 따라서 테스트 케이스 명명 규칙은 전체적인 프로젝트 규모와 기간, 개발자의 테스트 케이스 작성 수준 등을 고려하여 선정해야 합니다.


2) 테스트 데이터 생성

테스트 주도 개발을 하다 보면 테스트 데이터를 만드는 데 많은 시간을 쓰게 됩니다. 특히 테스트 데이터를 수동으로 만들면 시간도 많이 걸리고 데이터가 편향성을 가질 수도 있습니다. 따라서 아래 그림과 같이 랜덤하게 문자열이나 숫자를 자동으로 생성하는 함수를 활용하면, 테스트 케이스 작성 시간을 절약할 수 있을 뿐만 아니라 데이터 편향성도 제거할 수 있습니다.

 

테스트 데이터 생성
<출처: 곰씨네 IT 블로그>

 

3) 테스트 케이스 당 하나의 Assertion 사용

테스트 케이스를 작성하다 보면 여러 개의 assert 메소드를 사용하거나 assertAll을 넣는 경우가 있습니다. 이렇게 하면 테스트 실패 시 디버깅이 오래 걸릴 수 있으며, ‘단위 테스트 케이스는 단일 기능을 테스트해야 한다’는 원칙에도 부합하지 않게 됩니다. 따라서 만약 한 개의 테스트 케이스에 여러 개의 assertion을 넣고 싶다는 유혹이 든다면, 해당 테스트 케이스를 더 잘게 쪼갤 수는 없는지 다시 생각해 볼 필요가 있습니다.

 

 

많은 시행착오와 경험이 필수

이상 테스트 주도 개발과 단위 테스트에 대해 간단히 알아보고, 자바 테스트 도구인 JUnit의 사용 방법과 유용한 팁을 정리해 봤습니다. JUnit은 테스트 케이스를 작성하고 실행하는 것을 편리하게 해 준 도구입니다. 다만, 제대로 테스트 케이스를 작성하고 JUnit을 활용하려면 많은 시행착오와 경험을 쌓아야 하는데요. 추가로 JUnit 최신 버전에 대한 자세한 내용을 찾아보고 싶으면 Junit5 User Guide를 참고해 보길 바랍니다.

 

[출처] https://yozm.wishket.com/magazine/detail/1748/

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
78 [Java 일반] 07-06 함수형 프로그래밍 졸리운_곰 2023.09.04 6
77 [Java 일반] [JAVA] JAVA의 람다식 사용법 및 다양한 작성 예제 file 졸리운_곰 2023.09.04 39
76 [Java 언어] [Java] 람다식(Lambda Expressions) 사용법 및 예제 졸리운_곰 2023.09.04 22
75 [Java][jupyter notebook][!java] 주피터 노트북에서 자바 실행 환경구축. java on jupyter notebook file 졸리운_곰 2023.08.24 24
74 [java maven] jar 파일 의존성 한번에 다운로드 maven 사용 졸리운_곰 2023.08.18 33
» [Java] 효율적인 JUnit 사용 방법과 유용한 팁 file 졸리운_곰 2022.10.20 32
72 [Java] Java Console Input and Output Examples 졸리운_곰 2021.11.07 22
71 [Java] \ 문자 빠구기 : replaceAll 사용시 특수문자 졸리운_곰 2021.07.13 37
70 이클립스에서 java 버전 변경 file 졸리운_곰 2021.04.29 33
69 JAVA) 예외처리(throw , throws) file 졸리운_곰 2021.01.24 21
68 예외처리 (throwable, exception, error, throws) file 졸리운_곰 2021.01.21 39
67 [Java] 자바 extends, implements 차이 file 졸리운_곰 2020.12.10 48
66 Maven 배포시 Local Jar 파일과 함께 하기! file 졸리운_곰 2020.10.06 16
65 How to add a local lib directory to Maven 졸리운_곰 2020.10.06 17
64 [Maven] 외부 jar 의존성 추가, war build 시 외부 jar 포함시키기 졸리운_곰 2020.10.05 239
63 Spring Boot 프로젝트에 외부 라이브러리(jar) 추가하기 졸리운_곰 2020.10.05 695
62 [maven 설정] Jackson Databind » 2.6.7.1 졸리운_곰 2020.10.05 33
61 [maven 설정] MongoDB Java Driver » 3.12.6 졸리운_곰 2020.10.05 18
60 Maven 에 직접 jar 라이브러리 추가하기!!! ( 외부 repository 사용이 안될때) + scope 정리 졸리운_곰 2020.10.05 20
59 추상(abstract) 클래스가 필요한 기본적인 이유 졸리운_곰 2019.10.30 68
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED