Junit5学习(一)

Junit5

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

JUnit Jupiter支持配置测试和扩展框架的以下注解。

所有核心注解都位于 模块的org.junit.jupiter.api包中junit-jupiter-api。

注解描述
@Test表示一种方法是一种测试方法。与JUnit 4的@Test注解不同,此注解并未声明任何属性,因为JUnit Jupiter中的测试扩展基于其专用注解进行操作。除非这些方法被覆盖,否则这些方法会被继承。
@ParameterizedTest表示一种方法是参数化测试。除非这些方法被覆盖,否则这些方法会被继承。
@RepeatedTest表示方法是重复测试的测试模板。除非这些方法被覆盖,否则这些方法会被继承。
@TestFactory表示一种方法是动态测试的测试工厂。除非这些方法被覆盖,否则这些方法会被继承。
@TestInstance用于配置注解测试类的测试实例生命周期。这些注解是继承的。
@TestTemplate表示方法是测试用例的模板,设计为根据注册提供程序返回的调用上下文的数量调用多次。除非这些方法被覆盖,否则这些方法会被继承。
@DisplayName声明测试类或测试方法的自定义显示名称。这些注解不会被继承。
@BeforeEach表示该注解的方法应该被执行之前 的每个 @Test,@RepeatedTest,@ParameterizedTest,或@TestFactory方法在当前类; 类似于JUnit 4的@Before。除非这些方法被覆盖,否则这些方法会被继承。
@AfterEach表示该注解的方法应该被执行之后 每个 @Test,@RepeatedTest,@ParameterizedTest,或@TestFactory方法在当前类; 类似于JUnit 4的@After。除非这些方法被覆盖,否则这些方法会被继承。
@BeforeAll表示该注解的方法应该被执行之前 所有 @Test,@RepeatedTest,@ParameterizedTest,和@TestFactory方法在当前类; 类似于JUnit 4的@BeforeClass。这些方法是继承的(除非它们被隐藏或覆盖),并且必须是static(除非使用“每类” 测试实例生命周期)。
@AfterAll表示该注解的方法应该被执行之后 的所有 @Test,@RepeatedTest,@ParameterizedTest,和@TestFactory方法在当前类; 类似于JUnit 4的@AfterClass。这些方法是继承的(除非它们被隐藏或覆盖),并且必须是static(除非使用“每类” 测试实例生命周期)。
@Nested表示注解的类是嵌套的非静态测试类。@BeforeAll和@AfterAll方法不能直接在使用@Nested测试类除非“每级” 测试实例的生命周期被使用。这些注解不会被继承。
@Tag用于在类或方法级别声明过滤测试的标签 ; 类似于TestNG中的测试组或JUnit 4中的类别。这些注解在类级别上继承,但不在方法级别上继承。
@Disabled用于禁用测试类或测试方法; 类似于JUnit 4的@Ignore。这些注解不会被继承。
@ExtendWith用于注册自定义扩展。这些注解是继承的。

带注解的方法@Test,@TestTemplate,@RepeatedTest,@BeforeAll, @AfterAll,@BeforeEach,或@AfterEach注解不能返回一个值。

导包

<junit.version>5.2.0-M1</junit.version>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>

如果需要源注解的话,需要加上

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>

标准测试类

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 {
}
import static org.junit.jupiter.api.Assertions.fail;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

class StandardTests {

    @BeforeAll
    static void initAll() {
    }

    @BeforeEach
    void init() {
    }

    @Test
    void succeedingTest() {
    }

    @Test
    void failingTest() {
        fail("a failing test");
    }

    @Test
    @Disabled("for demonstration purposes")
    void skippedTest() {
        // not executed
    }

    @AfterEach
    void tearDown() {
    }

    @AfterAll
    static void tearDownAll() {
    }

}

测试类和测试方法都不需要public

断言

依旧可以使用断言assertThatisequalToassumeTrueassertAllassertEquals

假设

