Junit5

Junit은 Java의 λ‹¨μœ„ ν…ŒμŠ€νŒ… 도ꡬ이닀.

  • λ‹¨μœ„ ν…ŒμŠ€νŠΈ Framework쀑 ν•˜λ‚˜

  • λ‹¨μ •λ¬ΈμœΌλ‘œ Test Case μˆ˜ν–‰κ²°κ³Όλ₯Ό νŒλ³„

  • Annotation으둜 κ°„κ²°ν•˜κ²Œ μ‚¬μš© κ°€λŠ₯

JUnit5

Junit5λŠ” 이전 버전과 λ‹€λ₯΄κ²Œ 3개의 μ„œλΈŒ ν”„λ‘œμ νŠΈ λͺ¨λ“ˆλ‘œ μ΄λ£¨μ–΄μ Έμžˆλ‹€.

  • JUnit Platform : TestEngine API, Console Launcher, JUnit 4 based Runner λ“± 포함

  • JUnit Jupiter : TestEngine API κ΅¬ν˜„μ²΄λ‘œ JUnit 5 κ΅¬ν˜„

  • JUnit Vintage : TestEngine API κ΅¬ν˜„μ²΄λ‘œ JUnit 3, 4 κ΅¬ν˜„

    • Junit5μ—μ„œ JUnit Vintage λͺ¨λ“ˆμ„ ν¬ν•¨ν•˜κ³  μžˆμ–΄ JUnit 3,4도 μ‚¬μš©ν•  수 μžˆμ§€λ§Œ, μ™„λ²½ν•˜κ²Œ μ§€μ›ν•΄μ£ΌλŠ” 것은 μ•„λ‹ˆλ‹€.

Dependencies

spring boot 2.2.0 이후 λ²„μ „μ—μ„œλŠ” Junit5κ°€ 기본으둜 λ³€κ²½λ˜μ—ˆλ‹€. Junit5λŠ” Java8 λΆ€ν„° μ§€μ›ν•˜λ©°, 이전 λ²„μ „μœΌλ‘œ μž‘μ„±λœ ν…ŒμŠ€νŠΈ μ½”λ“œμ—¬λ„ 컴파일이 μ§€μ›λœλ‹€.

SpringBoot 2.2.0 이전 λ²„μ „μ—μ„œ junit5 μ„€μ •

maven

<!-- spring boot test junit5 μ‚¬μš© exclusion을 톡해 junit4μ—μ„œ μ½”λ“œ μ‹€ν–‰μ‹œ μ‚¬μš©ν•˜λŠ” vintage-engine μ˜ˆμ™Έμ²˜λ¦¬-->
<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>

<!-- ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„±μ— ν•„μš”ν•œ junit-jupiter-api λͺ¨λ“ˆκ³Ό ν…ŒμŠ€νŠΈ 싀행을 μœ„ν•œ junit-jupiter-engine λͺ¨λ“ˆ 포함 -->
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-api</artifactId>
</dependency>

gradle

testImplementation ('org.springframework.boot:spring-boot-starter-test') {
	exclude module: 'junit'
}
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testRuntimeOnly'org.junit.jupiter:junit-jupiter-engine'

ν…ŒμŠ€νŠΈλ₯Ό κ΅¬μ„±ν•˜κ³ , ν”„λ ˆμž„μ›Œν¬λ₯Ό μƒμ†ν•˜κΈ° μœ„ν•œ μ–΄λ…Έν…Œμ΄μ…˜μ„ μ§€μ›ν•œλ‹€. λŒ€λΆ€λΆ„ μ–΄λ…Έν…Œμ΄μ…˜μ€ junit-jupiter-apiλͺ¨λ“ˆμ˜ org.junit.jupiter.api νŒ¨ν‚€μ§€μ•ˆμ— μ‘΄μž¬ν•œλ‹€.

μš©μ–΄

ν…ŒμŠ€νŠΈ 클래슀

μ΅œμƒμœ„ 클래슀, μŠ€νƒœν‹± 멀버 클래슀, @Nested ν΄λž˜μŠ€μ— 적어도 ν•œκ°œμ˜ @Test μ–΄λ…Έν…Œμ΄μ…˜μ΄ 달린 ν…ŒμŠ€νŠΈ λ©”μ†Œλ“œκ°€ ν¬ν•¨λ˜μ–΄μžˆλŠ” 클래슀λ₯Ό λ§ν•œλ‹€. ν…ŒμŠ€νŠΈ ν΄λž˜μŠ€λŠ” abstract이면 μ•ˆλ˜κ³ , ν•˜λ‚˜μ˜ μƒμ„±μžκ°€ μ‘΄μž¬ν•΄μ•Όν•œλ‹€.

ν…ŒμŠ€νŠΈ λ©”μ†Œλ“œ

μ•„λž˜ 메타 μ–΄λ…Έν…Œμ΄μ…˜μ΄ 뢙여진 λ©”μ†Œλ“œλ₯Ό λ§ν•˜λ©°, ν…ŒμŠ€νŠΈ λ©”μ†Œλ“œλŠ” ν…ŒμŠ€νŠΈ ν•  클래슀, μƒμ†ν•œ λΆ€λͺ¨ 클래슀, μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλœλ‹€. abstractλ₯Ό μ„ μ–Έν•΄μ„œλŠ” μ•ˆλ˜λ©°, μ–΄λ– ν•œ 값도 λ°˜ν™˜λ˜λ©΄ μ•ˆλœλ‹€.

  • @Test

  • @RepetedTest

  • @ParameterizedTest

  • @TestFactory

  • @TestTemplate

λΌμ΄ν”Œ 사이클 λ©”μ†Œλ“œ

