条件测试

JUnit5支持条件注解,根据布尔值判断是否执行测试。

自定义条件

@EnabledIf@DisabledIf注解用来设置自定义条件,示例:

@Test
@EnabledIf("customCondition")
void enabled() {
// ...
} @Test
@DisabledIf("customCondition")
void disabled() {
// ...
} boolean customCondition() {
return true;
}

其中customCondition()方法用来返回布尔值,它可以接受一个ExtensionContext类型的参数。如果定义在测试类外部,那么需要是static方法。

内置条件

JUnit5的org.junit.jupiter.api.condition包中内置了一些条件注解。

操作系统条件

@EnabledOnOsDisabledOnOs,示例:

@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 {
}

JRE条件

@EnabledOnJre@DisabledOnJre用于指定版本,@EnabledForJreRange@DisabledForJreRange用于指定版本范围,示例:

@Test
@EnabledOnJre(JAVA_8)
void onlyOnJava8() {
// ...
} @Test
@EnabledOnJre({ JAVA_9, JAVA_10 })
void onJava9Or10() {
// ...
} @Test
@EnabledForJreRange(min = JAVA_9, max = JAVA_11)
void fromJava9to11() {
// ...
} @Test
@EnabledForJreRange(min = JAVA_9)
void fromJava9toCurrentJavaFeatureNumber() {
// ...
} @Test
@EnabledForJreRange(max = JAVA_11)
void fromJava8To11() {
// ...
} @Test
@DisabledOnJre(JAVA_9)
void notOnJava9() {
// ...
} @Test
@DisabledForJreRange(min = JAVA_9, max = JAVA_11)
void notFromJava9to11() {
// ...
} @Test
@DisabledForJreRange(min = JAVA_9)
void notFromJava9toCurrentJavaFeatureNumber() {
// ...
} @Test
@DisabledForJreRange(max = JAVA_11)
void notFromJava8to11() {
// ...
}

JVM系统属性条件

@EnabledIfSystemProperty@DisabledIfSystemProperty,示例:

@Test
@EnabledIfSystemProperty(named = "os.arch", matches = ".*64.*")
void onlyOn64BitArchitectures() {
// ...
} @Test
@DisabledIfSystemProperty(named = "ci-server", matches = "true")
void notOnCiServer() {
// ...
}

环境变量条件

@EnabledIfEnvironmentVariable@DisabledIfEnvironmentVariable,示例:

@Test
@EnabledIfEnvironmentVariable(named = "ENV", matches = "staging-server")
void onlyOnStagingServer() {
// ...
} @Test
@DisabledIfEnvironmentVariable(named = "ENV", matches = ".*development.*")
void notOnDeveloperWorkstation() {
// ...
}

嵌套测试

嵌套测试可以帮助我们对测试结构进行分层。借助于Java嵌套类的语法,JUnit5可以通过@Nested注解,实现嵌套测试,示例:

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<Object> stack; @Test
@DisplayName("is instantiated with new Stack()")
void isInstantiatedWithNew() {
new Stack<>();
} @Nested
@DisplayName("when new")
class WhenNew { @BeforeEach
void createNewStack() {
stack = new Stack<>();
} @Test
@DisplayName("is empty")
void isEmpty() {
assertTrue(stack.isEmpty());
} @Test
@DisplayName("throws EmptyStackException when popped")
void throwsExceptionWhenPopped() {
assertThrows(EmptyStackException.class, stack::pop);
} @Test
@DisplayName("throws EmptyStackException when peeked")
void throwsExceptionWhenPeeked() {
assertThrows(EmptyStackException.class, stack::peek);
} @Nested
@DisplayName("after pushing an element")
class AfterPushing { String anElement = "an element"; @BeforeEach
void pushAnElement() {
stack.push(anElement);
} @Test
@DisplayName("it is no longer empty")
void isNotEmpty() {
assertFalse(stack.isEmpty());
} @Test
@DisplayName("returns the element when popped and is empty")
void returnElementWhenPopped() {
assertEquals(anElement, stack.pop());
assertTrue(stack.isEmpty());
} @Test
@DisplayName("returns the element when peeked but remains not empty")
void returnElementWhenPeeked() {
assertEquals(anElement, stack.peek());
assertFalse(stack.isEmpty());
}
}
}
}

