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 beforeeach@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 aftereach@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 beforeall@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 afterall@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 @AfterAllmethods 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.
importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;@DisplayName("A special test case")classJunitDisplayNameDemo { @Test @DisplayName("Custom test name containing spaces")voidtestWithDisplayNameContainingSpaces() { } @Test @DisplayName("╯°□°)╯")voidtestWithDisplayNameContainingSpecialCharacters() { } @Test @DisplayName("😱")voidtestWithDisplayNameContainingEmoji() { }}
3.3. 断言(Assertions)
importorg.junit.jupiter.api.BeforeAll;importorg.junit.jupiter.api.Test;importstaticjava.time.Duration.ofMillis;importstaticjava.time.Duration.ofMinutes;importstaticorg.junit.jupiter.api.Assertions.*;classAssertionsDemo {privatestaticPerson person; @BeforeAllpublicstaticvoidbeforeAll() { person =newPerson("John","Doe"); } @TestvoidstandardAssertions() {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."); } @TestvoidgroupedAssertions() {// 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())); } @TestvoiddependentAssertions() {// 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"))); }); } @TestvoidexceptionTesting() {Throwable exception =assertThrows(IllegalArgumentException.class, () -> {thrownew IllegalArgumentException("a message"); });assertEquals("a message",exception.getMessage()); } @TestvoidtimeoutNotExceeded() {// The following assertion succeeds.assertTimeout(ofMinutes(2), () -> {// Perform task that takes less than 2 minutes. }); } @TestvoidtimeoutNotExceededWithResult() {// The following assertion succeeds, and returns the supplied object.String actualResult =assertTimeout(ofMinutes(2), () -> {return"a result"; });assertEquals("a result", actualResult); } @TestvoidtimeoutNotExceededWithMethod() {// The following assertion invokes a method reference and returns an object.String actualGreeting =assertTimeout(ofMinutes(2), AssertionsDemo::greeting);assertEquals("Hello, World!", actualGreeting); } @TestvoidtimeoutExceeded() {// The following assertion fails with an error message similar to:// execution exceeded timeout of 10 ms by 91 msassertTimeout(ofMillis(10), () -> {// Simulate task that takes more than 10 ms.Thread.sleep(100); }); } @TestvoidtimeoutExceededWithPreemptiveTermination() {// The following assertion fails with an error message similar to:// execution timed out after 10 msassertTimeoutPreemptively(ofMillis(10), () -> {// Simulate task that takes more than 10 ms.Thread.sleep(100); }); }privatestaticStringgreeting() {return"Hello, World!"; }}
3.4. 假想(Assumptions)
importstaticorg.junit.jupiter.api.Assertions.assertEquals;importstaticorg.junit.jupiter.api.Assumptions.assumeTrue;importstaticorg.junit.jupiter.api.Assumptions.assumingThat;importorg.junit.jupiter.api.Test;classAssumptionsDemo { @TestvoidtestOnlyOnCiServer() {assumeTrue("CI".equals(System.getenv("ENV")));// remainder of test } @TestvoidtestOnlyOnDeveloperWorkstation() {assumeTrue("DEV".equals(System.getenv("ENV")), () ->"Aborting test: not on developer workstation");// remainder of test } @TestvoidtestInAllEnvironments() {assumingThat("CI".equals(System.getenv("ENV")), () -> {// perform these assertions only on the CI server assertEquals(2,2); });// perform these assertions in all environmentsassertEquals("a string","a string"); }}
importstaticorg.junit.jupiter.api.Assertions.assertEquals;importstaticorg.junit.jupiter.api.Assertions.assertFalse;importstaticorg.junit.jupiter.api.Assertions.assertThrows;importstaticorg.junit.jupiter.api.Assertions.assertTrue;importjava.util.EmptyStackException;importjava.util.Stack;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Nested;importorg.junit.jupiter.api.Test;@DisplayName("A stack")classTestingAStackDemo {Stack<Object> stack; @Test @DisplayName("is instantiated with new Stack()")voidisInstantiatedWithNew() {newStack<>(); } @Nested @DisplayName("when new")classWhenNew { @BeforeEachvoidcreateNewStack() { stack =newStack<>(); } @Test @DisplayName("is empty")voidisEmpty() {assertTrue(stack.isEmpty()); } @Test @DisplayName("throws EmptyStackException when popped")voidthrowsExceptionWhenPopped() {assertThrows(EmptyStackException.class, () ->stack.pop()); } @Test @DisplayName("throws EmptyStackException when peeked")voidthrowsExceptionWhenPeeked() {assertThrows(EmptyStackException.class, () ->stack.peek()); } @Nested @DisplayName("after pushing an element")classAfterPushing {String anElement ="an element"; @BeforeEachvoidpushAnElement() {stack.push(anElement); } @Test @DisplayName("it is no longer empty")voidisNotEmpty() {assertFalse(stack.isEmpty()); } @Test @DisplayName("returns the element when popped and is empty")voidreturnElementWhenPopped() {assertEquals(anElement,stack.pop());assertTrue(stack.isEmpty()); } @Test @DisplayName("returns the element when peeked but remains not empty")voidreturnElementWhenPeeked() {assertEquals(anElement,stack.peek());assertFalse(stack.isEmpty()); } } }}
3.8. 重复测试
importstaticorg.junit.jupiter.api.Assertions.assertEquals;importjava.util.logging.Logger;importorg.junit.jupiter.api.BeforeEach;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.RepeatedTest;importorg.junit.jupiter.api.RepetitionInfo;importorg.junit.jupiter.api.TestInfo;classRepeatedTestsDemo {privateLogger logger =// ... @BeforeEachvoidbeforeEach(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)voidrepeatedTest() {// ... } @RepeatedTest(5)voidrepeatedTestWithRepetitionInfo(RepetitionInfo repetitionInfo) {assertEquals(5,repetitionInfo.getTotalRepetitions()); } @RepeatedTest(value =1, name ="{displayName} {currentRepetition}/{totalRepetitions}") @DisplayName("Repeat!")voidcustomDisplayName(TestInfo testInfo) {assertEquals(testInfo.getDisplayName(),"Repeat! 1/1"); } @RepeatedTest(value =1, name =RepeatedTest.LONG_DISPLAY_NAME) @DisplayName("Details...")voidcustomDisplayNameWithLongPattern(TestInfo testInfo) {assertEquals(testInfo.getDisplayName(),"Details... :: repetition 1 of 1"); } @RepeatedTest(value =5, name ="Wiederholung {currentRepetition} von {totalRepetitions}")voidrepeatedTestInGerman() {// ... }}
3.9. 参数化测试
@ParameterizedTest@ValueSource(strings = { "racecar","radar","able was I ere I saw elba" })voidpalindromes(String candidate) {assertTrue(isPalindrome(candidate));}