JUnit5常用注解的使用
注解(Annotations)是JUnit的標(biāo)志性技術(shù),本文就來對它的20個注解,以及元注解和組合注解進行學(xué)習(xí)。
20個注解
在org.junit.jupiter.api包中定義了這些注解,它們分別是:
@Test 測試方法,可以直接運行。
@ParameterizedTest 參數(shù)化測試,比如:
@ParameterizedTest
@ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })
void palindromes(String candidate) {
assertTrue(StringUtils.isPalindrome(candidate));
}
@RepeatedTest 重復(fù)測試,比如:
@RepeatedTest(10)
void repeatedTest() {
// ...
}
@TestFactory 測試工廠,專門生成測試方法,比如:
import org.junit.jupiter.api.DynamicTest;
@TestFactory
Collection<DynamicTest> dynamicTestsFromCollection() {
return Arrays.asList(
dynamicTest("1st dynamic test", () -> assertTrue(isPalindrome("madam"))),
dynamicTest("2nd dynamic test", () -> assertEquals(4, calculator.multiply(2, 2)))
);
}
@TestTemplate 測試模板,比如:
final List<String> fruits = Arrays.asList("apple", "banana", "lemon");
@TestTemplate
@ExtendWith(MyTestTemplateInvocationContextProvider.class)
void testTemplate(String fruit) {
assertTrue(fruits.contains(fruit));
}
public class MyTestTemplateInvocationContextProvider
implements TestTemplateInvocationContextProvider {
@Override
public boolean supportsTestTemplate(ExtensionContext context) {
return true;
}
@Override
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(
ExtensionContext context) {
return Stream.of(invocationContext("apple"), invocationContext("banana"));
}
}
@TestTemplate必須注冊一個TestTemplateInvocationContextProvider,它的用法跟@Test類似。
@TestMethodOrder 指定測試順序,比如:
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(OrderAnnotation.class)
class OrderedTestsDemo {
@Test
@Order(1)
void nullValues() {
// perform assertions against null values
}
@Test
@Order(2)
void emptyValues() {
// perform assertions against empty values
}
@Test
@Order(3)
void validValues() {
// perform assertions against valid values
}
}
@TestInstance 是否生成多個測試實例,默認JUnit每個測試方法生成一個實例,使用這個注解能讓每個類只生成一個實例,比如:
@TestInstance(Lifecycle.PER_CLASS)
class TestMethodDemo {
@Test
void test1() {
}
@Test
void test2() {
}
@Test
void test3() {
}
}
@DisplayName 自定義測試名字,會體現(xiàn)在測試報告中,比如:
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("A special test case")
class DisplayNameDemo {
@Test
@DisplayName("Custom test name containing spaces")
void testWithDisplayNameContainingSpaces() {
}
@Test
@DisplayName("╯°□°)╯")
void testWithDisplayNameContainingSpecialCharacters() {
}
@Test
@DisplayName("😱")
void testWithDisplayNameContainingEmoji() {
}
}
@DisplayNameGeneration 測試名字統(tǒng)一處理,比如:
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.IndicativeSentencesGeneration;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
class DisplayNameGeneratorDemo {
@Nested
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class A_year_is_not_supported {
@Test
void if_it_is_zero() {
}
@DisplayName("A negative value for year is not supported by the leap year computation.")
@ParameterizedTest(name = "For example, year {0} is not supported.")
@ValueSource(ints = { -1, -4 })
void if_it_is_negative(int year) {
}
}
@Nested
@IndicativeSentencesGeneration(separator = " -> ", generator = DisplayNameGenerator.ReplaceUnderscores.class)
class A_year_is_a_leap_year {
@Test
void if_it_is_divisible_by_4_but_not_by_100() {
}
@ParameterizedTest(name = "Year {0} is a leap year.")
@ValueSource(ints = { 2016, 2020, 2048 })
void if_it_is_one_of_the_following_years(int year) {
}
}
}
@BeforeEach 在每個@Test, @RepeatedTest, @ParameterizedTest, or @TestFactory之前執(zhí)行。
@AfterEach 在每個@Test, @RepeatedTest, @ParameterizedTest, or @TestFactory之后執(zhí)行。
@BeforeAll 在所有的@Test, @RepeatedTest, @ParameterizedTest, and @TestFactory之前執(zhí)行。
@AfterAll 在所有的@Test, @RepeatedTest, @ParameterizedTest, and @TestFactory之后執(zhí)行。
@Nested 嵌套測試,一個類套一個類,例子參考上面那個。
@Tag 打標(biāo)簽,相當(dāng)于分組,比如:
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Tag("fast")
@Tag("model")
class TaggingDemo {
@Test
@Tag("taxes")
void testingTaxCalculation() {
}
}
@Disabled 禁用測試,比如:
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@Disabled("Disabled until bug #99 has been fixed")
class DisabledClassDemo {
@Test
void testWillBeSkipped() {
}
}
@Timeout 對于test, test factory, test template, or lifecycle method,如果超時了就認為失敗了,比如:
class TimeoutDemo {
@BeforeEach
@Timeout(5)
void setUp() {
// fails if execution time exceeds 5 seconds
}
@Test
@Timeout(value = 100, unit = TimeUnit.MILLISECONDS)
void failsIfExecutionTimeExceeds100Milliseconds() {
// fails if execution time exceeds 100 milliseconds
}
}
@ExtendWith 注冊擴展,比如:
@ExtendWith(RandomParametersExtension.class)
@Test
void test(@Random int i) {
// ...
}
JUnit5提供了標(biāo)準的擴展機制來允許開發(fā)人員對JUnit5的功能進行增強。JUnit5提供了很多的標(biāo)準擴展接口,第三方可以直接實現(xiàn)這些接口來提供自定義的行為。
@RegisterExtension 通過字段注冊擴展,比如:
class WebServerDemo {
@RegisterExtension
static WebServerExtension server = WebServerExtension.builder()
.enableSecurity(false)
.build();
@Test
void getProductList() {
WebClient webClient = new WebClient();
String serverUrl = server.getServerUrl();
// Use WebClient to connect to web server using serverUrl and verify response
assertEquals(200, webClient.get(serverUrl + "/products").getResponseStatus());
}
}
@TempDir 臨時目錄,比如:
@Test
void writeItemsToFile(@TempDir Path tempDir) throws IOException {
Path file = tempDir.resolve("test.txt");
new ListWriter(file).write("a", "b", "c");
assertEquals(singletonList("a,b,c"), Files.readAllLines(file));
}
元注解和組合注解
JUnit Jupiter支持元注解,能實現(xiàn)自定義注解,比如自定義@Fast注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Tag;
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Tag("fast")
public @interface Fast {
}
使用:
@Fast
@Test
void myFastTest() {
// ...
}
這個@Fast注解也是組合注解,甚至可以更進一步和@Test組合:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Tag("fast")
@Test
public @interface FastTest {
}
只用@FastTest就可以了:
@FastTest
void myFastTest() {
// ...
}
小結(jié)
本文對JUnit20個主要的注解進行了介紹和示例演示,JUnit Jupiter支持元注解,可以自定義注解,也可以把多個注解組合起來。
參考資料:
https://junit.org/junit5/docs/current/user-guide/#writing-tests-annotations
https://vitzhou.gitbooks.io/junit5/content/junit/extension_model.html#概述
到此這篇關(guān)于JUnit5常用注解的使用的文章就介紹到這了,更多相關(guān)JUnit5注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
git stash 和unstash的使用操作,git unstash failed
JSON各種轉(zhuǎn)換問題(json轉(zhuǎn)List,json轉(zhuǎn)對象等)
Netty學(xué)習(xí)教程之Netty與Marshalling結(jié)合發(fā)送對象