外部测试类通过@BeforeEach向内部测试类传递变量。

执行后结果:

重复测试

@RepeatedTest注解能控制测试方法的重复执行次数,示例:

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("Repeat! 1/1", testInfo.getDisplayName());
} @RepeatedTest(value = 1, name = RepeatedTest.LONG_DISPLAY_NAME)
@DisplayName("Details...")
void customDisplayNameWithLongPattern(TestInfo testInfo) {
assertEquals("Details... :: repetition 1 of 1", testInfo.getDisplayName());
} @RepeatedTest(value = 5, name = "Wiederholung {currentRepetition} von {totalRepetitions}")
void repeatedTestInGerman() {
// ...
} }

其中name可以用来自定义重复测试的显示名字,{currentRepetition}{totalRepetitions}是当前次数和总共次数的变量。

执行结果:

├─ RepeatedTestsDemo
│ ├─ repeatedTest()
│ │ ├─ repetition 1 of 10
│ │ ├─ repetition 2 of 10
│ │ ├─ repetition 3 of 10
│ │ ├─ repetition 4 of 10
│ │ ├─ repetition 5 of 10
│ │ ├─ repetition 6 of 10
│ │ ├─ repetition 7 of 10
│ │ ├─ repetition 8 of 10
│ │ ├─ repetition 9 of 10
│ │ └─ repetition 10 of 10
│ ├─ repeatedTestWithRepetitionInfo(RepetitionInfo)
│ │ ├─ repetition 1 of 5
│ │ ├─ repetition 2 of 5
│ │ ├─ repetition 3 of 5
│ │ ├─ repetition 4 of 5
│ │ └─ repetition 5 of 5
│ ├─ Repeat!
│ │ └─ Repeat! 1/1
│ ├─ Details...
│ │ └─ Details... :: repetition 1 of 1
│ └─ repeatedTestInGerman()
│ ├─ Wiederholung 1 von 5
│ ├─ Wiederholung 2 von 5
│ ├─ Wiederholung 3 von 5
│ ├─ Wiederholung 4 von 5
│ └─ Wiederholung 5 von 5

小结

本文分别对JUnit5的条件测试、嵌套测试、重复测试进行了介绍,它们可以使得测试更加灵活和富有层次。除了这些,JUnit5还支持另一个重要且常见的测试:参数化测试。

参考资料:

https://junit.org/junit5/docs/current/user-guide/#writing-tests-conditional-execution

https://junit.org/junit5/docs/current/user-guide/#writing-tests-nested

https://junit.org/junit5/docs/current/user-guide/#writing-tests-repeated-tests