JUnit Jupiter附带了JUnit 4提供的一些假设方法的子集,并增加了一些适合与Java 8 lambda一起使用的假设方法。所有JUnit Jupiter假设都是org.junit.jupiter.api.Assumptions类中的静态方法。

@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");
    }
禁用测试

@Disabled 可以注解到类上,使整个类禁用测试

条件测试

当在某个条件是才测试

@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 {
}
@Test
@EnabledOnJre(JAVA_8)
void onlyOnJava8() {
    // ...
}

@Test
@EnabledOnJre({ JAVA_9, JAVA_10 })
void onJava9Or10() {
    // ...
}

@Test
@DisabledOnJre(JAVA_9)
void notOnJava9() {
    // ...
}

基于脚本的执行

@Test // Static JavaScript expression.
@EnabledIf("2 * 3 == 6")
void willBeExecuted() {
    // ...
}

@RepeatedTest(10) // Dynamic JavaScript expression.
@DisabledIf("Math.random() < 0.314159")
void mightNotBeExecuted() {
    // ...
}

@Test // Regular expression testing bound system property.
@DisabledIf("/32/.test(systemProperty.get('os.arch'))")
void disabledOn32BitArchitectures() {
    assertFalse(System.getProperty("os.arch").contains("32"));
}

@Test
@EnabledIf("'CI' == systemEnvironment.get('ENV')")
void onlyOnCiServer() {
    assertTrue("CI".equals(System.getenv("ENV")));
}

@Test // Multi-line script, custom engine name and custom reason.
@EnabledIf(value = {
                "load('nashorn:mozilla_compat.js')",
                "importPackage(java.time)",
                "",
                "var today = LocalDate.now()",
                "var tomorrow = today.plusDays(1)",
                "tomorrow.isAfter(today)"
            },
            engine = "nashorn",
            reason = "Self-fulfilling: {result}")
void theDayAfterTomorrow() {
    LocalDate today = LocalDate.now();
    LocalDate tomorrow = today.plusDays(1);
    assertTrue(tomorrow.isAfter(today));
}
函数注入
@DisplayName("TestInfo Demo")
public class DisplayNameDemo {

    DisplayNameDemo(TestInfo testInfo) {
        assertEquals("TestInfo Demo", testInfo.getDisplayName());
    }

    @BeforeEach
    void init(TestInfo testInfo) {
        String displayName = testInfo.getDisplayName();
        assertTrue(displayName.equals("TEST 1") || displayName.equals("test2()"));
    }

    @Test
    @DisplayName("TEST 1")
    @Tag("my-tag")
    void test1(TestInfo testInfo) {
        assertEquals("TEST 1", testInfo.getDisplayName());
        assertTrue(testInfo.getTags().contains("my-tag"));
    }

    @Test
    void test2() {
    }


}

参数注解

下面的@ParameterizedTest方法将被调用三次,用这些值1,2和3分别。

@ParameterizedTest
@ValueSource(ints = { 1, 2, 3 })
void testWithValueSource(int argument) {
    assertTrue(argument > 0 && argument < 4);
}

@EnumSource
@EnumSource提供了一种使用Enum常量的简便方法。该注释提供了一个可选names参数,可让您指定应使用哪些常量。如果省略,所有常量将如下例所示使用。

@ParameterizedTest
@EnumSource(TimeUnit.class)
void testWithEnumSource(TimeUnit timeUnit) {
    assertNotNull(timeUnit);
}
@ParameterizedTest
@EnumSource(value = TimeUnit.class, names = { "DAYS", "HOURS" })
void testWithEnumSourceInclude(TimeUnit timeUnit) {
    assertTrue(EnumSet.of(TimeUnit.DAYS, TimeUnit.HOURS).contains(timeUnit));
}

该@EnumSource注释还提供了可选的mode,使在其上常数传递给测试方法精细控制参数。例如,您可以从枚举常量池中排除名称或指定正则表达式,如以下示例中所示。

