Junit5 ์ •๋ฆฌ

ํ•ด๋‹น ํฌ์ŠคํŒ…์€ ์ธํ”„๋Ÿฐ์˜ ๋ฐฑ๊ธฐ์„ ๋‹˜ ๊ฐ•์˜๋ฅผ ์š”์•ฝํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ Junit Reference๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์šฉ!

JUnit5 ๊ฐœ์š”

Junit5 ์˜์กด์„ฑ ์ถ”๊ฐ€

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.5.2</version>
    <scope>test</scope>
</dependency>

@DisplayName

@DiaplayName("์ฃผ๋ฌธ ์„ฑ๊ณต ํ…Œ์ŠคํŠธ") ์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ junit ์‹คํ–‰ํ›„ ํ•˜๋‹จ์— ํ‘œ์‹œ๋˜๋Š” report ์— ํ•œ๊ธ€๋กœ ํ‘œ์‹œ๋œ๋‹ค. ๋”์ด์ƒ ๋ฉ”์„œ๋“œ ์ด๋ฆ„์„ ํ•œ๊ธ€๋กœ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. (junit5) ๋ถ€ํ„ฐ๋Š”

assertEquals

public static void assertEquals(Object expected, Object actual) {
    AssertEquals.assertEquals(expected, actual);
}

ํฌ๊ฒŒ ์ค‘์š”ํ•œ๊ฑด ์•„๋‹ˆ์ง€๋งŒ, ์ฒซ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” expected ๊ฐ’์„, ๋‘๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์‹ค์ œ ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒŒ Junit API๋ฅผ ์ดํ•ดํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์—๊ฒŒ ์กฐ๊ธˆ ๋” ์™€ ๋‹ฟ์ง€ ์•Š์„๊นŒ?

โœ… assertEquals์˜ ์„ธ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์ด String message ๋„ ์žˆ์ง€๋งŒ, Supplier ๋„ ์กด์žฌํ•œ๋‹ค. ์–ด๋–ค ์ฐจ์ด์ธ๊ฐ€?

ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋Š” ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•˜๋Š” ์ผ€์ด์Šค์— ์„ธ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ’์œผ๋กœ ์ž…๋ ฅํ•œ message๋‚ด์šฉ์ด ์ถœ๋ ฅ๋œ๋‹ค.

๊ทธ๋ƒฅ ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•œ ๊ฒฝ์šฐ์—๋Š” ๋งค๋ฒˆ ํ•ด๋‹น ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.(์‹คํŒจํ•˜๋“ , ์„ฑ๊ณตํ•˜๋“  ์ƒ๊ด€์—†์ด) ํ•˜์ง€๋งŒ Supplier ์œผ๋กœ ๋žŒ๋‹ค์‹์œผ๋กœ ํ•ด์„œ ๋„˜๊ธฐ๊ฒŒ ๋œ๋‹ค๋ฉด, ์‹ค์ œ ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ(lazy evaluation)์„ ํ†ตํ•ด์„œ ์‹คํ–‰๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฌธ์ž์—ด์ด ๋ชจ๋“  ํ…Œ์ŠคํŠธ์— ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด, Supplier๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํšจ์œจ์ ์ด๋‹ค!!

assertAll

๋ณดํ†ต assertEquals()๋กœ ๊ฒ€์ฆํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ๋กœ ๊ฒ€์ฆ์„ ํ•˜๊ณ , ๊ทธ ์ค‘์—์„œ ๋ช‡๊ฐœ๊ฐ€ ์‹คํŒจํ•˜๋”๋ผ๋„ ์ตœ์ดˆ์˜ ์‹คํŒจ๊ฑด ํ•˜๋‚˜๋งŒ ๋ฆฌํฌํŒ…์ด ๋œ๋‹ค. ํ•˜์ง€๋งŒ assertAll์„ ํ†ตํ•ด์„œ ๋žŒ๋‹ค์‹์œผ๋กœ(Executable) ๋ชจ๋“  ๊ฒ€์ฆ ์ฝ”๋“œ๋ฅผ ๋„˜๊ธฐ๊ฒŒ ๋˜๋ฉด, ์ด ๋ช‡๊ฑด์ด ์‹คํŒจ ํ–ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

assertAll(
    () -> assertEquals(StudyStatus.COMPLETE, study.getStudyStatus(), "์ดˆ๊ธฐ ์ƒํƒœ๊ฐ’์€ DRAFT ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค."),
    () -> assertTrue(study.getLimit() > 0, "์Šคํ„ฐ๋”” ์ฐธ์—ฌ ์ œํ•œ์€ 0 ๋ณด๋‹ค ์ปค์•ผ ํ•ฉ๋‹ˆ๋‹ค.")
);

