μ°ν μ½ level1 1μ£Όμ°¨ - JUnitμ νμ©ν λ¨μ ν μ€νΈ μ΄λ‘ λ° μ€μ΅ λ¨μν μ€νΈμ λν΄μ λ°°μ λ€. νλ λλ λ¨μ ν μ€νΈλ μ²μμ΄λΌ π μ²μ λ°°μ΄ JUnit5λ₯Ό μ΅νκΈ° μν΄ μ 리ν΄λ³Έλ€.
κ³μ μΆκ° μμ βοΈ
JUnitμ΄λ
- μλ° νλ‘κ·Έλλ° μΈμ΄λ₯Ό μν λ¨μ ν μ€νΈ νλ μ μν¬
- xUnitμΌλ‘ μλ €μ§ λ¨μ ν μ€νΈ νλ μ μν¬ μ νκ΅°μ΄λ€.
- βλ¨Όμ ν μ€νΈ ν λ€μ μ½λ©β
- βμ‘°κΈ ν μ€νΈ, μ½κ° μ½λ©, μ½κ° ν μ€νΈ, μ½κ° μ½λ©β
νΉμ§
- ν μ€νΈλ₯Ό μμ±νκ³ μ€ννλ λ° μ¬μ©λλ μ€ν μμ€ νλ μ μν¬
- annotationμ μ 곡νλ€.
- ν μ€νΈ κΈ°λ κ²°κ³Όλ₯Ό μν assertionμ μ 곡νλ€.
- test runnerλ₯Ό μ 곡νλ€.
- ν리ν°λ₯Ό μ¬λ¦¬λ©° λΉ λ₯΄κ² μ½λλ₯Ό μμ±ν μ μκ² ν΄μ€λ€.
- μλμΌλ‘ ν μ€νΈκ° μ€νλ μ μμΌλ©° μ체μ κ²°κ³Όλ₯Ό νμΈνκ³ λ°λ‘ κ²°κ³Όλ₯Ό μ 곡νλ€.
- ν μ€νΈ cases λ° κΈ°ν ν μ€νΈ suitesλ₯Ό ν¬ν¨νλ test suitesλ‘ κ΅¬μ±λλ€.
- ν μ€νΈ μ±κ³΅μ μ΄λ‘, μ€ν¨μ λΉ¨κ°
λ¨μ ν μ€νΈ μΌμ΄μ€λ μ μ¨?
- λ©μλκ° μμλλ‘ λμνλμ§ νμΈνλ€.
- μνλ κ²°κ³Όλ₯Ό λΉ λ₯΄κ² νμΈνκΈ° μν΄μλ ν μ€νΈ νλ μ μν¬κ° νμνλ€.
- μ΄ μν μ JUnitμ΄ νλ€.
- μκ³ μλ μ λ ₯κ³Ό κΈ°λνλ μΆλ ₯μΌλ‘ μμ±λλ€.
- κ° μꡬ μ¬νμ λν΄ μ΅μ λ κ°μ λ¨μ ν μ€νΈ μΌμ΄μ€κ° νμνλ€. (μμ±, μμ±)
- μꡬμ¬νμ νμ μꡬμ¬νμ΄ μμΌλ©΄ μ¬κΈ°μλ λ κ°μ λ¨μ ν μ€νΈ μΌμ΄μ€κ° νμνλ€.
JUnit5 π
λͺ¨λ ꡬμ±
JUnit Platform
ν μ€νΈ νλ μμν¬λ₯Ό μ€ννλλ° κΈ°λ°μ΄ λλ λͺ¨λ νλ«νΌμμ λμνλ ν μ€νΈ νλ μ μν¬ κ°λ°μ μν TestEngine APIλ₯Ό μ μνλ€. command lineμμ console Launcherμ JUnit4 κΈ°λ° νκ²½μ νλ«νΌμμ μ€ννκΈ° μν JUnit 4 based Runner λ₯Ό μ 곡νλ€. κ°μ’ IDE λ° λΉλ λꡬμ μ‘΄μ¬νλ€.
JUnit Jupiter
ν μ€νΈλ₯Ό μν μλ‘μ΄ νλ‘κ·Έλλ° λͺ¨λΈ κ³Ό νμ₯ λͺ¨λΈμ μ‘°ν©μ΄λ€. μ£ΌνΌν°μ νμ νλ‘μ νΈλ νλ«νΌμμ μ£ΌνΌν° λμμ μν TestEngineμ μ 곡νλ€.
JUnit Vintage
νμ λ²μ μ μ€νν μ μλ TestEngineμ μ 곡νλ€.
Installation
mavenμ΄λ gradle νλ‘μ νΈμμ Jupiter Engine Dependency and Platform Runner Dependency μ¦ μ΅μ 2κ°μ dependencyκ° νμνλ€.
maven
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
<junit.jupiter.version>5.5.2</junit.jupiter.version>
<junit.platform.version>1.5.2</junit.platform.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${junit.platform.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
gradle
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.5.2")
testRuntime("org.junit.platform:junit-platform-runner:1.5.2")
Java Versions
Java8 μ΄μμ΄μ΄μΌ νλ€.
Tests μμ±νκΈ°
μ΄ λΆλΆμ κ°μ μκ°μ λ€λ€λ μ½λλ‘!
...
public class SetTest {
private Set<Integer> numbers;
@Test
void checkSizeOfSet(){
assertThat(numbers.size()).isEqualTo(4);
}
}
Test Class
μ΅μ νλμ ν
μ€νΈ λ©μλλ₯Ό ν¬ν¨νλ μ΅μμ ν΄λμ€
single constructor
μ¬μΌ νλ€.
Test Method
@Test
, @ParameterizedTest
λ±μ μ΄λ
Έν
μ΄μ
μ ν΅ν΄ ν
μ€νΈ λ©μλμμ λνλΈλ€.
assertJ
λ₯Ό ν΅ν΄ ν μ€νΈ μ½λμ κ°λ μ±μ λμ΄λ©° μλ¬ λ©μΈμ§λ₯Ό μ½κ² νμΈν μ μλ€.
곡λΆν Annotation λͺ κ°
@Test
λ©μλκ° ν μ€νΈ λ©μλμμ λνλΈλ€.
@ParameterizedTest
λ©μλκ° λ§€κ°λ³μκ° μλ ν μ€νΈμμ λνλΈλ€.
νλΌλ―Έν°λ₯Ό μ λ¬νλ λ°©λ²μ μλμ μ΄λ Έν μ΄μ κ³Ό λλΆμ΄ Sourceλ‘ λ겨μ€λ€.
@ValueSource
λ¨μΌ 리ν°λ΄ κ° λ°°μ΄μ ν
μ€νΈ λ©μλμ μ λ¬ν μ μμΌλ©°,
λ§€λ² ν
μ€νΈ λ©μλμ νλμ μΈμ λ§ μ λ¬ν μ μλ€.
short
, byte
, int
, long
, float
, double
, char
, boolean
, java.lang.String
, java.lang.Class
리ν°λ΄ κ°μ μ§μνλ€.
@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
void contains1(int i) {
assertThat(numbers.contains(i)).isTrue();
}
@CsvSource
μ¬λ¬ νλΌλ―Έν°λ₯Ό μ λ¬νκ³ μ ν λ μ¬μ©νλ€.
μ£Όλ‘ μ
λ ₯ κ°κ³Ό κΈ°λ κ°μ ν¨κ» μ λ¬νλ©° ν
μ€νΈν λ μ¬μ©νλ€.
,
λ‘ κ°μ ꡬλΆνμ§λ§ delimiter μμ±μ μ¬μ©ν΄ μ¬μ©μ μ μλ₯Ό ν μ μλ€.
@ParameterizedTest
@CsvSource(value = {"1:true", "5:false"}, delimiter = ':')
void contains3(int i, boolean expected) {
assertThat(expected).isEqualTo(numbers.contains(i));
}
@NullSource
λ¨μΌ null κ°μ μ λ¬ν μ μλ€.
νμ§λ§ κΈ°λ³Έ λ°μ΄ν° νμ μ null κ°μ νμ©ν μ μμ΄ @NullSourceλ₯Ό μ¬μ©ν μ μλ€.
@EmptySource
λ©μλμ νλμ λΉ κ°μ μΈμμ μ λ¬νλ€.
@ParameterizedTest
@EmptySource
void isBlank_ShouldReturnTrueForEmptyStrings(String input) {
assertTrue(Strings.isBlank(input));
}
@NullAndEmptySource
null
κ³Ό empty
κ° λͺ¨λλ₯Ό μ λ¬νκΈ° μν΄ μ¬μ©νλ€.
@ParameterizedTest
@NullAndEmptySource
void isBlank_ShouldReturnTrueForNullAndEmptyStrings(String input) {
assertTrue(Strings.isBlank(input));
}
β null
κ³Ό empty
κ°, λ³νλ λΉ λ¬Έμμ΄μ μ λ¬νκΈ° μν΄ @ValueSource
, @NullSource
, @EmptySource
λ₯Ό ν¨κ» κ²°ν©ν΄ μ¬μ©ν μ μλ€.
@ParameterizedTest
@NullAndEmptySource
@ValueSource(strings = {" ", "\t", "\n"})
void isBlank_ShouldReturnTrueForAllTypesOfBlankStrings(String input) {
assertTrue(Strings.isBlank(input));
}
@EnumSource
μ΄κ±°ν κ°μ λ°°μ΄μ λ©μλμ μ λ¬νλ€.
@ParameterizedTest
@EnumSource(Month.class) // 12 monthsλ₯Ό μ λ¬
void getValueForAMonth_IsAlwaysBetweenOneAndTwelve(Month month) {
int monthNumber = month.getValue();
assertTrue(monthNumber >= 1 && monthNumber <= 12);
}
μ μμμμ names
μμ±μ μ¬μ©νμ¬ λͺ κ°μ λ¬λ§ μ λ¬ν μλ μλ€.
@ParameterizedTest
@EnumSource(value = Month.class, names = {"APRIL", "JUNE", "SEPTEMBER", "NOVEMBER"})
void someMonths_Are30DaysLong(Month month) {
final boolean isALeapYear = false;
assertEquals(30, month.length(isALeapYear));
}
@ValueSource
μ λΉμ·νκ² ν
μ€νΈ μ€ν λΉ νλμ 맀κ°λ³μλ§ μ λ¬ν μ μλ€.
@BeforeEach / @AfterEach
λ©μλκ° νμ¬ ν μ€νΈ ν΄λμ€μ κ°κ°μ λ©μλλ³΄λ€ λ¨Όμ / κ°κ°μ λ©μλμ μ΄νμ μ€ννλ€.
- λ¦¬ν΄ νμ
:
void
private
λΆκ°λ₯static
λΆκ°λ₯@BeforeEach void setUp(){ numbers = new HashSet<>(); numbers.add(1); numbers.add(2); numbers.add(3); numbers.add(4); }
@BeforeAll / @AfterAll
λ©μλκ° νμ¬ ν μ€νΈ ν΄λμ€μ λͺ¨λ λ©μλλ³΄λ€ λ¨Όμ / λͺ¨λ λ©μλμ μ΄νμ μ€ννλ€.
@DisplayName
ν΄λμ€ λλ λ©μλμ λν μ¬μ©μ μ§μ νμ μ΄λ¦μ μ μΈνλλ° μ¬μ©νλ€.
@DisplayName("Setμ μ¬μ΄μ¦ νμΈ ν
μ€νΈ")
@Test
void checkSizeOfSet(){
assertThat(numbers.size()).isEqualTo(4);
}
@Disabled
ν΄λμ€ λλ λ©μλλ₯Ό λΉνμ±ν νλλ° μ¬μ©νλ€.