@ParameterizedTest
@EnumSource(value = TimeUnit.class, mode = EXCLUDE, names = { "DAYS", "HOURS" })
void testWithEnumSourceExclude(TimeUnit timeUnit) {
    assertFalse(EnumSet.of(TimeUnit.DAYS, TimeUnit.HOURS).contains(timeUnit));
    assertTrue(timeUnit.name().length() > 5);
}
@ParameterizedTest
@EnumSource(value = TimeUnit.class, mode = MATCH_ALL, names = "^(M|N).+SECONDS$")
void testWithEnumSourceRegex(TimeUnit timeUnit) {
    String name = timeUnit.name();
    assertTrue(name.startsWith("M") || name.startsWith("N"));
    assertTrue(name.endsWith("SECONDS"));
}

@MethodSource
@MethodSource允许您引用测试类或外部类的一个或多个工厂方法。这样的工厂方法必须返回一个Stream,Iterable,Iterator,或参数数组。另外,这种工厂方法不能接受任何论点。测试类中的工厂方法必须是static除非测试类注有@TestInstance(Lifecycle.PER_CLASS); 而外部类中的工厂方法必须始终如一static。

如果您只需要一个参数,则可以返回一个Stream参数类型的实例,如以下示例所示。

@ParameterizedTest
@MethodSource("stringProvider")
void testWithSimpleMethodSource(String argument) {
    assertNotNull(argument);
}

static Stream<String> stringProvider() {
    return Stream.of("foo", "bar");
}

如果您没有明确提供工厂方法名称@MethodSource,则JUnit Jupiter将按照惯例搜索与当前方法名称相同的工厂方法 @ParameterizedTest。以下示例演示了这一点。

@ParameterizedTest
@MethodSource
void testWithSimpleMethodSourceHavingNoValue(String argument) {
    assertNotNull(argument);
}

static Stream<String> testWithSimpleMethodSourceHavingNoValue() {
    return Stream.of("foo", "bar");
}

以下示例说明了原始类型(DoubleStream,,IntStream和LongStream)的流也受支持。

@ParameterizedTest
@MethodSource("range")
void testWithRangeMethodSource(int argument) {
    assertNotEquals(9, argument);
}

static IntStream range() {
    return IntStream.range(0, 20).skip(10);
}

如果测试方法声明多个参数,则需要返回Arguments如下所示的集合或实例流。请注意,这Arguments.of(Object…​)是在Arguments界面中定义的静态工厂方法。

@ParameterizedTest
@MethodSource("stringIntAndListProvider")
void testWithMultiArgMethodSource(String str, int num, List<String> list) {
    assertEquals(3, str.length());
    assertTrue(num >=1 && num <=2);
    assertEquals(2, list.size());
}

static Stream<Arguments> stringIntAndListProvider() {
    return Stream.of(
        Arguments.of("foo", 1, Arrays.asList("a", "b")),
        Arguments.of("bar", 2, Arrays.asList("x", "y"))
    );
}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用,你可以在CSDN博客上找到一个非常详细的JDK1.8下载和安装教程,这对于刚开始学习Java的人来说可能会很有用。你可以在这个博客上找到下载JDK1.8的步骤和安装过程的详细说明。请注意,下载速度可能会比较慢,因此你可能需要一些耐心。 根据引用,你还可以看到一个JUnit5的测试套件的代码示例。这个测试套件使用了一些JUnit的注解,如@BeforeClass、@AfterClass、@Before和@After,并且使用了@RunWith注解来指定测试运行器为Suite。 至于NetBeans的安装问题,根据引用,你可能会遇到卡在安装过程中的情况。这个引用提到有人在TB上找到了一个代安装的方法,并且也总结了一些可能导致安装卡住的原因。如果你遇到了类似的问题,可以参考这个引用中提供的解决方法。 希望这些信息对你有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Netbeans安装时卡住](https://blog.csdn.net/m0_63520221/article/details/123508650)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [在NetBeans中开发JUnit测试套件](https://blog.csdn.net/jay314159/article/details/4900861)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值