document.addeventlistener方法不执行_JUnit 5 测试方法的执行优先级

67301366e11ad47ad3d19c0455cac9c0.png

前言

使用单元测试有时对方法的执行顺序有要求,而默认情况下测试方法的执行并非按照编写顺序,这就导致测试用例因执行顺序而导致的不通过。这里我使用的JUnit版本是5.6.2,下面讲述如何自定义测试方法的执行优先级。

@TestMethodOrder

这个注解标注在测试类上,用于指定测试方法要以怎样的方式确定执行顺序:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface TestMethodOrder {Class<? extends MethodOrderer> value();
}

value()接收一个MethodOrderer类型,这个类型是一个接口,里面重要的有一个接口方法orderMethods以及三个静态实现类,分别是:RandomOrderAnnotationAlphanumeric

public interface MethodOrderer {void orderMethods(MethodOrdererContext context);default Optional<ExecutionMode> getDefaultExecutionMode() {return Optional.of(ExecutionMode.SAME_THREAD);}// 随机顺序class Random implements MethodOrderer {// ...}// 根据@Order注解确定执行顺序,注意这个注解在org.junit.jupiter.api包下class OrderAnnotation implements MethodOrderer {// ...}// 按照方法名字母升序顺序,如果方法名相同,则拿方法的参数列表类型名称比较class Alphanumeric implements MethodOrderer {// ...}
}

其中比较重要的是void orderMethods(MethodOrdererContext context);接口方法,如果你不满足于默认提供的三种实现,可以实现此方法,方法参数MethodOrdererContext可以获得测试方法的上下文信息,据此定制方法执行顺序。一般来说上述提供的三种实现已基本满足需求,有需要可参照三种实现。

Random

随机确定方法执行顺序,只需要在测试类上标注如下:

@TestMethodOrder(MethodOrderer.Random.class)
class SampleTests {// methods ...
}

以下是Random的关键源码:

class Random implements MethodOrderer {private static final long DEFAULT_SEED;static {DEFAULT_SEED = System.nanoTime(); // 默认的随机种子是系统时间,单位纳秒}public static final String RANDOM_SEED_PROPERTY_NAME = "junit.jupiter.execution.order.random.seed"; // 在配置文件中指定随机种子,这个值必须是数值型@Overridepublic void orderMethods(MethodOrdererContext context) {// 对方法随机洗牌Collections.shuffle(context.getMethodDescriptors(),new java.util.Random(getCustomSeed(context).orElse(DEFAULT_SEED)));}// 获取配置文件中指定的随机种子private Optional<Long> getCustomSeed(MethodOrdererContext context) {return context.getConfigurationParameter(RANDOM_SEED_PROPERTY_NAME).map(configurationParameter -> {Long seed = null;try {seed = Long.valueOf(configurationParameter);}catch (NumberFormatException ex) {}return seed;});}}

OrderAnnotation

如果需要为特定的方法指定执行顺序,需要在测试类上标注@TestMethodOrder(MethodOrderer.OrderAnnotation.class) ,这个注解不能够单独使用,需要配合方法上的注解org.junit.jupiter.api.Order确定执行顺序,你可以只为希望按顺序执行的方法标注此注解,而不是所有方法:

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class SampleTests {@Test@Order(1) // 优先执行void shouldUploadFileSuccess() throws Exception {}@Test@Order(2) // 延后执行void shouldDeleteFileSuccess() throws Exception {}@Test // 不会因执行顺序而导致失败,可不指定@Ordervoid shouldListAllFiles() throws Exception {}
}

@Order注解中的value越小越优先执行,没有标注@Order的方法使用的是DEFAULT值:

@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Order {int DEFAULT = Integer.MAX_VALUE / 2;int value();
}

下面是OrderAnnotation实现:

class OrderAnnotation implements MethodOrderer {@Overridepublic void orderMethods(MethodOrdererContext context) {// java.util.Comparator.comparingIntcontext.getMethodDescriptors().sort(comparingInt(OrderAnnotation::getOrder));}// 获取方法上@Order注解的value,没有标注@Order注解的方法使用的是@Order注解上的DEFAULT值private static int getOrder(MethodDescriptor descriptor) {return descriptor.findAnnotation(Order.class).map(Order::value).orElse(Order.DEFAULT);}}

方法排序表面使用的是Comparator接口的静态方法comparingInt,实际使用的是java.lang.Integer.compare的比较逻辑:

public static int compare(int x, int y) {return (x < y) ? -1 : ((x == y) ? 0 : 1);}

Alphanumeric

按照方法名的字母升序排序执行,如果方法名相同,则拿方法的参数列表类型名称比较:

@TestMethodOrder(MethodOrderer.Alphanumeric.class)
class AlphaTests {@Test // 后执行void b() {}@Test // 先执行void a() {}
}

下面是这种方式的实现:

class Alphanumeric implements MethodOrderer {@Overridepublic void orderMethods(MethodOrdererContext context) {context.getMethodDescriptors().sort(comparator);}private static final Comparator<MethodDescriptor> comparator = Comparator.<MethodDescriptor, String>// 拿方法名比较 comparing(descriptor -> descriptor.getMethod().getName())// 如果测试方法的名称相同,则进一步比较方法上的参数列表的类型.thenComparing(descriptor -> parameterList(descriptor.getMethod()));// 将方法的参数列表类型处理成形如:java.lang.String,java.lang.Integerdprivate static String parameterList(Method method) {return ClassUtils.nullSafeToString(method.getParameterTypes());}}

上面parameterList方法用到的ClassUtilsJUnit自身的,实际并没什么可看,就是对给定的类型列表名称做逗号拼接处理(使用的是Java 8中的函数式编程,自行了解):

public final class ClassUtils {private ClassUtils() {}public static String nullSafeToString(Class<?> clazz) {return clazz == null ? "null" : clazz.getName();}// method.getParameterTypes()得到的是一个数组,所以使用的的是这个方法public static String nullSafeToString(Class<?>... classes) {// Class:getName => clazz -> clazz.getNamereturn nullSafeToString(Class::getName, classes);}// Function<? super Class<?>, ? extends String> mapper表示传入的是一个Class类型,// 将会产生一个String类型public static String nullSafeToString(Function<? super Class<?>, ? extends String> mapper, Class<?>... classes) {Preconditions.notNull(mapper, "Mapping function must not be null");return classes != null && classes.length != 0 ? (String)Arrays.stream(classes).map((clazz) -> {// mapper.apply(clazz)将调用nullSafeToString(Class::getName, classes)// 中的Class::getName用于获取类型限定名称return clazz == null ? "null" : (String)mapper.apply(clazz);}).collect(Collectors.joining(", ")) : "";}
}

软件版本

软件版本
JUnit5.6.2(junit-jupiter)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2异常处理_Java处理异常2种机制关键字区别解析

在异常处理的过程中,throws和throw的区别是?throws:是在方法上对一个方法进行声明,而不进行处理,而是向上传,谁调用谁处理.throw:是在具体的抛出一个异常类型.throws的栗子:throws的话,就是这个方法有可能会产生异常,而我只是将它声明出去,我自己不处理,如果有人调用的时候,可…

Scrapy——1

python3安装scrapy:http://www.cnblogs.com/Wananbo/p/6093969.html 运行scrapy时&#xff0c;弹出win32错误&#xff0c;然后用pip install pywin32 不行&#xff0c;实际上是缺少了pypiwin32转载于:https://www.cnblogs.com/tangbinghaochi/p/6593543.html

TL431的用法

TL431是可控精密稳压源。它的输出电压用两个电阻就可以设置从Vref&#xff08;2.5V&#xff09;到36V范围内的任何值。该器件的典型动态阻抗为0.2Ω&#xff0c;在很多应用中用它代替稳压二极管&#xff0c;例如&#xff0c;数字电压表&#xff0c;运放电路&#xff0c;可调压电…

个人作业2——英语学习APP的案例分析

产品&#xff1a;必应词典Android客户端 第一部分 调研&#xff0c; 评测 1、第一印象 一款app给人带来的第一印象&#xff0c;一是图标二是界面。微软必应词典的图标好似一本书&#xff0c;好看简洁又与词典相呼应&#xff0c;好评。二来其界面打开也很清爽&#xff0c;每日一…

AD16原理图.schdot中批量修改标签中的文本字体、大小、颜色

1&#xff09;使用鼠标左键区域选中需要修改的文本&#xff0c;或按住shift键使用鼠标左键选择分布在图中各处的需要修改的文本 2&#xff09;按住shift键&#xff0c;鼠标左键双击选中的任一文本&#xff0c;弹出如下的SCH Inspector弹窗 3&#xff09;在SCH Inspector弹窗中…

12v小型电机型号大全_鄂破碎机型号大全图,小型鄂破碎机价格

鄂破碎机&#xff0c;粗碎加工主力配置&#xff0c;因为使用频繁&#xff0c;很多案例都少不了&#xff0c;所以设备生产厂家有很多&#xff0c;但是随时鄂破碎机的机型更新&#xff0c;核心性能越来越完善&#xff0c;整机时产更高&#xff0c;而且环保性能更强悍。鄂破碎机型…

我的第一次Pascal程序

今天刚刚来学点Pascal语言&#xff0c;都怪我买的书大多是用Pascal语言写的&#xff0c;所以我只能试着学一点咯&#xff01; 来一段程序员最经典的Hello World&#xff01; 1 program exl_2; 2 begin 3 write(Hello World!); 4 end. 转载于:https://www.cnblogs.com/ECJTU…

C#中的前台线程和后台线程的区别

前台线程&#xff1a;应用程序必须运行完所有的前台线程才能退出&#xff0c;默认创建的线程都是前台线程。 后台线程&#xff1a;应用程序可以不必考虑后台线程是否已经运行完毕&#xff08;包括正常退出和异常退出&#xff09;&#xff0c;只要所有的前台线程结束&#xff0…

jenkins执行bat失败_关于批处理文件:即使在BAT脚本中成功执行了ROBOCOPY命令,JENKINS作业也会失败...

我正在通过詹金斯执行Windows蝙蝠脚本。 批处理文件正在提供所需的输出&#xff0c;但是构建失败。我的批处理文件是..cd /d D:\\Bank\\Member\\IDif %errorlevel% neq 0 exit /b %errorlevel%mkdir OTPif %errorlevel% neq 0 exit /b %errorlevel%robocopy C:\Corporate D:\\B…

c语言 周期

//问题:如果一个字符串可以由某个长度为k的字符串重复多次得到,则称该串的周期为k.例如,abcabcabc 以3为周期(同时它也以6为周期)//输入一个长度不超过80的字符串,输出其最小的周期#include<stdio.h>#include<string.h>const int maxn100;char s[maxn];int main(){…

C#中的参数数组

参数数组允许特定类型的零个或多个实参对应一个特定的形参。 参数数组的重点如下&#xff1a; 在一个参数列表中只能有一个参数数组如果有&#xff0c;它必须是列表中的最后一个由参数数组表示的所有参数必须是同一类型 声明一个参数数组需要注意&#xff1a; 在数据类型前使…

上传本地项目到gitee_用git上传本地文件到码云gitee的方法

首先登录码云 https://gitee.com/&#xff0c;注册一个账号&#xff0c;并登录账号。1. 在码云上创建项目在码云首页顶部&#xff0c;下图所示&#xff0c;右上角头像旁边的加号&#xff0c;鼠标移上去会显示下拉的&#xff0c;点击“新建项目”。填写好项目的名称、路径等&…

51nod 1307 绳子与重物 二分+dfs / 并查集

题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId1307 题意: 题解: 方法一&#xff1a; 因为所有绳子最终组成了1棵树&#xff0c;所以我们可以通过一次DFS&#xff0c;来检测是否有某根绳子下面绑了超过他所能负荷的重量。 具体方法&#xff1a;对…

C#中string.Concat方法的使用

string.Concat方法用于连接string的一个或多个实例&#xff0c;或string的一个或多个实例的object表示形式 https://docs.microsoft.com/zh-cn/dotnet/api/system.string.concat?viewnet-5.0 1&#xff09;连接string[]或object[]数组中的元素 using System; using System.C…

将java项目做成app_将鸿蒙做成和EMUI一致,又兼容安卓APP,华为已立于不败之地...

自从华为的系统曝光以来&#xff0c;每天都有众多的网友为其摇旗呐喊&#xff0c;说不管怎么时候推出&#xff0c;甚至就算不好用&#xff0c;都无条件支持&#xff0c;说如果连自己人都不支持&#xff0c;就不可能成功了。但近日&#xff0c;随着网上曝光华为鸿蒙系统的的相关…

[APIO2016]

2016的题貌似是韩国棒子出的&#xff0c;好丧啊.... 看了题解还想了好久...... ------------------------------------------------- A.Boat 有n个数&#xff0c;每个数字可取[li,ri]内的任意整数si&#xff0c;但是要求对于任意i<j,都有si<sj&#xff0c;求方案数 n<…

C# 使用StackFrame和StackTrace类 获取当前函数名,当前代码行,源代码文件

https://docs.microsoft.com/zh-cn/dotnet/api/system.diagnostics.stackframe?viewnetframework-3.0 https://docs.microsoft.com/zh-cn/dotnet/api/system.diagnostics.stacktrace?viewnetframework-3.0 测试代码如下&#xff1a; using System; using System.Collections…

华为鸿蒙系统智能手机_余承东再度确认:鸿蒙系统将适配到华为手机上

近期余承东承认华为芯片不够用&#xff0c;麒麟芯片也将在9月15日暂时停产&#xff0c;华为麒麟芯片或将成为绝唱已经确定为事实&#xff0c;这显然是有点遗憾的事情&#xff0c;不过华为也有好消息传来&#xff0c;那就是余承东再度确认鸿蒙系统将适配到手机上&#xff0c;具体…

2017-03-16 Codeforces 453A 概率期望,思维 UOJ 228(待补)

Codeforces 453A A. Little Pony and Expected Maximum 题意&#xff1a;一个m面质地均匀的骰子&#xff0c;每面出现的概率都是独立的1/m, 你需要投掷n次&#xff0c;其结果是这n次出现的最大点数。问投掷n次骰子的结果的期望值是多少&#xff0c;要求相对误差或绝对误差不…

C#多线程时对同一资源加锁实现互斥访问

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; //using System.Diagnostics;namespace 多线程 {#region 我的程序class ResultCount{public static int PassNumber { get; s…