μ•„λž˜ 메타 μ–΄λ…Έν…Œμ΄μ…˜μ΄ 뢙여진 λ©”μ†Œλ“œλ₯Ό λ§ν•˜λ©°, ν…ŒμŠ€νŠΈ λ©”μ†Œλ“œλŠ” ν…ŒμŠ€νŠΈ ν•  클래슀, μƒμ†ν•œ λΆ€λͺ¨ 클래슀, μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλœλ‹€. abstractλ₯Ό μ„ μ–Έν•΄μ„œλŠ” μ•ˆλ˜λ©°, μ–΄λ– ν•œ 값도 λ°˜ν™˜λ˜λ©΄ μ•ˆλœλ‹€.

  • @BeforeAll

  • @AfterAll

  • @BeforeEach

  • @AfterEach

Dependency Injection

Junit Jupiter의 주된 λ³€ν™”λ‘œ ν…ŒμŠ€νŠΈ 클래슀의 생성와 λ©”μ„œλ“œκ°€ νŒŒλΌλ―Έν„°λ₯Ό κ°€μ§ˆ 수 있게 λ˜μ—ˆλ‹€. μ΄λŠ” μ½”λ“œμ˜ μœ μ—°ν•¨μ΄ 증가할 뿐만 μ•„λ‹ˆλΌ, μ˜μ‘΄μ„± μ£Όμž… λ˜ν•œ κ°€λŠ₯ν•˜κ²Œ λ˜μ—ˆλ‹€.

ParameterResolverλŠ” μ‹€ν–‰ μ‹œκ°„ λ™μ•ˆμ— λ™μ μœΌλ‘œ νŒŒλΌλ―Έν„°λ₯Ό 해석할 수 μžˆλŠ” APIλ₯Ό μ •μ˜ν•˜κ³  μžˆλ‹€. ν˜„μž¬ μžλ™μœΌλ‘œ λ“±λ‘λ˜λŠ” 3개의 Resolverκ°€ μžˆλ‹€.

ParmeterResolver
μ„€λͺ…

TestInfoParameterResolver

TestInfo Resolver이닀. TestInfo κ°μ²΄λŠ” ν…ŒμŠ€νŠΈ 클래슀, λ©”μ„œλ“œλͺ…, λ””μŠ€ν”Œλ ˆμ΄λͺ…κ³Ό 같은 ν˜„μž¬ ν…ŒμŠ€νŠΈμ— λŒ€ν•œ 정보λ₯Ό 가지고 μžˆλ‹€.

RepetitionInfoParameterResolver

반볡 μ‹€ν–‰ κ°€λŠ₯ν•œ λ©”μ„œλ“œ(@RepeatedTest ,@BeforeEach ,@AfterEach)와 같은 λ©”μ„œλ“œ 정보λ₯Ό κ°€μ§€λŠ” RepetionInfo 객체에 λŒ€ν•œ Resolver이닀.

TestReporterParameterResolver

ν˜„μž¬ μ‹€ν–‰ν•˜λŠ” ν…ŒμŠ€νŠΈμ— λŒ€ν•œ μΆ”κ°€ 정보λ₯Ό ν‘œμ‹œν•  수 μžˆλŠ” TestReporter 객체에 λŒ€ν•œ Resolver이닀.

TestInfo

λ©”μ†Œλ“œλͺ…

νƒ€μž…

μ„€λͺ…

getDisplayName()

String

@DisplayName κ°’μ΄λž‘ 동일

getTags()

Set<String>

@Tag λ°°μ—΄ κ°’

getTestClass()

Optional<Class<?>>

νŒ¨ν‚€μ§€ + ν…ŒμŠ€νŠΈ 클래슀λͺ…

getTestMethod()

Optional<Method>

νŒ¨ν‚€μ§€λͺ… + ν…ŒμŠ€νŠΈ 클래슀λͺ… + ν…ŒμŠ€νŠΈ λ©”μ†Œλ“œ

RepetitionInfo

λ©”μ†Œλ“œλͺ… / λ³€μˆ˜λͺ…

νƒ€μž…

μ„€λͺ…

getCurrentRepetition()

int

ν˜„μž¬ 반볡 횟수

getTotalRepetitions()

int

총 반볡 횟수

DISPLAY_NAME_PLACEHOLDER

String

@DisplayName κ°’

SHORT_DISPLAY_NAME

String

λ°˜λ³΅ν•  λ•Œ λ‚˜νƒ€λ‚˜λŠ” ν…ŒμŠ€νŠΈλͺ… κΈ°λ³Έκ°’ : "repetition " + ν˜„μž¬ 반볡 횟수 + " of " + 총 반볡 횟수

LONG_DISPLAY_NAME

String

DISPLAY_NAME_PLACEHOLDER + " :: " + SHORT_DISPLAY_NAME

TOTAL_REPETITIONS_PLACEHOLDER

String

ν˜„μž¬ 반볡 횟수

CURRENT_REPETITION_PLACEHOLDER

String

총 반볡 횟수

TestInfoParameterResolver

@DisplayName("TestInfo ν…ŒμŠ€νŠΈ")
public class TestInfoTest {

    TestInfoTest(TestInfo testInfo) {
        assertThat("TestInfo ν…ŒμŠ€νŠΈ").isEqualTo(testInfo.getDisplayName());
    }

    @BeforeEach
    void setUp(TestInfo testInfo) {
        String displayName = testInfo.getDisplayName();
        assertThat("demo test").isEqualTo(testInfo.getDisplayName());
    }

    @Test
    @Tag("demo1")
    @DisplayName("demo test")
    void test(TestInfo testInfo) {
        assertThat(testInfo.getTags().contains("demo1")).isTrue();
    }
}

Last updated

Was this helpful?