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团队 :

我刚刚将github上的junit存储库转移到junit-team。 *嗅嗅*我的孩子都长大了。

—肯特·贝克(@KentBeck) 2013年2月6日

早期的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开发工具)一起提供,但是确实如此。

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

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

4.报告结果

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

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

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

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

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

5.自动化测试运行

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

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

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

6.终止失败的测试

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

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


底线:要使您的环境更上一层楼 ,请查看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的用户可能较少,但是它的社区并不短(尽管其网站可以改头换面)。 而且...两者都可以从一些徽标准则中受益。 人群中有设计师吗?

在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

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

  1. 用maven搭建 testNG+PowerMock+Mockito测试框架

    转载:http://www.cnblogs.com/changzhz/p/5158068.html 单元测试是开发中必不可少的一部分,是产品代码的重要保证. Junit和testNG是当前最流行的测试 ...

  2. gtest测试框架使用详解_测试框架TestNG使用介绍

    近期接触到了一个比较全面的基于Java的接口自动化测试框架,作为一名Java小白,所以打算研究一下,顺带学习学习Java,该测试框架的逻辑控制层使用的HttpClient + TestNG. 在本期中 ...

  3. TestNG测试框架介绍整理

    TestNG学习 什么是TestNG 添加pom maven依赖 Idea创建module 注解之@BeforeMethod和@AfterMethod 注解之@BeforeClass和@AfterCl ...

  4. 机器学习编程语言_我应该选择哪种编程语言? 我应该专注于前端吗? 后端? 机器学习?...

    机器学习编程语言 by Preethi Kasireddy 通过Preethi Kasireddy 我应该选择哪种编程语言? 我应该专注于前端吗? 后端? 机器学习? (What programmin ...

  5. 心得丨对于机器学习,到底该选择哪种编程语言

    作者: jihong10102006 开发者到底应该学习哪种编程语言才能获得机器学习或数据科学这类工作呢?这是一个非常重要的问题.我们在许多论坛上都有讨论过.现在,我可以提供我自己的答案并解释原因,但 ...

  6. 到底应该选择哪种Linux.NET的部署方式?

    到底应该选择哪种Linux.NET的部署方式? 当前部署Linux.NET环境的方式可谓是五花八门,既有传统的源码编译的方式.又有各式各样的一键安装脚本.还有绿色包安装方式,而随着Mono官方的新站上 ...

  7. Windows Mobile开发应该选择哪种开发语言?

    Windows Mobile开发应该选择哪种开发语言?这个问题曾经被问了很多很多次,特别是打算开始学习Windows Mobile开发的朋友.Native Code or Managed Code? ...

  8. 规格选择_日常使用的拉杆箱脚轮选择哪种规格最合适?

    大家可能在采购拉杆箱脚轮的时候,都会有一个问题,拉杆箱脚轮规格选择哪种比较好呢?万向轮好还是单向轮?是万向轮还是单向轮比较耐磨?脚轮厂家诺贝小编接收到大家的疑问,接下来将告诉大家拉杆箱脚轮选择的规格. ...

  9. 新手前端练手网站_编程到底难不难学?新手入门选择哪种语言好?

    以下内容适合的读者:想要学习编程的小白 一.编程到底难不难学? 对于这个问题我的回答是不知道,学会了编程的人会说好学,中途就放弃的人会说很难,任何知识想要掌握好都不是一件容易的事情.所以我决定用自己的 ...

最新文章

  1. nginx日志模块及日志格式
  2. intent的startActivityForResult()方法
  3. 条件随机场 (CRF) 分词序列谈之一(转)
  4. Mobile RDA 同步数据库的类--转
  5. pip安装deb_技术|如何在 Ubuntu 上安装 pip
  6. php传递数据给jquery,将值从php传递给jquery
  7. php websocket 帧封装,swoole websocket封装类和调用
  8. php相隔几分钟变换随机数,PHP怎么固定随机出号几分钟时间再变?
  9. 调试js 试用火狐的firebug
  10. android 上划卡住tab_Android SlidingTabLayout用法禁止ViewPager滑动
  11. struct interface_今天就谈谈go中的接受 interface 参数,返回 struct
  12. ASP.Net学习笔记001--ASP.Net简介1
  13. C语言中全局变量、局部变量、静态全局变量、静态局部变量的区别 (转)
  14. ZTree相关使用的例子
  15. linux 反汇编 静态库,如何反汇编.lib静态库?
  16. NVIDIA Riva中文手册 (五) —— Riva TTS语音合成API的使用
  17. iview+Collapse折叠面板动态操作表单
  18. Effective Java笔记(第二章)
  19. 检索的原理和方法步骤
  20. UI入门必读!完整的UI设计学习流程是怎样的?

热门文章

  1. Java IO: InputStreamReader和OutputStreamWriter
  2. 表扬几位积极的同学!
  3. Git GitHub Gitee GitLab
  4. MyBatis中多表查询(N+1方式)
  5. 查找前端依赖 jquery css js 时间控件 不要用远程依赖 会变化的 card
  6. html5中 save方法,如何HTML5画布另存为窗口8 Metro应用中的图像文件?(How to save html5 c...
  7. (转)数据库可靠性/可用性、稳定性RTO/RPO
  8. jvm高级特性第4章-虚拟机性能监控与故障处理工具
  9. spring(1)Spring之旅
  10. 583. 两个字符串的删除操作用时6ms的另类解法