JUnit与TestNG:您应该选择哪种测试框架?

JUnit与TestNG:测试框架对决

在平衡良好的开发人员团队中,测试是软件发布周期中不可分割的一部分。 并非总是那样。 单元测试,集成测试,系统测试等并不总是存在的。 如今,我们很幸运能及时到达一个测试很重要且其价值已为大多数利益相关者所知的地方。

在本文中,我们将测试放在中心,并通过JUnit和TestNG的眼光探索Java测试,同时比较它们的主要功能和用例。

非常感谢OverOps的测试自动化工程师Sasson Shmuel在撰写本文时所提供的帮助。

所以……给定一个干净的状态,您会选择什么?

1.符合框架

毫无疑问,JUnit和TestNG是那里最受欢迎的测试框架。 实际上,当我们查看GitHub上Java顶级项目使用的库时,它们都进入了前20名 。

JUnit在62%的项目中排名第一,而TestNG在6%的项目中排名第20。 Maven存储库显示了类似的结果,其中JUnit的流行度排名在第1位(使用42,484次)和TestNG在第15位(使用3,873次使用)。 这也是因为默认情况下,许多Maven原型中都添加了JUnit。

版本和一些近期历史

最新的JUnit版本是2014年12月发布的4.12, JUnit 5有望在2016年底达到GA状态。这很快就会实现,我们也希望它成为会议中的热门话题。

JUnit一直是采用测试驱动开发的驱动程序之一,最初由Kent Beck和Erich Gamma开发 。 在2013年,火炬传递给了JUnit团队 :

早期的JUnit 5版本已经可供您使用,您也可以在GitHub上为它的开发做出贡献。 一个有趣的事实是,通过众筹活动使新版本的开发成为可能。


至于由Cedric Beust创建的TestNG,撰写本文时的最新版本是2015年12月的6.9.10。它首次出现在JUnit 3出现的那一刻,并提供了当时不存在的新功能。专注于更广泛的测试用例的设计时代。 其中一些功能(例如使用批注)已添加到JUnit 4中,这是我们在此处重点关注的版本,并展望了即将发布的JUnit 5版本。

2.编写测试

TestNG和JUnit都基于类似于Java断言的行为,该行为在Java 4中又添加了。而且我们可以直接使用断言,所以……为什么要为测试框架而烦恼?

从简单的Java断言开始就很容易受到诱惑,但是随着项目的发展,测试很快变得不平凡,使用框架来管理它非常有意义。 而且,学习曲线很快,主要概念简单而强大。 JUnits代码库非常轻巧,因此引用了Martin Fowler:

“在软件开发领域,从来没有太多人需要这么少的代码行”

JUnit和TestNG都遵循xUnit约定,但是有很多区别,我们在这里要强调。 组,并行性,参数化测试和依赖项:

团体

TestNG为JUnit中提供的注释提供了附加注释。 可能最值得注意的是在一组测试用例之前/之后运行代码的能力。 同样,单个测试可以属于多个组,然后在不同的上下文中运行(例如慢速或快速测试)。 实际上,这是测试用例和测试套件之间的另一层:

@Test(groups = { "sanity", "insanity" })

JUnit类别中存在类似的功能,但缺少@BeforeGroups / @AfterGroups TestNG批注,该批注允许初始化测试/将其拆解。 顺便说一句,JUnit 5似乎将弃用Categories并引入一个称为Tag的新概念:

@Tag("sanity")
@Tag("insanity")
void testSomething() {...
}

但就目前看来,看不到@BeforeTag / @AfterTag注释。

并行性

如果您想在多个线程上并行运行相同的测试,TestNG会为您提供一个易于使用的注释,而JUnit并没有提供开箱即用的简单方法。 TestNG实现看起来像:

@Test(threadPoolSize = 3, invocationCount = 9)
public void testSomething() {...
}

意思是,同一测试有3个线程和9个调用。 如果在TestNG的XML运行配置中指定整个套件,则也可以并行运行整个套件。 使用JUnit时,您必须编写一个自定义的运行器方法,并多次提供相同的测试参数。 这将我们带到下一个要点。

参数化/数据驱动测试

