JUnit : ์๋ฐ ๋จ์ ํ ์คํธ ์์ฑ์ ์ํ ํ ์คํ ํ๋ ์์ํฌ
JUnit ์์ํ๊ธฐ
Java(no Spring) , IntelliJ (2022.2.3 ver), gradle ์ฌ์ฉ
Junit์ spring-boot-starter-test dependency์ ํฌํจ๋์ด์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ์์กด์ฑ์ ์ถ๊ฐํด์ค ํ์๊ฐ ์๋ค. Spring Initializr์ ์๋์ผ๋ก ์ถ๊ฐ๋์ด์ง๋ค.
maven dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ gradle ๋น๋๋ฅผ ๋ง์น๋ฉด ์๋์ผ๋ก test ํด๋๊ฐ ์์ฑ๋๋ค.
ํ ์คํธ ํด๋๋ฅผ ์ฐํด๋ฆญํด์ ์ง์ test class ํ์ผ์ ์์ฑํด๋ ๋๊ณ test ์ํ๋ class๋ฅผ ์ฐํด๋ฆญํด์ test ํ์ผ์ ์์ฑํด๋๋๋ค.
testing library์ JUnit์ ์ ํํ๊ณ ํ๋จ์ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํฌํจ๋์ด์์ง ์๋ค๋ ๋ฌธ๊ตฌ๊ฐ ๋์ค๋ฉด fix๋ฅผ ๋๋ฌ ์ถ๊ฐํด ์ค๋๋ค.
ํ ์คํธ ์ฝ๋ ์์ฑ
ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ ๋จ์ ํ ์คํธ(Unit Test)์ ๋ํด์ ์์๋ณด์.
๋จ์ ํ ์คํธ๋?
ํ๋์ ๋ชจ๋์ ๊ธฐ์ค์ผ๋ก ๋ ๋ฆฝ์ ์ผ๋ก ์งํ๋๋ ๊ฐ์ฅ ์์ ๋จ์์ ํ ์คํธ. ์ฌ๊ธฐ์ ๋ชจ๋์ ์ดํ๋ฆฌ์ผ์ด์ ์์ ์๋ํ๋ ํ๋์ ๊ธฐ๋ฅ ๋๋ ๋ฉ์๋๋ก ์ดํดํ ์ ์๋ค.
๋จ์ ํ ์คํธ ๋ชจ๋ฒ
- 1๊ฐ์ ํ ์คํธ ํจ์๋ 1๊ฐ์ง ๊ฐ๋ ๋ง์ ํ ์คํธ ํ๋ผ.
- ๋ช ํํ๊ณ ์ผ๊ด๋ ๋ค์ด๋ฐ ๊ท์ฝ์ ์ค์ํ๋ผ
- ๋ฐ์คํธ ์์ ์๋์ ๋ชฉ์ ์ด ๋ค์ด๋๊ฒ ์์ฑํ๋ค. (์ด๋ค ์กฐ๊ฑด - ์ด๋ค ์ํ - ์ด๋ค ๊ฒฐ๊ณผ)
- ์ด๋ค ๋ชจ๋์์ ์ฝ๋ ๋ณํ๊ฐ ์๋ ๊ฒฝ์ฐ, ๋ฐ๋์ ๋ชจ๋์ ๋ํด ์์ํ๋ ๋จ์ ํ ์คํธ๊ฐ ์ด๋ค์ค์ผํ๋ค.
- 1๊ฐ์ ํ ์คํธ ํจ์์ ๋ํด assert๋ฅผ ์ต์ํ ํ๋ผ.
์ข์ ๋จ์ ํ ์คํธ์ ์์ฑ (FIRST)
- Fast : ์คํ์ด ๋นจ๋ผ์ผํ๋ค.
- Independent : ํ ์คํธ ํ๊ณ ์ ํ๋ ๋จ์ ๊ธฐ๋ฅ์ ์ง์ค๋์ผํ๋ค. ๋ ๋ฆฝ์ ์ด๋ฉฐ ๋ค๋ฅธ ํ ์คํธ์ ์์กดํ์ง ์๋๋ค.
- Repeatable : ๋ฐ๋ณต์ด ๊ฐ๋ฅํด์ผํ๋ฉฐ, ํญ์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ผํ๋ค.
- Self-Validating : ์์ฒด ๊ฒ์ฆ์ด ๊ฐ๋ฅํด์ผํ๋ค. ํ ์คํธ ์์ฒด์ ์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ์์์์ด์ผํ๋ค.
- Timely : ์ ์์, ์ค์ ๊ตฌํ ์ง์ ์ ๊ตฌํ๋์ด์ผ ํ๋ค.
์ฃผ์ ์ฌํญ
- ๋ด๊ฐ ์ง ์ฝ๋๊ฐ ์๋๊ฒ ์ฒ๋ผ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ผ.
- ‘์ค๋ณต์ด ๋ถ๊ฐ๋ฅํ๊ฒ ์งฐ์ผ๋๊น ์ค๋ณต ์ฒดํฌ๋ ์ํด๋ ๋ ๊บผ์ผ’ ๋ผ๋ ์๊ฐ ๋ฒ๋ฆฌ๊ธฐ. ๊ตฌํ์ ์ธ์ ๊ฐ ์ด๋ป๊ฒ๋ ๋ณํ ์ ์๋ค. ๊ตฌํ์ ๋ํ ํ ์คํธ๊ฐ ์๋ ์ค๊ณ์ ๋ํ ํ ์คํธ๋ฅผ ํด์ผํ๋ค.
- private ๋ฉ์๋ ํ
์คํธ
- private ํ์๋ฅผ ๊ฐ์ง๊ณ ์๋ ๋น์ฆ๋์ค ๋ก์ง(์์ ๋ฉ์๋) ํ ์คํธ๋ง ์ถ๊ฐ๋ ๋ฟ ์ฐ๋ฆฌ๊ฐ ๊ทธ ์์ชฝ(private ๋ฉ์๋)๊น์ง ๋ค์ฌ๋ค๋ณผ ํ์๊ฐ ์๋ค. ์ด๋ ๊ฒ ๊ตฌํํ์๋ ๋ญ๊ฐ ์ด์คํ๊ณ ์ด์ํ๋ค ์ถ์ผ๋ฉด privateํจ์๊ฐ ๊ทธ ์์ ์์ง ์์์ด์ผํ ํ๋ฅ ์ด ํฌ๋ค. ์ฆ ์ฝ๋ ๊ตฌํ์ ์๋ชปํ๋ค๋ ๊ฒ!
- Non-testable
- Random, LocalDate.now(),Shuffle
- ์ธ๋ถ ์ธ๊ณ (HTTP, ์ธ๋ถ ์ ์ฅ์)
์ ํ๋ธ์ ์ฌ๋ผ์จ ์คํ๋ง์บ ํ ์ธ์ ์ ๋ณด๊ณ ์์ฑํ์ต๋๋ค. ํ ์คํธ์ ๊ดํด ์ข์ ์ธ์ฌ์ดํธ๋ฅผ ์ป์ ์ ์๋ ์ ์ตํ ๊ฐ์์ ๋๋ค. ๊ผญ ๋ณด์๊ธธ ์ถ์ฒํฉ๋๋ค! ์ถ์ฒ → https://www.youtube.com/watch?v=YdtknE_yPk4&ab_channel=springcamp.io
๋จ์ ๋ฌธ(assert)
์ ํฉ์ฑ์ ๊ฒ์ฆํ๊ธฐ ์ํ ๋ฉ์๋๋ก ‘~ํ๊ธธ ๊ธฐ๋ํ๋ค’ ์ ๋๋ก ํด์ํ๋ฉด ๋ ๊ฒ๊ฐ๋ค.
assertEquals(a, b) : ๊ฐ์ฒด a์ b๊ฐ ๊ฐ์ ๊ฐ์ธ์ง ํ์ธ
assertSame(a, b) : ๊ฐ์ฒด a์ b๊ฐ ๊ฐ์ ๊ฐ์ฒด์ธ์ง ํ์ธ
assertNull(a) / assertNotNull(a) : a๊ฐ null ์ธ์ง/์๋์ง ํ์ธ
assertTrue(a) / assertFalse(a) : a๊ฐ ์ฐธ์ธ์ง/๊ฑฐ์ง์ธ์ง ํ์ธ
assertArrayEquals(๋ฐฐ์ด1, ๋ฐฐ์ด2) : ๋ฐฐ์ดa์ b๊ฐ ๊ฐ์์ง ํ์ธ
assertThat : ๊ฒ์ฆ ๊ฐ์ด ํน์ ์ํฉ์ ๋ง์กฑํ๋์ง ๊ฒ์ฆ
JUnit 4.4๋ถํฐ asserThat ๋ฉ์๋๊ฐ ์ถ๊ฐ๋๋ค. ์ฌ๋ฌ matcher๋ฅผ ์ง์ํ์ฌ ์ข ๋ ์ ์ฐ์ฑ ์๊ฒ ๋จ์ ๋ฌธ์ ์ฌ์ฉํ ์ ์๋ค.
์ฐธ๊ณ → https://jongmin92.github.io/2020/03/31/Java/use-assertthat/
๊ทธ์ธ ๋ค์ํ ๋จ์ ๋ฌธ ํ์ธ → https://junit.sourceforge.net/javadoc/org/junit/Assert.html
์ด๋ ธํ ์ด์ (@)
@Test : ๋จ์ ํ ์คํธ ๋งค์๋์์ ๋ช ์ (static & private X), timeout/exception์ ๋งค๊ฐ๋ณ์๋ก ์ง์ ๊ฐ๋ฅ
@BeforeClass : ๋ชจ๋ ๋จ์ ํ ์คํธ ์คํ ์ ์ต์ด ํ๋ฒ ์คํ (DB ์ฐ๊ฒฐ ์ ๋๋ผ์ด๋ฒ ๋ก๋ฉ ๋ฑ์ ํ ์คํธ ํฉ๋๋ค.)
@AfterClass : ๋ชจ๋ ๋จ์ ํ ์คํธ ์คํ ํ ๋ง์ง๋ง์ผ๋ก ํ๋ฒ ์คํ
@BeforeEach : ๋จ์ ํ ์คํธ ์คํ ์ ๋ง๋ค ์คํ
@AfterEach : ๋จ์ ํ ์คํธ ์คํ ํ๋ง๋ค ์คํ
@Disabled : ํด๋จ ๋จ์ ํ ์คํธ ์คํํ์ง ์์
@DiaplayName : ์คํ ์ฐฝ์ ํด๋น ๋จ์ ํ ์คํธ์ ๋ฉ์๋ ๋ช ๋์ parameter ๊ฐ์ ์ถ๋ ฅ
์คํ์์ : @BeforeClass → @BeforeEach → @Test → @AfterEach → @AfterClass
๊ณ์ฐ๊ธฐ ํ ์คํธ ์ฝ๋ ์์ฑ
์ ๊ฐ ๋ง๋๋ก ์ง๋ดค์ต๋๋ค..^&^
class postfixCalculationTest {
private static Calculation calculation = new postfixCalculation();
// 1. ์๋ชป๋ ํํ์ input ํ
์คํธ
@DisplayName("์ซ์์ ์ฌ์น์ฐ์ฐ์๋ง ์ ์ธํ ๋ฌธ์ ์
๋ ฅ ํ
์คํธ")
@Test
void CalculatorOtherInput(){
final String input = "4 % 7";
Optional<String> result = calculation.getResult(input);
assertSame(Optional.empty(),result);
}
@DisplayName("์ฐ์ฐ์์ ์ซ์ ์ฌ์ด์ ๊ณต๋ฐฑ์ด ํฌํจ๋์ง์์ ์
๋ ฅ ํ
์คํธ")
@Test
void CalculatorNonSpaceInput(){
final String input = "7+3-1";
Optional<String> result = calculation.getResult(input);
assertSame(Optional.empty(),result);
}
@DisplayName("ํผ์ฐ์ฌ์ ์์ฐ์๊ฐ ์๋ ์
๋ ฅ ํ
์คํธ")
@Test
void CalculatorNonNatualNumInput(){
final String input = "2.2 + 7";
Optional<String> result = calculation.getResult(input);
assertSame(Optional.empty(),result);
}
// 2. ๊ณ์ฐ ๊ฒฐ๊ณผ ํ
์คํธ
@DisplayName("์ฌ๋ฐ๋ฅธ ๊ณ์ฐ - ์ฐ์ฐ์ ์ฐ์ ์์ ๋ฏธํฌํจ")
@Test
void CalculatorBasicOperator(){
final String input = "7 * 20 - 9";
Optional<String> result = calculation.getResult(input);
assertEquals("131",result.get());
}
@DisplayName("์ฌ๋ฐ๋ฅธ ๊ณ์ฐ - ์ฐ์ฐ์ ์ฐ์ ์์ ํฌํจ")
@Test
void CalculatorOrderOfOperator(){
final String input = "82 + 2 * 4";
Optional<String> result = calculation.getResult(input);
assertEquals("90",result.get());
}
}
โ
@ParameterizedTest
์ค๋ณต๋๋ ์ฝ๋ ์ ๊ฑฐ๋ฅผ ์ํ ์ด๋ ธํ ์ด์ .
์ ์ฝ๋์ ๊ฐ์ด ์ค๋ณต ์ฝ๋๊ฐ ๋ง์ ์ฝ๋๋ ์ข์ ๋ฐฉ์์ด ์๋๋ฉฐ ์ค๋ณต ์ฝ๋๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๋ฐฉ์์ด๋ค.
1. gradle dependency ์ถ๊ฐ
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.4.2'
2. ์ฌ์ฉํด๋ณด๊ธฐ
class OperatorTest {
DecimalFormat resultBuffer = new DecimalFormat("#.##");
@ParameterizedTest(name = "{index}: {0}")
@MethodSource("calculateParameters")
@DisplayName("์ฌ์น์ฐ์ฐ ๊ณ์ฐ")
void calculate(String name, double num1, double num2, String operator, String result) {
assertEquals(resultBuffer.format(Operator.of(operator).result(num1,num2)),result);
}
private static Stream<Arguments> calculateParameters() {
return Stream.of(
Arguments.of("๋ํ๊ธฐ",1,2,"+","3"),
Arguments.of("๋นผ๊ธฐ",3,5,"-","-2"),
Arguments.of("๊ณฑํ๊ธฐ",77,3,"*","231"),
Arguments.of("๋๋๊ธฐ",2,7,"/","0.29")
);
}
@ParameterizedTest(name = "{index}: {2}")
@MethodSource("validParameters")
@DisplayName("์ฐ์ฐ์ ์ ํจ์ฑ ๊ฒ์ฌ")
void validOperator(double num1, double num2, String operator, String errMsg){
Exception error = assertThrows(Exception.class,()-> Operator.of(operator));
assertEquals(error.getMessage(),errMsg);
}
private static Stream<Arguments> validParameters(){
return Stream.of(
Arguments.of(1,2,"%","์
๋ ฅ ์ค๋ฅ : ์๋ชป๋ ์ฐ์ฐ์ ํน์ ๋ฌธ์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค."),
Arguments.of(3,5,"dd","์
๋ ฅ ์ค๋ฅ : ์๋ชป๋ ์ฐ์ฐ์ ํน์ ๋ฌธ์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค."),
Arguments.of(77,3,"&","์
๋ ฅ ์ค๋ฅ : ์๋ชป๋ ์ฐ์ฐ์ ํน์ ๋ฌธ์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.")
);
}
}
ํ ์คํธ ์คํ
์์ฑ์ ๋ง์น๋ค ํ ์คํธ class๋ฅผ Run ์ํค๋ฉด ํ ์คํธ๊ฐ ์คํ๋๋ค.
ํต๊ณผ๋ ๋ชฉ๋ก์ ๋ณผ ์ ์์ต๋๋ค.
๋ง์น๋ฉฐ
์ํํธ์จ์ด ํ ์คํธ์ ๊ดํด ์ฐพ์๋ณผ์๋ก ๊น๊ฒ ๊ณต๋ถํด์ผํ ๋ถ์ผ๋ผ๋ ์๊ฐ์ด ๋ ๋ค. ๋ค์ํ ๋ฐฉ๋ฒ๋ก ์ด๋ TDD์ ๊ดํด์๋ ์ง์๊ฐ๋ฅํ ๊ฐ๋ฐ์๊ฐ ๋๊ธฐ ์ํด์ ํ์๋ก ์ตํ ํ์๊ฐ ์์ด๋ณด์ธ๋ค. ๊ทธ๋ฌ๋ ์์ผ๋ก๋ ํ์ดํ
reference.
https://mangkyu.tistory.com/143
https://sakjung.tistory.com/33
https://www.youtube.com/watch?v=YdtknE_yPk4&ab_channel=springcamp.io
https://jongmin92.github.io/2020/03/31/Java/use-assertthat/
์๋ชป๋ ์ ๋ณด๊ฐ ์๋ค๋ฉด ๋๊ธ์ ํตํด ์๋ ค์ฃผ์ธ์. ๊ฐ์ฌํฉ๋๋ค.
'Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java] a.equlas(b)๋ณด๋ค๋ Object.equlas(a,b) ์ฌ์ฉํ๊ธฐ (0) | 2022.12.01 |
---|---|
Java์ ๋๋ค (Lambda) (0) | 2022.10.31 |
๋๊ธ