JUnit 5クイックガイド
17748 ワード
JUnit 5クイックガイド
version: junit5 1. を取り付ける.JUnit注記 3.作成ユニットテスト 3.1.基本的なユニットテストクラスと方法 3.2.カスタムテストクラスとメソッドの表示名 3.3.アサーション 3.4.仮想(Assumptions) 3.5.無効 3.6.試験条件 3.7.ネストテスト 3.8.繰り返しテスト 3.9.パラメトリックテスト 4.引用と引用 1.インストール
pomに依存を追加
コンポーネント間の依存関係:
2.JUnit注記
Annotation
Description
Denotes that a method is a test method. Unlike JUnit 4’s
Denotes that a method is a parameterized test. Such methods are inherited unless they are overridden.
Denotes that a method is a test template for a repeated test. Such methods are inherited unless they are overridden.
Denotes that a method is a test factory for dynamic tests. Such methods are inherited unless they are overridden.
Used to configure the test instance lifecycle for the annotated test class. Such annotations are inherited.
Denotes that a method is a template for test cases designed to be invoked multiple times depending on the number of invocation contexts returned by the registered providers. Such methods are inherited unless they are overridden.
Declares a custom display name for the test class or test method. Such annotations are not inherited.
Denotes that the annotated method should be executed before each
Denotes that the annotated method should be executed after each
Denotes that the annotated method should be executed before all
Denotes that the annotated method should be executed after all
Denotes that the annotated class is a nested, non-static test class.
Used to declare tags for filtering tests, either at the class or method level; analogous to test groups in TestNG or Categories in JUnit 4. Such annotations are inherited at the class level but not at the method level.
Used to disable a test class or test method; analogous to JUnit 4’s
Used to register custom extensions. Such annotations are inherited.
3.作成ユニットテスト
3.1.基本的なユニットテストクラスと方法
3.2.テストクラスとメソッドの表示名をカスタマイズする
普通文字、特殊記号、emojiをサポート
3.3.アサーション(Assertions)
3.4.仮想(Assumptions)
3.5.無効
ユニットテストクラスを無効にする例:
ユニットテストを無効にする方法の例:
3.6.試験条件
オペレーティングシステムの条件
Javaランタイムバージョン条件
システム属性条件
3.7.ネストテスト
3.8.繰り返しテスト
3.9.パラメトリックテスト
4.引用と引用 Github 公式ユーザーズマニュアル Javadoc バージョン宣言 公式例
version: junit5
pomに依存を追加
5.3.2
org.junit.jupiter
junit-jupiter-api
${junit.jupiter.version}
test
org.junit.jupiter
junit-jupiter-params
${junit.jupiter.version}
test
org.junit.jupiter
junit-jupiter-engine
${junit.jupiter.version}
test
コンポーネント間の依存関係:
2.JUnit注記
Annotation
Description
@Test
Denotes that a method is a test method. Unlike JUnit 4’s
@Test
annotation, this annotation does not declare any attributes, since test extensions in JUnit Jupiter operate based on their own dedicated annotations. Such methods are inherited unless they are overridden. @ParameterizedTest
Denotes that a method is a parameterized test. Such methods are inherited unless they are overridden.
@RepeatedTest
Denotes that a method is a test template for a repeated test. Such methods are inherited unless they are overridden.
@TestFactory
Denotes that a method is a test factory for dynamic tests. Such methods are inherited unless they are overridden.
@TestInstance
Used to configure the test instance lifecycle for the annotated test class. Such annotations are inherited.
@TestTemplate
Denotes that a method is a template for test cases designed to be invoked multiple times depending on the number of invocation contexts returned by the registered providers. Such methods are inherited unless they are overridden.
@DisplayName
Declares a custom display name for the test class or test method. Such annotations are not inherited.
@BeforeEach
Denotes that the annotated method should be executed before each
@Test
, @RepeatedTest
, @ParameterizedTest
, or @TestFactory
method in the current class; analogous to JUnit 4’s @Before
. Such methods are inherited unless they are overridden. @AfterEach
Denotes that the annotated method should be executed after each
@Test
, @RepeatedTest
, @ParameterizedTest
, or @TestFactory
method in the current class; analogous to JUnit 4’s @After
. Such methods are inherited unless they are overridden. @BeforeAll
Denotes that the annotated method should be executed before all
@Test
, @RepeatedTest
, @ParameterizedTest
, and @TestFactory
methods in the current class; analogous to JUnit 4’s @BeforeClass
. Such methods are inherited (unless they are hidden or overridden) and must be static
(unless the "per-class"test instance lifecycle is used). @AfterAll
Denotes that the annotated method should be executed after all
@Test
, @RepeatedTest
, @ParameterizedTest
, and @TestFactory
methods in the current class; analogous to JUnit 4’s @AfterClass
. Such methods are inherited (unless they are hidden or overridden) and must be static
(unless the "per-class"test instance lifecycle is used). @Nested
Denotes that the annotated class is a nested, non-static test class.
@BeforeAll
and @AfterAll
methods cannot be used directly in a @Nested
test class unless the "per-class"test instance lifecycle is used. Such annotations are not inherited. @Tag
Used to declare tags for filtering tests, either at the class or method level; analogous to test groups in TestNG or Categories in JUnit 4. Such annotations are inherited at the class level but not at the method level.
@Disabled
Used to disable a test class or test method; analogous to JUnit 4’s
@Ignore
. Such annotations are not inherited. @ExtendWith
Used to register custom extensions. Such annotations are inherited.
3.作成ユニットテスト
3.1.基本的なユニットテストクラスと方法
import org.junit.jupiter.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class Junit5StandardTests {
private static final Logger LOGGER = LoggerFactory.getLogger(Junit5StandardTests.class);
@BeforeAll
static void beforeAll() {
LOGGER.info("call beforeAll()");
}
@BeforeEach
void beforeEach() {
LOGGER.info("call beforeEach()");
}
@Test
void succeedingTest() {
LOGGER.info("call succeedingTest()");
}
@Test
void failingTest() {
LOGGER.info("call failingTest()");
// fail("a failing test");
}
@Test
@Disabled("for demonstration purposes")
void skippedTest() {
LOGGER.info("call skippedTest()");
// not executed
}
@AfterEach
void afterEach() {
LOGGER.info("call afterEach()");
}
@AfterAll
static void afterAll() {
LOGGER.info("call afterAll()");
}
}
3.2.テストクラスとメソッドの表示名をカスタマイズする
普通文字、特殊記号、emojiをサポート
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("A special test case")
class JunitDisplayNameDemo {
@Test
@DisplayName("Custom test name containing spaces")
void testWithDisplayNameContainingSpaces() { }
@Test
@DisplayName("╯°□°)╯")
void testWithDisplayNameContainingSpecialCharacters() { }
@Test
@DisplayName("?")
void testWithDisplayNameContainingEmoji() { }
}
3.3.アサーション(Assertions)
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static java.time.Duration.ofMillis;
import static java.time.Duration.ofMinutes;
import static org.junit.jupiter.api.Assertions.*;
class AssertionsDemo {
private static Person person;
@BeforeAll
public static void beforeAll() {
person = new Person("John", "Doe");
}
@Test
void standardAssertions() {
assertEquals(2, 2);
assertEquals(4, 4, "The optional assertion message is now the last parameter.");
assertTrue('a' < 'b', () -> "Assertion messages can be lazily evaluated -- "
+ "to avoid constructing complex messages unnecessarily.");
}
@Test
void groupedAssertions() {
// In a grouped assertion all assertions are executed, and any
// failures will be reported together.
assertAll("person", () -> assertEquals("John", person.getFirstName()),
() -> assertEquals("Doe", person.getLastName()));
}
@Test
void dependentAssertions() {
// Within a code block, if an assertion fails the
// subsequent code in the same block will be skipped.
assertAll("properties", () -> {
String firstName = person.getFirstName();
assertNotNull(firstName);
// Executed only if the previous assertion is valid.
assertAll("first name", () -> assertTrue(firstName.startsWith("J")),
() -> assertTrue(firstName.endsWith("n")));
}, () -> {
// Grouped assertion, so processed independently
// of results of first name assertions.
String lastName = person.getLastName();
assertNotNull(lastName);
// Executed only if the previous assertion is valid.
assertAll("last name", () -> assertTrue(lastName.startsWith("D")),
() -> assertTrue(lastName.endsWith("e")));
});
}
@Test
void exceptionTesting() {
Throwable exception = assertThrows(IllegalArgumentException.class, () -> {
throw new IllegalArgumentException("a message");
});
assertEquals("a message", exception.getMessage());
}
@Test
void timeoutNotExceeded() {
// The following assertion succeeds.
assertTimeout(ofMinutes(2), () -> {
// Perform task that takes less than 2 minutes.
});
}
@Test
void timeoutNotExceededWithResult() {
// The following assertion succeeds, and returns the supplied object.
String actualResult = assertTimeout(ofMinutes(2), () -> {
return "a result";
});
assertEquals("a result", actualResult);
}
@Test
void timeoutNotExceededWithMethod() {
// The following assertion invokes a method reference and returns an object.
String actualGreeting = assertTimeout(ofMinutes(2), AssertionsDemo::greeting);
assertEquals("Hello, World!", actualGreeting);
}
@Test
void timeoutExceeded() {
// The following assertion fails with an error message similar to:
// execution exceeded timeout of 10 ms by 91 ms
assertTimeout(ofMillis(10), () -> {
// Simulate task that takes more than 10 ms.
Thread.sleep(100);
});
}
@Test
void timeoutExceededWithPreemptiveTermination() {
// The following assertion fails with an error message similar to:
// execution timed out after 10 ms
assertTimeoutPreemptively(ofMillis(10), () -> {
// Simulate task that takes more than 10 ms.
Thread.sleep(100);
});
}
private static String greeting() {
return "Hello, World!";
}
}
3.4.仮想(Assumptions)
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.junit.jupiter.api.Assumptions.assumingThat;
import org.junit.jupiter.api.Test;
class AssumptionsDemo {
@Test
void testOnlyOnCiServer() {
assumeTrue("CI".equals(System.getenv("ENV")));
// remainder of test
}
@Test
void testOnlyOnDeveloperWorkstation() {
assumeTrue("DEV".equals(System.getenv("ENV")),
() -> "Aborting test: not on developer workstation");
// remainder of test
}
@Test
void testInAllEnvironments() {
assumingThat("CI".equals(System.getenv("ENV")),
() -> {
// perform these assertions only on the CI server
assertEquals(2, 2);
});
// perform these assertions in all environments
assertEquals("a string", "a string");
}
}
3.5.無効
ユニットテストクラスを無効にする例:
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@Disabled
class DisabledClassDemo {
@Test
void testWillBeSkipped() {
}
}
ユニットテストを無効にする方法の例:
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
class DisabledTestsDemo {
@Disabled
@Test
void testWillBeSkipped() {
}
@Test
void testWillBeExecuted() {
}
}
3.6.試験条件
オペレーティングシステムの条件
@Test
@EnabledOnOs(MAC)
void onlyOnMacOs() {
// ...
}
@TestOnMac
void testOnMac() {
// ...
}
@Test
@EnabledOnOs({ LINUX, MAC })
void onLinuxOrMac() {
// ...
}
@Test
@DisabledOnOs(WINDOWS)
void notOnWindows() {
// ...
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Test
@EnabledOnOs(MAC)
@interface TestOnMac {
}
Javaランタイムバージョン条件
@Test
@EnabledOnJre(JAVA_8)
void onlyOnJava8() {
// ...
}
@Test
@EnabledOnJre({ JAVA_9, JAVA_10 })
void onJava9Or10() {
// ...
}
@Test
@DisabledOnJre(JAVA_9)
void notOnJava9() {
// ...
}
システム属性条件
@Test
@EnabledIfSystemProperty(named = "os.arch", matches = ".*64.*")
void onlyOn64BitArchitectures() {
// ...
}
@Test
@DisabledIfSystemProperty(named = "ci-server", matches = "true")
void notOnCiServer() {
// ...
}
3.7.ネストテスト
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.EmptyStackException;
import java.util.Stack;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@DisplayName("A stack")
class TestingAStackDemo {
Stack
3.8.繰り返しテスト
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.logging.Logger;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.RepetitionInfo;
import org.junit.jupiter.api.TestInfo;
class RepeatedTestsDemo {
private Logger logger = // ...
@BeforeEach
void beforeEach(TestInfo testInfo, RepetitionInfo repetitionInfo) {
int currentRepetition = repetitionInfo.getCurrentRepetition();
int totalRepetitions = repetitionInfo.getTotalRepetitions();
String methodName = testInfo.getTestMethod().get().getName();
logger.info(String.format("About to execute repetition %d of %d for %s", //
currentRepetition, totalRepetitions, methodName));
}
@RepeatedTest(10)
void repeatedTest() {
// ...
}
@RepeatedTest(5)
void repeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {
assertEquals(5, repetitionInfo.getTotalRepetitions());
}
@RepeatedTest(value = 1, name = "{displayName} {currentRepetition}/{totalRepetitions}")
@DisplayName("Repeat!")
void customDisplayName(TestInfo testInfo) {
assertEquals(testInfo.getDisplayName(), "Repeat! 1/1");
}
@RepeatedTest(value = 1, name = RepeatedTest.LONG_DISPLAY_NAME)
@DisplayName("Details...")
void customDisplayNameWithLongPattern(TestInfo testInfo) {
assertEquals(testInfo.getDisplayName(), "Details... :: repetition 1 of 1");
}
@RepeatedTest(value = 5, name = "Wiederholung {currentRepetition} von {totalRepetitions}")
void repeatedTestInGerman() {
// ...
}
}
3.9.パラメトリックテスト
@ParameterizedTest
@ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })
void palindromes(String candidate) {
assertTrue(isPalindrome(candidate));
}
4.引用と引用