这是将不同的测试输入馈送到同一测试用例的问题,TestNG和JUnit都解决了这些问题,但是使用了不同的方法。 基本思想是相同的,创建一个包含参数的2D数组Object [] []。

但是,除了通过代码提供参数之外,TestNG @DataProvider还可以支持XML,用于输入数据,CSV甚至纯文本文件。

JUnit中存在的一项功能,而TestNG缺少的一项功能是能够在多个参数之间使用不同的组合。 这提供了长参数列表的快捷方式,并在JUnit Theories中进行了解释。

组/方法之间的依赖关系

由于JUnit是为单元测试而构建的,并且TestNG考虑到了更广泛的测试,因此它们在测试之间的依赖方式上也有所不同。

TestNG允许您声明测试之间的依赖关系,如果未通过依赖项测试,则跳过它们:

@Test(dependsOnMethods = { "dependOnSomething" })
public void testSomething() {...
}

JUnit中不存在此功能,可以使用假设来模拟BUT。 失败的假设会导致忽略被忽略的测试。

底线:不同的开发人员对其选择的框架会有不同的期望。 与JUnit相比,TestNG似乎提供了更大的灵活性。

3.运行测试

在编写测试时,我们不需要包括main方法,因为框架使用自己的main方法为我们运行这些测试,这些方法管理各个测试的执行。

如果确实需要自定义运行器,则JUnit提供@RunWith批注,使您可以使用自己的运行器。 使用TestNG也可以绕过默认运行器,但不像使用JUnit那样简单。 但是,值得注意的是,TestNG支持XML运行配置,这些配置在许多用例中都非常有用。

至于实际运行的测试,这两个框架都具有CLI支持,通过ANT运行,以及可供您选择的IDE使用的插件,它们具有非常相似的功能。 尽管JUnit随JDT(Eclipse Java开发工具)一起提供,但是确实如此。

testngeclipseplugin-768x504

TestNG Eclipse插件上的测试套件结果

底线: JUnit的@RunWith注释稍微灵活一些。

4.报告结果

测试结果引起了很多人的兴趣。 运行它们的不仅仅是开发人员。 这是报告开始发挥作用的时候,两个框架都对此问题给出了答案。

默认情况下,TestNG报告会生成到一个test-output文件夹,其中包含带有所有测试数据,通过/失败/跳过,运行了多长时间,使用了哪些输入以及完整的测试日志的html报告。 此外,它还将所有内容导出到XML文件,该文件可用于构建您自己的报告模板。

在JUnit方面,所有这些数据也可以通过XML获得,但是没有开箱即用的报告,您需要依赖插件。

testngemailablereport-768x418

TestNG Eclipse插件上的测试套件结果

底线: TestNG提供了开箱即用的报告,JUnit仅将其导出到XML

5.自动化测试运行

这两个框架均可用于通过Jenkins,Travis CI和Teamcity之类的工具创建自动化测试运行。 还可以使用插件从测试数据中创建报告,并将其发送给您选择的渠道可能感兴趣的任何人。 例如,将TestNG与Jenkins结合使用,并将其与email和Slack集成。

我们以前也曾写过一些对开发人员最有用的Slack集成, 请查看 。

底线:自动化取胜。 JUnit和TestNG都可能具有您要查找的集成。

6.终止失败的测试

糟糕,测试失败。 接下来发生什么? 如果足够精细,则查找故障原因应该相对容易一些,但是现实中对我们通常有不同的计划。

尽管它主要用于生产环境,但我们的很大一部分用户还设置了OverOps来监视其测试环境。 每当测试失败时,他们就可以通过导致失败的所有方法查看导致失败的变量。

overopsgif2
底线:要使您的环境更上一层楼 ,请查看OverOps并查看其如何帮助您解决错误。

7.模拟,匹配和其他框架

如果不提及一些补充测试库,那么关于Java测试,JUnit和TestNG的博客文章是不完整的。
在本节中,我们将根据GitHub的顶级Java项目 ,对最受欢迎的库进行这些类别的快速概述。

嘲笑