JUnit5的条件测试、嵌套测试、重复测试的更多相关文章

  1. 如何避免测试人员提交重复的Bug

    我们在软件测试过程中,由于不同人员测试同一个项目,所以往往会出现Bug重复提交情况,导致对整个项目和人员产生影响: 浪费测试人员时间和精力,从而影响测试进度 浪费开发人员重复看Bug时间 若开发人员由 ...

  2. junit测试延伸--方法的重复测试

    在实际编码测试中,我们有的时候需要对一个方法进行多次测试,那么怎么办呢?这个问题和测试套件解决的方案一样,我们总不能不停的去右键run as,那怎么办呢?还好伟大的junit帮我们想到了. OK,现在 ...

  3. LTP--linux稳定性测试 linux性能测试 ltp压力测试 内核更新 稳定性测试

    LTP--linux稳定性测试 linux性能测试 ltp压力测试 zhangzj1030关注14人评论33721人阅读2011-12-09 12:07:45   说明:在写这篇文章之前,本人也不曾了 ...

  4. 组合测试(Combinatorial Test)/配对测试 (pairwise)

    组合测试方法:配对测试实践 实施组合测试 常用的Pairwise工具集:http://www.pairwise.org/tools.asp 成对测试(Pairwise Testing)又称结对测试.两 ...

  5. Selenium & Webdriver 远程测试和多线程并发测试

    Selenium & Webdriver 远程测试和多线程并发测试 Selenium Webdriver自动化测试,初学者可以使用selenium ide录制脚本,然后生成java程序导入ec ...

  6. 【星云测试】开发者测试(2)-采用精准测试工具对J2EE Guns开发框架进行测试

    配置测试Guns Guns简介 Guns是一个近几年来基于SpringBoot的开源便利且较新的JavaEE项目开发框架,它整合了springmvc + shiro + mybatis-plus + ...

  7. 使用iozone测试磁盘性能(测试文件读写)

    IOzone是一个文件系统测试基准工具.可以测试不同的操作系统中文件系统的读写性能.可以通过 write, re-write, read, re-read, random read, random w ...

  8. web 压力测试工具ab压力测试详解

    Web性能压力测试工具之ApacheBench(ab)详解 原文:http://www.ha97.com/4617.html PS:网站性能压力测试是性能调优过程中必不可少的一环.只有让服务器处在高压 ...

  9. 【测试基础】App测试要点总结

    测试工作过程中思维过程:测试人员常被看作Bug寻找者,程序的破坏者. 1.好的测试工程师所具备的能力: 细心的观察能力 有效的提问能力 产品的业务能力 好奇心 2.测试人员需要询问问题:测试人员的核心 ...

随机推荐

  1. html原生js实现99乘法表

    原生的js实现99乘法表实现选择下拉框颜色,改变背景颜色为选中的颜色 <!DOCTYPE html> <html> <head> <meta charset= ...

  2. 编写程序,计算当n=10000,20000,30000...100000时,π的值.求π的近似公式 π=4*(1-1/3+1/5-1/7+1/9-1/11+1/13-...+1/(2n-1)-1/(2n+1))

    该程序是求的 π 近似值,所以随着 i 的增大,值会无线接近于 3.1415926... 代码示例 : package judgment;/** * 编写程序,计算当n=10000,20000,300 ...

  3. ubuntu下 SVN 服务器搭建及使用

    简化篇 http://blog.csdn.net/Eric_lmy/article/details/51942931 详细篇 1.安装Subversion ServerSubversion serve ...

  4. 实践指南-网页生成PDF

    一.背景 开发工作中,需要实现网页生成 PDF 的功能,生成的 PDF 需上传至服务端,将 PDF 地址作为参数请求外部接口,这个转换过程及转换后的 PDF 不需要在前端展示给用户. 二.技术选型 该 ...

  5. jupyter notebook 默认文件路径修改以及启动

    其实这个方法有时候不是特别有效额 方法一: 查了网上好多其他的方法,但是都没用,只好独辟蹊径了. 首先找到anaconda的安装路径,找到jupyter notebook,我的是如下: 发送快捷方式到 ...

  6. ISP算法高水平分析(上)

    ISP算法高水平分析(上) 一.ISP基本框架及算法介绍 ISP是Image Signal Processor的缩写,全称是影像处理器.在相机成像的整个环节中,它负责接收感光元件(Sensor)的原始 ...

  7. KITTI数据集上MaskRCNN检测效果示例

    KITTI数据集上MaskRCNN检测效果示例 在Semantic Instance Segmentation Evaluation中,MaskRCNN性能效果排名第一. Test Image 0 I ...

  8. AI芯片结构目标图形处理

    AI芯片结构目标图形处理 AI chip architecture targets graph processing 东京--AI处理器设计师Blaize,原名ThinCI(发音为"Thin ...

  9. Java如何使用while和for嵌套循环控制输出数据,使数据奇偶行不同

    /* 题目1 使用Eclipse编写控制台应用程, 使用while循环在控制台打印10行10列的如下图形 □ □ □ □ □ □ □ □ □ □ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ □ □ □ □ ...

  10. Bind DNS服务——转发与区域记录更新

    Linux基础服务--Bind DNS服务 Part4 转发与区域记录更新 一个DNS服务器不可能保存所有的区域记录,所以我们一般都会将其他的区域纪录转发到其他的服务器上进行解析. Bind9提供了全 ...