2๊ฑด๋‹ค ์‹คํŒจํ•œ ๊ฒƒ์— ๋Œ€ํ•ด์„œ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ฆฌํฌํŒ…ํ•ด์ค€๋‹ค.

assertThrows

public Study(int limit) {
    if (limit < 0) {
        throw new IllegalArgumentException("limit ์€ 0๋ณด๋‹ค๋Š” ์ปค์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
    }
    this.limit = limit;
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด limit์ด 0๋ณด๋‹ค ์ž‘์€ ๊ฒฝ์šฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

assertThrows(IllegalArgumentException.class, () -> new Study(-10));

์ฒซ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๊ธฐ๋Œ€๋˜๋Š” exception์˜ ํƒ€์ž…, ๋‘๋ฒˆ์งธ๋Š” Executable ๋กœ ์–ด๋–ค ์‹คํ–‰์„ ํ–ˆ์„๋•Œ๋ฅผ ๋„˜๊ธด๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ด๋‹น Exception์„ ๋ฐ›์•„์„œ ๋ฉ”์„ธ์ง€๋„ ๋™์ผํ•œ์ง€ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> new Study(-10));
assertEquals("limit ์€ 0๋ณด๋‹ค๋Š” ์ปค์•ผ ํ•ฉ๋‹ˆ๋‹ค.", e.getMessage());

assertTimeout

assertTimeout(Duration.ofMillis(100), () -> {
    new Study(1);
    Thread.sleep(300);
});

100 millieSeconds๋ฅผ ๊ธฐ๋Œ€ํ–ˆ์ง€๋งŒ, ์‹ค์ œ 300milieSeconds๊ฐ€ ๋‚˜์˜ค๊ธฐ ๋•Œ๋ฌธ์— ์œ„ ์ผ€์ด์Šค๋Š” ์‹คํŒจํ•œ๋‹ค.

์กฐ๊ฑด์— ๋”ฐ๋ฅธ ํ…Œ์ŠคํŠธ

programming ๋ฐฉ๋ฒ•

assumeTrue(System.getenv().get("HOME").equals("/Users/andrew"));
// ์•„๋ž˜ ๋กœ์ง ์‹คํ–‰


assumeTrue ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’ ์กฐ๊ฑด์— ๋งž์œผ๋ฉด ๊ทธ ๋‹ค์Œ ๋กœ์ง์ด ์‹คํ–‰๋œ๋‹ค.

assumingThat(System.getenv().get("HOME").equals("/Users/andrew"), () -> {
    // ์‹คํ–‰ํ•  ๋ถ€๋ถ„
});

assumingThat(System.getenv().get("TEST_ENV").equals("andrew"), () -> {
    // ์‹คํ–‰ํ•  ๋ถ€๋ถ„
});

assumingThat๋ฅผ ํ†ตํ•ด์„œ ์ฝ”๋“œ ๋ธ”๋Ÿญ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

annotaion ๊ธฐ๋ฐ˜

@Test
@EnabledOnJre(JRE.JAVA_8)
@EnabledOnOs(OS.MAC)
@EnabledIfEnvironmentVariable(named = "TEST_ENV", matches = "andrew")
void test(){
    // ..
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์œผ๋กœ๋„, ์›ํ•˜๋Š” ์กฐ๊ฑด๋“ค์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

Tag & Filtering

@Tag ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ํŠน์ • ํ…Œ์ŠคํŠธ๋ฅผ ๊ทธ๋ฃจํ•‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

@Test
@Tag("fast")
void study_test1() {

}

@Test
@Tag("slow")
void study_test2() {

}

Custom Tag (Composed Annotation)

๋ฐ˜๋ณต์ ์œผ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜๊ฐ™์€ ๊ฒฝ์šฐ, composed (ํ•ฉ์„ฑ)์„ ํ†ตํ•ด์„œ ์ปค์Šคํ…€ํ•œ ํƒœ๊ทธ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„์—์„œ ์‚ดํŽด๋ณธ fast, slow ๋กœ ๋‚˜๋ˆ ์ง€๋Š” tag๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ๋‹ค.

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
@Test
@Tag("fast")
public @interface FastTest {
}

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
@Test
@Tag("slow")
public @interface SlowTest {
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

@FastTest
void study_test1() {
}

@SlowTest
void study_test2() {

}

ParameterizedTest (ํ…Œ์ŠคํŠธ ๋ฐ˜๋ณตํ•˜๊ธฐ)

ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ธด๊ฐ’์„ ๊ฐ์ฒด์— ๋งคํ•‘ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ?

@ParameterizedTest
@ValueSource(ints = {10, 20, 30})
void test1(@ConvertWith(StudyConverter.class) Study study) {
    System.out.println(study.getLimit());
}

SimpleArgumentConverter๋ฅผ ๊ตฌํ˜„ํ•œ StudyConverter ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  @ConvertWith ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๋„˜๊ฒจ์ค€๋‹ค.

// single argument
static class StudyConverter extends SimpleArgumentConverter {
    @Override
    protected Object convert(Object source, Class<?> aClass) throws ArgumentConversionException{
        assertEquals(Study.class, aClass, "Can only converter to Study");
        return new Study(Integer.parseInt(source.toString()));
    }
}

๋‹จ์ผ ๊ฐ’์ธ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ–๋Š” ๊ฐ’์ธ ๊ฒฝ์šฐ์—๋Š” ์–ด๋–ป๊ฒŒ ํ• ๊นŒ?

// ์ƒ์„ฑ์ž
public Study(int limit, String name) {
    this.limit = limit;
    this.name = name;
}

@CsvSource๋ฅผ ํ†ตํ•ด์„œ , (์ฝค๋งˆ)๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น ๊ฐ’๋“ค์„ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ArgumentsAggregator ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

@ParameterizedTest
@CsvSource(value = {"10, ์ž๋ฐ”", "20, ์Šคํ”„๋ง"})
void test2(@AggregateWith(StudyAggregator.class) Study study) {
    System.out.println(study);
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด ArgumentsAggregator ๋ฅผ ๊ตฌํ˜„ํ•œ StudyAggregator๋ฅผ @AggregateWith ์œผ๋กœ ๋„˜๊ธด๋‹ค.

// multiple argument - using argument accessor
static class StudyAggregator implements ArgumentsAggregator {
    @Override
    public Object aggregateArguments(ArgumentsAccessor argumentsAccessor, ParameterContext parameterContext) throws ArgumentsAggregationException {
        return new Study(argumentsAccessor.getInteger(0), argumentsAccessor.getString(1));
    }
}

ํ…Œ์ŠคํŠธ ์ˆœ์„œ

๊ธฐ๋ณธ Junit Test๋Š” ๋ฉ”์„œ๋“œ ์‹คํ–‰๋‹น ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ ๋‹ค. Junit5 ์—์„œ๋Š” Class๋‹น ํ…Œ์ŠคํŠธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํด๋ž˜์Šค ๋ ˆ๋ฒจ์— ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

@TestInstance(TestInstance.Lifecycle.PER_CLASS)

ํ…Œ์ŠคํŠธ ์ˆœ์„œ๋Š” Junit์—์„œ ๊ตฌํ˜„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋”ฐ๋ผ์„œ ์ˆœ์„œ๊ฐ€ ์ •ํ•ด์ง„๋‹ค. ์ˆœ์„œ๋ฅผ ๋ช…ํ™•ํžˆ ํ•ด์•ผ ํ• ๋•Œ๋Š” ํด๋ž˜์Šค ๋ ˆ๋ฒจ์— @TestMethodOrder์˜ MethodOrderer๋ฅผ ์–ด๋–ค๊ฑธ๋กœ ํ• ์ง€ ๋„˜๊ฒจ์ค€๋‹ค. ์‹ค์ œ ๋ฉ”์„œ๋“œ ๋ณ„๋กœ @Order ์• ๋…ธํ…Œ์ด์…˜์„ ๋‹ฌ์•„์„œ ์ˆœ์„œ๋ฅผ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)

โ—๏ธ์ฃผ์˜์‚ฌํ•ญ, @Order ์• ๋…ธํ…Œ์ด์…˜์€ ์Šคํ”„๋ง์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ๋„ ์žˆ๋‹ค. ์ด๊ฒƒ์€ ๋นˆ์˜ ์ˆœ์„œ๋ฅผ ์ •์˜ ํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ, ๋ฐ˜๋“œ์‹œ junit์—์„œ ์ œ๊ณตํ•˜๋Š” @Order์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค!

JUnit ํ™•์žฅํ•˜๊ธฐ

์ผ๋ฐ˜ ํ…Œ์ŠคํŠธ์—์„œ ํŠน์ • ์‹œ๊ฐ„(1000 millies) ์„ ๋„˜์œผ๋ฉด @SlowTest ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋„๋ก ๋งŒ๋“ค์–ด๋ผ

๋‹ค์Œ๊ณผ ๊ฐ™์ด BeforeTestExecutionCallback, AfterTestExecutionCallback ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

public class FindSlowTestExecution implements BeforeTestExecutionCallback, AfterTestExecutionCallback {
    @Override
    public void beforeTestExecution(ExtensionContext extensionContext) {
    }

    @Override
    public void afterTestExecution(ExtensionContext extensionContext) {
    }
}

ExtensionContext.Store ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ ํ•ด๋‹น context์—์„œ ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค ๋„ค์ž„, ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ ๋„ค์ž„์ •๋ณด๋ฅผ ๋„˜๊ธด๋‹ค. store์— ์‹œ์ž‘ ์‹œ๊ฐ„ ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•˜๊ณ , afterTestExecution ๋ฉ”์„œ๋“œ์—์„œ ์‹œ๊ฐ„๊ธฐ๋ก ์ฐจ์ด(duration) ์„ ๊ตฌํ•œ๋‹ค. ๊ทธ ์ฐจ์ด๊ฐ’์ด 1000 millies ๋ฅผ ๋„˜๊ฒŒ ๋˜๋ฉด ๋กœ๊ทธ๋ฅผ ์ฐ๋Š”๋‹ค.

private static final long THRESHOLD = 1000L;

@Override
public void beforeTestExecution(ExtensionContext extensionContext) {
    String className = extensionContext.getRequiredTestClass().getName();
    String methodName = extensionContext.getRequiredTestMethod().getName();
    ExtensionContext.Store store = extensionContext.getStore(ExtensionContext.Namespace.create(className, methodName));
    store.put("START_TIME", System.currentTimeMillis());
}

@Override
public void afterTestExecution(ExtensionContext extensionContext) {
    String className = extensionContext.getRequiredTestClass().getName();
    String methodName = extensionContext.getRequiredTestMethod().getName();
    ExtensionContext.Store store = extensionContext.getStore(ExtensionContext.Namespace.create(className, methodName));
    Long startTime = store.remove("START_TIME", long.class);
    long duration = System.currentTimeMillis() - startTime;
    if (duration > THRESHOLD) {
        System.out.printf("Please consider mark method [%s] with @SlowTest\n",
                          extensionContext.getRequiredTestMethod().getName());
    }
}

์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ํด๋ž˜์Šค ๋ ˆ๋ฒจ์— ์„ ์–ธํ•œ๋‹ค.

@ExtendWith(FindSlowTestExecution.class)
class StudyTest {

}

์ง€๊ธˆ๊นŒ์ง€ ์‚ดํŽด๋ณธ ๋ฐฉ๋ฒ•์€ ํ™•์žฅํŒฉ์„ ์„ ์–ธ์ ์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์„ ์–ธ์ ์œผ๋กœ ํ™•์žฅํŒฉ์„ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ด๋ฏธ ๋“ฑ๋กํ•œ ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค. ์ข…์†์ ์ด๋‹ค. ๋‹ค์Œ์—๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ ์ธ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด์„œ THRESHOLD ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด์ž!

public class FindSlowTestExecution implements BeforeTestExecutionCallback, AfterTestExecutionCallback {

    private final long THRESHOLD;
	// ์ƒ์„ฑ์ž ์ฃผ์ž…
    public FindSlowTestExecution(long THRESHOLD) {
        this.THRESHOLD = THRESHOLD;
    }

์‹ค์ œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ @RegisterExtension์œผ๋กœ ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

class StudyTest {

    @RegisterExtension
    static FindSlowTestExecution findSlowTestExecution = new FindSlowTestExecution(1000);

}

Junit4 -> Junit5 ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

springboot ํ”„๋กœ์ ํŠธ 2.x.x ์‹œ์ž‘ํ•˜๊ฒŒ ๋˜๋ฉด ๊ธฐ๋ณธ์œผ๋กœ junit5๊ฐ€ ๋“ค์–ด๊ฐ€๊ณ , junit-vintage-engine์ด exlude ๋œ๋‹ค.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

vinatage ์—”์ง„์€ junit 4์˜ ๊ตฌํ˜„์ฒด์ด๊ณ , jupitor๊ฐ€ junit5 ๊ตฌํ˜„์ฒด์ด๋‹ค. ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ•  ๋•Œ๋Š” exclude ๋œ junit-vintage-engine์„ ์‚ญ์ œ ํ•˜๋ฉด junit4 ๊ธฐ๋ฐ˜์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ• ์ˆ˜๋„ ์žˆ๊ณ , ๊ธฐ์กด์˜ ์ž‘์„ฑ๋œ junit4 ๊ธฐ๋ฐ˜์˜ ํ…Œ์ŠคํŠธ๋„ ๋Œ์•„๊ฐ„๋‹ค. ํ•˜์ง€๋งŒ spring์—์„œ 100% migration์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ฐ€๋ น Rule ๊ด€๋ จ๋œ ๊ฒƒ์€ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— junit-jupiter-migrationsuppor ๋””ํŽœ๋˜์‹œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

์—ฐ๊ด€ ํฌ์ŠคํŠธ