一个好的做法是隔离运行单元测试,但是如果要测试的组件依赖于其他复杂对象怎么办? 这是进行模拟的地方,让我们创建模拟对象,以模拟系统其他部分所需的行为:

  • Mockito (#8,项目的10.2%)
  • EasyMock (#49,项目的2.9%)
  • Powermock (#91,项目的1.76%)

匹配

JUnit和TestNG所提供的断言是非常基本的,使用匹配器有助于提高其可读性,并增加更多功能供您选择:

  • Hamcrest (#34,项目的4.12%)
  • AssertJ (#55,占项目的2.72%)
  • 另一个值得一试的库是Google的Truth ,我们在其中写了一篇有关Google有趣的Java项目(超越Guava)的文章 。

还有... Spock

Spock是一个基于JUnit的新兴的Groovy( 不是那种groovy )测试框架。 其背后的想法是通过简单的Groovy DSL将测试库生态系统整合为一个单一框架。 在关于Groovy 及其在Java中的用法的帖子中,我们讨论了它的一些功能。 要进行更深入的比较,请查看Kostis Kapelonis的 这些幻灯片 。

底线:测试通常不会止于单个框架,而是要了解游戏中的其他库。

8.社区

JUnit拥有更悠久的历史和相当大的用户基础,它基本上定义了Java单元测试的标准。 因此,它拥有最大的用户群,很容易找到答案或有人问您可能遇到的任何问题。

TestNG的用户可能较少,但是它的社区并不短(尽管其网站可以改头换面)。 而且...两者都可以从一些徽标准则中受益。 人群中有设计师吗?

stackoverflowjunittestngtags-768x128

在Stackoverflow上用junit和testng标记的问题

这是一些有关JUnit的有用链接:

  • JUnit 4 网站和GitHub存储库
  • JUnit 5 网站和GitHub存储库

和TestNG:

  • TestNG 网站和GitHub存储库
  • TestNG 讨论组

底线:您不会对任何一个迷路。

最后的想法

Java测试已经走了很长一段路,我们很高兴能在测试很重要的时代。 这里的主要收获是创建有意义的测试。

照这样说…

您正在使用哪个框架,为什么? 给定一个干净的选择,您会选择什么? 在下面的评论部分让我们知道。

翻译自: https://www.javacodegeeks.com/2016/09/junit-vs-testng-testing-framework-choose.html

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

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

相关文章

小尾数,大尾数

大尾小尾 是数据在存储器中的存储格式,INtel采用的是小尾表示,即数据的高位存储在存储器的高地址,低位存储在存储器的低地址,例如一个十六进制数据0x1234存储在内存中,那么该数据在内存中的存储格式为: 34 …

s11.1 lsof:查看进程打开的文件

功能说明 lsof 全名为list open files,也就是列举系统中已经被打开的文件,通过lsof命令,就可以根据文件找到对应的进程信息,也可以根据进程信息找到进程打开的文件。【语法格式】 lsof [option]lsof [选项]参数选项 …

理解linux time命令的输出

Linux中time命令,我们经常用来计算 某个程序的运行耗时(real), 用户态cpu耗时(user), 系统态cpu耗时(sys)。例如:$ time foo real 0m0.003s user 0m0.000s sys 0m0.004s$ 那么这三个时间都具体代表什么意思…

matlab persistent静态变量

persistent关键字说明; matlab中persistent定义为一个静态变量,程序结束静态变量内存不释放,只有在matlab程序关闭时,静态变量的内存才被清除。当程序结束时,不希望变量的值被清空,这时可以用persistent关键…

小程序 转义_为内存密集型应用程序转义JVM堆

小程序 转义如果您曾经分配过大型Java堆,您就会知道在某个时候(通常从大约4 GiB开始),您将开始遇到垃圾回收暂停的问题。 我不会详细说明为什么在JVM中会出现暂停,但是总之,当JVM进行完整的收集并且您有很…

Ubuntu 进入单用户模式—修改启动项利器

偶尔会遇到Ubuntu无法正常启动的情况,这时候需修改某些文件让系统正常启动,如果直接进入 recovery 模式,默认是文件权限只读,无法修改文件。这是我们需要进入recovery 的单用户模式,获得修改文件的权限。 1、重启ubunt…

博客教程中百度网盘地址

博客中百度网盘地址: 链接:https://pan.baidu.com/s/1ncGK5fXMBmmkuZGbBSohBw 提取码:v67x 复制这段内容后打开百度网盘手机App,操作更方便哦 转载于:https://www.cnblogs.com/PIESat/p/10593654.html

只有经验丰富的开发人员才能教您有关Java的5件事

深入研究Java之前需要了解的所有内容的概述 有许多工具,方法,环境和功能会改变您处理代码的方式,而这些通常是在学年期间不会遇到的。 尽管它在Java开发世界中迈出了第一步,但大多数实际学习都是在工作中进行的。 在接下来的文章…

conda命令

创建环境 conda create --name snowflake biopython 这条命令将会给biopython包创建一个新的环境,位置在/envs/snowflakes 很多跟在--后边常用的命令选项,可以被略写为一个短线加命令首字母。所以--name选项和-n的作用是一样的。通过conda -h或conda –-…

bzoj4443:[Scoi2015]小凸玩矩阵

传送门 二分答案是显然的啊&#xff0c;然后对于比二分出的值大的直接跑最大匹配&#xff0c;然后判定就好了 代码&#xff1a; #include<cstdio> #include<iostream> #include<algorithm> #include<vector> #include<cstring> using namespace …

GDB调试及其调试脚本的使用

一、GDB调试 1.1. GDB 概述 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许&#xff0c;各位比较喜欢那种图形界面方式的&#xff0c;像VC、BCB等IDE的调试&#xff0c;但如果你是在UNIX/Linux平台下做软件&#xff0c;你会发现GDB这个调试工具有比VC、BCB的图形…

Python中xlrd模块解析

xlrd 导入模块 import xlrd 2、打开指定的excel文件&#xff0c;返回一个data对象 data xlrd.open_workbook(file) #打开excel表&#xff0c;返回data对象 3、通过data对象可以得到各个sheet对象(一个excel文件可以有多个sheet&#xff0c;每个sheet就是一…

数学中常见的距离

1. 欧氏距离 最常见的两点之间或多点之间的距离表示法&#xff0c;又称之为欧几里得度量&#xff0c;它定义于欧几里得空间中&#xff0c;如点 x (x1,...,xn) 和 y (y1,...,yn) 之间的距离为&#xff1a; (1) 二维平面上两点a(x1,y1)与b(x2,y2)间的欧氏距离&#xff1a; (…

使用Spring Boot和Heroku在20分钟内完成Java的单点登录

建筑物身份管理&#xff0c;包括身份验证和授权&#xff1f; 尝试Stormpath&#xff01; 我们的REST API和强大的Java SDK支持可以消除您的安全风险&#xff0c;并且可以在几分钟内实现。 注册 &#xff0c;再也不会建立auth了&#xff01; 大规模更新 我最初为本文撰写的代码…

OO第一次单元总结

第一次总结性博客 16071070 陈泽寅 2019.3.23 一、第一单元所学总结 首先先来总结一下第一单元我所学到的知识以及所感所悟。第一个单元&#xff0c;是我第一次接触JAVA语言&#xff0c;并且再使用了几次之后&#xff0c;就被这门语言的独有的魅力以及简便的用法所深深吸引。下…

汇编语言学习笔记(十二)-浮点指令

浮点数如何存储浮点寄存器浮点数指令浮点计算例子浮点高级运算CMOV移动指令 浮点数如何存储 浮点数的运算完全不同于整数&#xff0c;从寄存器到指令&#xff0c;都有一套独特的处理流程&#xff0c;浮点单元也称作x87 FPU。 现在看浮点数的表示方式&#xff0c;我们所知道的&a…

人工智能简述

人工智能研究的方向之一&#xff0c;是以所谓 “专家系统” 为代表的&#xff0c;用大量 “如果-就” &#xff08;If - Then&#xff09; 规则定义的&#xff0c;自上而下的思路。   人工神经网络 &#xff08; Artifical Neural Network&#xff09;&#xff0c;标志着另外…

Mockito 的使用

转自&#xff1a;Mockito 中文文档 ( 2.0.26 beta ) 转自&#xff1a;手把手教你 Mockito 的使用 参数匹配器 Argument Matcher(参数匹配器) Mockito通过equals()方法&#xff0c;来对方法参数进行验证。但是有时候我们需要更加灵活的参数需求&#xff0c;比如&#xff0c;匹配…