junit runner_了解JUnit的Runner架构

junit runner

几周前,我开始创建一个小的JUnit Runner( Oleaster ),它允许您使用Jasmine方式在JUnit中编写单元测试。 我了解到,创建自定义JUnit Runners实际上非常简单。 在这篇文章中,我想向您展示JUnit Runners在内部如何工作以及如何使用自定义Runners修改JUnit的测试执行过程。



那么什么是JUnit Runner?

JUnit Runner是扩展JUnit抽象Runner类的类。 运行程序用于运行测试类。 可以使用@RunWith注释设置应该用于运行测试的Runner 。

@RunWith(MyTestRunner.class)
public class MyTestClass {@Testpublic void myTest() {..}
}

JUnit测试是使用JUnitCore类开始的。 可以通过从命令行运行它,也可以使用它的各种run()方法之一来完成此操作(如果您按run test按钮,这就是您的IDE所做的事情)。

JUnitCore.runClasses(MyTestClass.class);

然后,JUnitCore使用反射为通过的测试类找到合适的Runner。 此处的一个步骤是在测试类上查找@RunWith批注。 如果未找到其他运行程序,则将使用默认运行程序( BlockJUnit4ClassRunner )。 将实例化Runner,并将测试类传递给Runner。 现在,实例化并运行通过的测试类是Runner的工作。

跑步者如何工作?

让我们看一下标准JUnit Runners的类层次结构:

跑步者

Runner是一个非常简单的类,实现了Describable接口,并具有两个抽象方法:

public abstract class Runner implements Describable {public abstract Description getDescription();public abstract void run(RunNotifier notifier);
}

方法getDescription()从Describable继承,并且必须返回Description 。 描述包含了各种工具以后导出和使用的信息。 例如,您的IDE可能会使用此信息来显示测试结果。 run()是一种非常通用的方法, 可以运行某些内容 (例如测试类或测试套件)。 我认为通常Runner并不是您要扩展的类(它太慷慨了)。

在ParentRunner中,事情变得更加具体。 ParentRunner是具有多个子代的Runner的抽象基类。 在这里重要的是要理解,测试是按层次结构构造和执行的(就像树一样)。

例如:您可能运行包含其他测试套件的测试套件。 这些测试套件可能包含多个测试类。 最后,每个测试类可以包含多个测试方法。

ParentRunner具有以下三种抽象方法:

public abstract class ParentRunner<T> extends Runner implements Filterable, Sortable {    protected abstract List<T> getChildren();protected abstract Description describeChild(T child);protected abstract void runChild(T child, RunNotifier notifier);
}

子类需要在getChildren()中返回泛型T的列表。 然后,ParentRunner要求子类为每个孩子(describeChild())创建一个Description,最后运行每个孩子(runChild())。

现在,让我们看一下两个标准的ParentRunners:BlockJUnit4ClassRunner和Suite。

如果没有提供其他Runner,则使用BlockJUnit4ClassRunner为默认Runner。 因此,这是运行单个测试类时通常使用的Runner。 如果您查看BlockJUnit4ClassRunner的来源,您将看到类似以下内容:

public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> {@Overrideprotected List<FrameworkMethod> getChildren() {// scan test class for methonds annotated with @Test}@Overrideprotected Description describeChild(FrameworkMethod method) {// create Description based on method name}@Overrideprotected void runChild(final FrameworkMethod method, RunNotifier notifier) {if (/* method not annotated with @Ignore */) {// run methods annotated with @Before// run test method// run methods annotated with @After}}
}

当然,这被过度简化了,但是它显示了BlockJUnit4ClassRunner的基本功能。 通用类型参数FrameworkMethod基本上是java.lang.reflect.Method的包装,提供了一些方便的方法。 在getChildren()中,扫描测试类以查找使用@Test进行反射的方法。 找到的方法包装在FrameworkMethod对象中并返回。 describeChildren()从方法名称创建一个Description,然后runChild()最终运行测试方法。 BlockJUnit4ClassRunner在内部使用了很多受保护的方法。 根据您要确切执行的操作,最好检查BlockJUnit4ClassRunner是否可以覆盖方法。 您可以在GitHub上查看BlockJUnit4ClassRunner的源代码。

Suite Runner用于创建测试套件。 套件是测试(或其他套件)的集合。 一个简单的套件定义如下所示:

@RunWith(Suite.class)
@Suite.SuiteClasses({MyJUnitTestClass1.class,MyJUnitTestClass2.class,MyOtherTestSuite.class
})
public class MyTestSuite {}

通过选择带有@RunWith批注的Suite Runner来创建测试套件。 如果查看Suite的实现,您会发现它实际上非常简单。 Suite唯一要做的就是从使用@SuiteClasses批注定义的类中创建Runner实例。 因此,getChildren()返回Runner列表,runChild()将执行委托给相应的Runner。

例子

利用提供的信息,创建您自己的JUnit Runner并不难(至少我希望如此)。 如果您正在寻找一些示例自定义Runner实现,则可以查看以下列表:

  • Fabio Strozzi创建了一个非常简单明了的GuiceJUnitRunner项目 。 它为您提供了在JUnit测试中注入Guice组件的选项。 来源GitHub
  • Spring的SpringJUnit4ClassRunner可帮助您测试Spring框架应用程序。 它允许您在测试类中使用依赖项注入或创建事务性测试方法。 来源GitHub
  • Mockito为自动模拟初始化提供了MockitoJUnitRunner 。 来源GitHub
  • Oleaster的 Java 8茉莉花赛跑者。 源自GitHub (无耻的自我推广)

结论

JUnit Runners具有高度可定制性,可让您选择更改以完成测试执行过程。 很酷的事情是,可以更改整个测试过程,并且仍然使用IDE,构建服务器等的所有JUnit集成点。

如果您只想进行较小的更改,那么最好查看一下BlockJUnit4Class运行程序的受保护方法。 您很有可能在正确的位置找到可重写的方法。

翻译自: https://www.javacodegeeks.com/2014/08/understanding-junits-runner-architecture.html

junit runner

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

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

相关文章

php 邮件服务器 群发,发送使用PHP群发电子邮件发送使用PHP群发电子邮件(Sending mass email usin...

我目前正在写一个音乐博客。 管理员发布一个新的文章每2-3天。 一旦管理员岗位的文章&#xff0c;群发电子邮件将被立即发送到5000左右的用户。什么是实现群发邮件功能的最佳方法是什么&#xff1f;请问下面的函数工作&#xff1f;function massmail(){$content ...;foreach (…

linq判断集合中相同元素个数_iOS开发swift语法梳理:集合Set

1.集合的三特性确定性&#xff1a;给定一个集合&#xff0c;任意给一个元素&#xff0c;该元素或者属于或者不属于该集合&#xff0c;二者必居其一。互斥性&#xff1a;一个集合中的所有元素都是不相同的。无序性&#xff1a;每个元素的地位相同&#xff0c;元素之间是无序的。…

Java 14:有用的NullPointerException消息

Java 14中引入了新的JVM选项-XX:ShowCodeDetailsInExceptionMessages &#xff0c;以提供有用的NullPointerException消息 &#xff0c;以准确显示在发生NullPointerException时为空。 例如&#xff0c;考虑以下代码&#xff1a; var name library.get( "My Book" )…

世界机器人冠军王宇航_★​身边的榜样,为你喝彩:我校学子摘冠第七届河南省VEX U机器人挑战赛...

近日&#xff0c;第七届河南省大学生机器人竞赛在河南开放大学顺利闭幕。我校2018级机自专业学生王宇航、李泽坤和应用物理学专业学生闫朝硕荣获“VEX U机器人挑战赛冠军”、“VEX U机器人挑战赛一等奖”&#xff0c;中原工学院荣获“优秀组织奖”。一份耕耘、一份收获&#xf…

python监控服务器信息,Python监控服务器实现邮件微信报警

本文中笔者暂时实现的只有cpu和内存的监控&#xff0c;python可以监控许多的主机信息&#xff0c;网络&#xff0c;硬盘&#xff0c;机器状态等&#xff0c;以下是代码的实现&#xff0c;代码可以实现windows和 linux 的监控。实验环境&#xff1a;Ubuntu16.04和windos10&#…

对象空指针_可选和对象:空指针救星!

对象空指针没有人喜欢空指针异常 &#xff01; 我们有办法摆脱它们吗&#xff1f; 也许 。 。 。 这篇文章中讨论了几种技术&#xff1a; 可选类型&#xff08;Java 8中的新增功能&#xff09; 对象类&#xff08;旧的Java 7东西&#xff01;&#xff09; Java 8中的可选类…

循环发ajax请求,在循环中发送jquery ajax请求

我在我的Web应用程序的Map中实现了“空间选择”&#xff0c;它选择Streets的数量。选择后&#xff0c;我会为使用“选择处理程序”选择的所有街道获取唯一的街道标识。在循环中发送jquery ajax请求我的下一步是发送Ajax请求到每个街道Id的服务器并获取回应。目前&#xff0c;我…

延迟关机_苹果电脑到底需不需要关机?关机和休眠你选择哪个

刚买了MacBook的朋友&#xff0c;会不会跟小编一样&#xff0c;是格外的珍惜&#xff0c;总想以一种最好的方式使用自己人生中第一个苹果电脑。苹果笔记本需要关机吗&#xff1f;不关机会卡吗&#xff1f;也成了自己关心的话题&#xff01;Mac 到底要不要关机&#xff0c;这个问…

关于高效企业测试的思考(1/6)

企业中的测试仍然不是应有的广泛使用的话题。 编写尤其是维护测试需要花费时间和精力&#xff0c;但是缩短软件测试并不是解决方案。 为了提高测试效率&#xff0c;应该追求哪些范围&#xff0c;方法和测试技术&#xff1f; 我根据许多实际项目&#xff0c;结合了我在企业测试…

电脑开机后显示服务器没有声音,我的电脑音频服务启动不了,没有声音,小扬声器那里是一个红色的小叉叉...

(我系统是W7普通家庭版32位)一、电脑没了声音&#xff0c;小喇叭上有个红叉&#xff0c;鼠标放上去显“音频服务未运行”&#xff0c;进入控制面板&#xff0c;声音里显没有设备。1&#xff0c;确保硬件好的前提下&#xff0c;还是得先检查下你的驱动有没有问题。2&#xff0c;…

10鼎信诺为什么安装不了_鼎信诺审计软件一周常见问题(4.134.17)

今天介绍一下近期咨询较多的两款财务软件在取数后不能显示辅助核算明细的问题&#xff0c;分别是诺诺云和亿企代账&#xff0c;这两款软件都是采用云记账方式&#xff0c;均可以通过其平台中的导出审计数据的功能导出一个备份文件夹&#xff0c;备份文件夹中都是TXT格式的文本文…

Angular 8 + Spring Boot 2.2:立即构建一个CRUD应用程序!

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕&#xff1f; 尝试使用Okta API进行托管身份验证&#xff0c;授权和多因素身份验证。 如果您已经成为Java开发人员超过15年&#xff0c;那么您可能还记得什么时候有过多的J…

http服务器网站打不开,网站打不开_ostonkin8743的博客__杭州19楼

HTTP 错误 403 - 限制为仅本地主机访问 Internet 服务管理器 (HTML)HTTP 错误 403 403.1 禁止&#xff1a;禁止执行访问如果从并不允许执行程序的目录中执行 CGI、ISAPI 或其他执行程序就可能引起此错误。如果问题依然存在&#xff0c;请与 Web 服务器的管理员联系。HTTP 错误 …

函数传参字典_Python 函数中的 4 种参数类型

作者&#xff1a;小小程序员链接&#xff1a;https://zhuanlan.zhihu.com/p/89538123来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。在调用函数时&#xff0c;通常会传递参数&#xff0c;函数内部的代码保持不变&#x…

gc频繁的暂停启动_减少主要GC暂停的频率

gc频繁的暂停启动这篇文章将讨论一种减少垃圾收集暂停的技术&#xff0c;它会延迟应用程序的延迟。 正如我几年前所写&#xff0c; 在JVM中无法禁用垃圾收集 。 但是&#xff0c;有一个巧妙的技巧可以用来大大减少长时间停顿的时间和频率。 如您所知&#xff0c;JVM内部发生了…

部署war文件到服务器,war包怎么部署到云服务器

war包怎么部署到云服务器 内容精选换一换部署提供可视化、一键式部署服务&#xff0c;支持并行部署和流水线无缝集成&#xff0c;实现部署环境标准化和部署过程自动化。本节通过以下四步介绍如何使用部署服务将归档在软件发布库的软件包部署到云主机上。第一步&#xff1a;准备…

惠普bios硬重置_惠普笔记本电脑按什么样键进入BIOS设置?惠普笔记本BIOS密码忘了咋重置...

F① F② DEL都不行。r是不是的啊&#xff1f;量情拆好&#xff1a;如果您确认无法进入BIOS://stg.www⑧.hp&#xff0c;这个情况很可能是硬件有故障造成的&#xff0c;建议您可以通过以下网址查询距离最近的惠普金牌服务中心.com/cn/zh/support-drivers/esupport/ascpps&…

Java 8中的StringJoiner与String.join的示例

将多个String文字或对象合并为一个是常见的编程要求&#xff0c;并且经常会发现需要为应用程序将String列表或String集合转换为CSV String的情况。 长期以来&#xff0c;JDK API无法将多个String文字或对象连接在一起&#xff0c;这迫使程序员编写诸如遍历所有String对象并使用…

小米4系统定位服务器地址,小米4原装浏览器怎么开启定位系统

手机系统最好是开发版&#xff0c;稳定版必须先root&#xff0c;可以自己root(另找教程)&#xff0c;也可以刷成开发版。我的手机系统是MIUI4.10.31(开发版)&#xff0c;可以在“系统更新”查看&#xff0c;具有root功能。小米4如何开启虚拟键盘方法安装RE管理器和Root Explore…

中如何将方形图片转换成圆形图片_【PS】PS中不可不知的实用技巧!你都掌握了吗?...

今天给大家分享一些在PS中经常用到的实用小技巧&#xff0c;操作简单易上手。01 拉伸图片人物不变形在我们在PS里想要拉伸一些图片时&#xff0c;里面的人物往往会跟着一起变形&#xff0c;那么如何改变图片比例的同时&#xff0c;又不影响人物的形态呢&#xff1f;打开我们需要…