-
@ParameterizedTest☕️ java 2023. 10. 25. 01:19
Test 코드를 작성하는 도중 실패 케이스마다 실패 테스트 메서드를 만들다보니 중복되는 코드도 많아지고 이로 인해 코드의 양이 많아지는 문제가 발생했다.
이런 문제를 해결하기 위해 @ParameterizedTest 를 사용해 해결하고자 알아보게 되었다.
📌 Parameterized Test
💡 Parameterized Test
- 다른 인수로 여러번 테스트를 실행하는 것을 가능하게 한다.
- @Test 대신 @ParameterizedTest 를 사용한다.
- 최소 하나의 source 어노테이션을 붙여주어야 한다.💡 다양한 Source 종류들
1️⃣ ValueSource
@ParameterizedTest @ValueSource(strings = {"beomsic", "beom"}) void valueSourceTest(String name) { }
- argument가 하나인 테스트에 사용
- short, byte, int, long, float, double, char, boolean, String, java.lang.Class 타입 지원
2️⃣ NullSource, EmptySource, NullAndEmptySource
@ParameterizedTest @ParameterizedTest @NullAndEmptySource void nullAndEmptySourceTest(List<Integer> list) { System.out.println(list); }
결과
NullSource null을 보낸다 EmptySource 비어있는 배열, 컬렉션, 문자열 등을 반환 NullAndEmptySource NullSource와 EmptySource를 합쳐 놓은 것 3️⃣ EnumSource
@ParameterizedTest @EnumSource void enumSourceTest(TestEnum testEnum) { } public enum TestEnum { BEOMSIC, BEOM; }
결과
4️⃣ MethodSource
@ParameterizedTest() @MethodSource("InputStringStream") void calculate_Success(String inputString, int strikeCount, int ballCount) { ... } static Stream<Arguments> InputStringStream() { return Stream.of( Arguments.of("123", 3, 0), ); }
- 테스트 클래스 내의 메소드 혹은 외부 클래스의 메소드가 반환하는 값을 source로 삼는다.
- 테스트 클래스 내에 있고 @TestInstance(Lifecycle.PRE_CLASS)를 붙인 것이 아니라면 모두 static 메소드여야 한다.
- 한 파라미터뿐 아니라 여러 파라미터도 넣을 수 있다.
- 파라미터를 한 개만 넘기려면 Stream을 반환
- 파라미터를 여러개 넘기려면 Stream<Arguments>를 반환
5️⃣ CsvSource
@ParameterizedTest @CsvSource({ "apple, 1", "banana, 2" }) void csvSourceTest(String fruit, int number) { }
- , 로 분리된 문자열을 테스트 메소드의 파라미터로 넣어준다.
🧑🏻💻 사용해보기
👀 기존에 내가 했던 테스트 코드
@Test void generateNumber_InvalidInputStringMoreThanLimitSize_ThrownException() { // given // when // then Assertions.assertThatThrownBy(() -> BaseBallNumber.generateNumber("1234")) .isInstanceOf(IllegalArgumentException.class); } @Test void generateNumber_InvalidInputStringWithAlpha_ThrownException() { // given // when // then Assertions.assertThatThrownBy(() -> BaseBallNumber.generateNumber("abc")) .isInstanceOf(IllegalArgumentException.class); } ...
🔥 @ParameterizedTest를 적용한 테스트 코드
@ParameterizedTest(name = "{0} 실패, 값 : {1}") @MethodSource("inValidNumberArray") void generateNumber_InvalidInputString_ThrownException(String reason, String inputNumber) { // given // when // then Assertions.assertThatThrownBy(() -> BaseBallNumber.generateNumber(inputNumber)) .isInstanceOf(IllegalArgumentException.class); } static Stream<Arguments> inValidNumberArray() { return Stream.of( Arguments.of("3자리보다 큰 숫자 문자열이 들어온 경우", "1234"), Arguments.of("3자리보다 작은 숫자 문자열이 들어온 경우", "12"), Arguments.of("영어 소문자가 포함된 경우", "a12"), Arguments.of("영어 소문자로만 이루어진 경우", "abc"), Arguments.of("한글로만 이루어진 경우", "테스트"), Arguments.of("특수문자가 포함된 경우", "~!@") ); }
📖 참고자료
'☕️ java' 카테고리의 다른 글
☕️ Java 17 (1) 2023.10.25 🆚 AssertJ과 JUnit 의 Assertions 비교 (1) 2023.10.25 👀 Unit Test 네이밍 컨벤션 (0) 2023.10.24 일급 컬렉션 (1) 2023.10.24 🧪 JMH (Java Microbenchmark Harness) (1) 2023.10.23