参数化的单元测试用于在不同条件下测试相同的代码。 借助参数化的单元测试,我们可以建立一种测试方法,该方法从某些数据源中检索数据。 该数据源可以是测试数据对象,外部文件甚至数据库的集合。 一般的想法是使使用相同的单元测试方法测试不同的条件变得容易,这将限制我们需要编写的源代码并使测试代码更健壮。 我们可以将这些测试称为数据驱动的单元测试。

在JUnit中实现数据驱动的单元测试的最佳方法是使用JUnit的自定义运行器- Parameterized或JUnitParams的 JUnitParamsRunner 。 使用JUnit的方法可能在许多情况下都可行,但是后者似乎更易于使用且功能更强大。

基本例子

在我们的示例中,一个扑克骰子,我们需要计算满屋的得分。 就像纸牌扑克一样,“满座”是一副掷骰子,您同时拥有3个和一对。 为了简单起见,分数是一卷中所有骰子的总和。 因此,让我们看一下代码:

class FullHouse implements Scoreable {@Overridepublic Score getScore(Collection dice) {Score pairScore = Scorables.pair().getScore(dice);Score threeOfAKindScore = Scorables.threeOfAKind().getScore(pairScore.getReminder());if (bothAreGreaterThanZero(pairScore.getValue(), threeOfAKindScore.getValue())) {return new Score(pairScore.getValue() + threeOfAKindScore.getValue()); // no reminder}return new Score(0, dice);}private boolean bothAreGreaterThanZero(int value1, int value2) {return value1 > 0 && value2 > 0;}
}

我想确保该掷骰正确得分(当然我已经对Pair和ThreeOfAKind进行了单元测试)。 因此,我想测试以下条件:

  • 分数是11:1、1、3、3、3
  • 2、2、2、1、1的得分是8
  • 分数是0代表:2、3、4、1、1
  • 分数是25,表示:5、5、5、5、5

让我们研究为该方法编写数据驱动的测试的两种可能方法。 首先, JUnit的参数化

@RunWith(Parameterized.class)
public class FullHouseTest {private Collection rolled;private int score;public FullHouseTest(Collection rolled, int score) {this.rolled = rolled;this.score = score;}@Testpublic void fullHouse() {assertThat(new FullHouse().getScore(rolled).getValue()).isEqualTo(score);}@Parameterized.Parameterspublic static Iterable data() {return Arrays.asList(new Object[][]{{roll(1, 1, 3, 3, 3), score(11)},{roll(2, 2, 2, 1, 1), score(8)},{roll(2, 3, 4, 1, 1), score(0)},{roll(5, 5, 5, 5, 5), score(25)}});}private static int score(int score) {return score;}
}

另一个是JUnitParams

@RunWith(JUnitParamsRunner.class)
public class FullHouseTest {@Test@Parameterspublic void fullHouse(Collection rolled, int score) {assertThat(new FullHouse().getScore(rolled).getValue()).isEqualTo(score);}public Object[] parametersForFullHouse() {return $($(roll(1, 1, 3, 3, 3), score(11)),$(roll(2, 2, 2, 1, 1), score(8)),$(roll(2, 3, 4, 1, 1), score(0)),$(roll(5, 5, 5, 5, 5), score(25)));}private static int score(int score) {return score;}
}

乍一看,两者看起来非常相似。 没错 那么JUnit Parameterized (1)和JUnitParams(2)之间有什么区别? 最重要的一种是传递参数的方法,因此实际上是解决方案的体系结构。 在(1)中,参数在构造函数中传递,而在(2)中,参数直接传递到测试方法。 我应该在乎吗? 是。 原因之一是,在(2)中,我们可以有多个参数化测试方法,每种方法的数据都不同,如以下示例所示:

@RunWith(JUnitParamsRunner.class)
public class NumberOfAKindTest {@Test@Parameterspublic void pair(Collection rolled, int[] expected, int score) {NumberOfAKind sut = new NumberOfAKind(2);doTest(rolled, expected, score, sut);}@Test@Parameterspublic void threeOfAKind(Collection rolled, int[] expected, int score) {NumberOfAKind sut = new NumberOfAKind(3);doTest(rolled, expected, score, sut);}public Object[] parametersForPair() {return $($(roll(1, 1, 1, 2, 3), hand(1, 1), score(2)),$(roll(2, 1, 1, 1, 1), hand(1, 1), score(2)),$(roll(2, 3, 4, 1, 1), hand(1, 1), score(2)),$(roll(2, 3, 5, 5, 5), hand(5, 5), score(10)),$(roll(2, 1, 5, 4, 3), null, score(0)));}public Object[] parametersForThreeOfAKind() {return $($(roll(1, 1, 1, 2, 3), hand(1, 1, 1), score(3)),$(roll(2, 1, 1, 1, 3), hand(1, 1, 1), score(3)),$(roll(2, 3, 1, 1, 1), hand(1, 1, 1), score(3)),$(roll(2, 3, 5, 5, 5), hand(5, 5, 5), score(15)),$(roll(2, 5, 5, 5, 6), hand(5, 5, 5), score(15)),$(roll(2, 2, 5, 5, 3), null, score(0)));}private static int[] hand(int... dice) {return dice;}private static int score(int score) {return score;}}

在更简单的示例中,可以通过值方法直接在@Parameters批注中将参数定义为String数组。 我们还可以将数据提取到一个外部类中,并使我们的测试更加清晰易读。 NumberOfAKind的完整测试如下:

@RunWith(JUnitParamsRunner.class)
public class NumberOfAKindTest {@Test@Parameters(source = NumberOfAKindProvider.class, method = "providePair")public void pair(Collection rolled, int[] expected, int score) {NumberOfAKind sut = new NumberOfAKind(2);doTest(rolled, expected, score, sut);}@Test@Parameters(source = NumberOfAKindProvider.class, method = "provideThreeOfAKind")public void threeOfAKind(Collection rolled, int[] expected, int score) {NumberOfAKind sut = new NumberOfAKind(3);doTest(rolled, expected, score, sut);}@Test@Parameters(source = NumberOfAKindProvider.class, method = "provideFourOfAKind")public void fourOfAKind(Collection rolled, int[] expected, int score) {NumberOfAKind sut = new NumberOfAKind(4);doTest(rolled, expected, score, sut);}@Test@Parameters(source = NumberOfAKindProvider.class, method = "provideFiveOfAKind")public void fiveOfAKind(Collection rolled, int[] expected, int score) {NumberOfAKind sut = new NumberOfAKind(5);doTest(rolled, expected, score, sut);}private void doTest(Collection rolled, int[] expected, int score, NumberOfAKind sut) {Collection consecutiveDice = sut.getConsecutiveDice(rolled);assertDiceContainsValues(consecutiveDice, expected);assertThat(sut.getScore(rolled).getValue()).isEqualTo(score);}private void assertDiceContainsValues(Collection dice, int[] expected) {Collection values = toInts(dice);if (expected == null) {assertThat(values).isEmpty();return;}for (int i = 0; i < expected.length; i++) {assertThat(values).hasSize(expected.length).contains(expected[i]);}}private Collection toInts(Collection dice) {return Collections2.transform(dice, new Function() {@Overridepublic Integer apply(Dice input) {return input.getValue();}});}}

每个方法都指定提供程序类和提供程序的方法名称。 查看以下提供者:

public class NumberOfAKindProvider {public static Object[] providePair() {return $($(roll(1, 1, 1, 2, 3), hand(1, 1), score(2)),$(roll(2, 1, 1, 1, 1), hand(1, 1), score(2)),$(roll(2, 3, 4, 1, 1), hand(1, 1), score(2)),$(roll(2, 3, 5, 5, 5), hand(5, 5), score(10)),$(roll(2, 1, 5, 4, 3), null, score(0)));}public static Object[] provideThreeOfAKind() {return $($(roll(1, 1, 1, 2, 3), hand(1, 1, 1), score(3)),$(roll(2, 1, 1, 1, 3), hand(1, 1, 1), score(3)),$(roll(2, 3, 1, 1, 1), hand(1, 1, 1), score(3)),$(roll(2, 3, 5, 5, 5), hand(5, 5, 5), score(15)),$(roll(2, 5, 5, 5, 6), hand(5, 5, 5), score(15)),$(roll(2, 2, 5, 5, 3), null, score(0)));}public static Object[] provideFourOfAKind() {return $($(roll(1, 1, 1, 1, 3), hand(1, 1, 1, 1), score(4)),$(roll(2, 1, 1, 1, 1), hand(1, 1, 1, 1), score(4)),$(roll(2, 5, 5, 5, 5), hand(5, 5, 5, 5), score(20)),$(roll(2, 3, 4, 5, 5), null, score(0)));}public static Object[] provideFiveOfAKind() {return $($(roll(1, 1, 1, 1, 1), hand(1, 1, 1, 1, 1), score(5)),$(roll(6, 6, 6, 6, 6), hand(6, 6, 6, 6, 6), score(30)),$(roll(6, 6, 6, 6), null, score(0)),$(roll(2, 3, 4, 6, 6), null, score(0)));}private static int[] hand(int... dice) {return dice;}private static int score(int score) {return score;}
}

摘要

对我来说, JUnitParams是编写良好的数据驱动的单元测试的更好的解决方案。 但是上面介绍的并不是库必须提供给开发人员的所有内容。 还有更多功能。 参数可以作为CSV字符串传递,我们可以混合参数化测试和非参数化测试,仅举几例。

请访问该项目的网站以了解有关此库的更多信息: https : //code.google.com/p/junitparams

参考:来自Codeleak.pl博客的JCG合作伙伴 Rafal Borowiec的JUnitParams 参数化JUnit测试 。

翻译自: https://www.javacodegeeks.com/2013/12/parameterized-junit-tests-with-junitparams.html

使用JUnitParams进行参数化的JUnit测试相关推荐

  1. 参数化测试 junit_使用JUnitParams进行参数化的JUnit测试

    参数化测试 junit 参数化的单元测试用于在不同条件下测试相同的代码. 借助参数化的单元测试,我们可以建立一种测试方法,该方法从某个数据源中检索数据. 该数据源可以是测试数据对象,外部文件甚至数据库 ...

  2. 参数化测试 junit_参数化的JUnit测试

    参数化测试 junit 有时,您会遇到一个问题,就是尖叫使用"参数化"测试,而不是多次复制/粘贴相同的方法. 测试方法基本上是相同的,唯一改变的是传入的数据.在这种情况下,请考虑创 ...

  3. 参数化的JUnit测试

    有时,您会遇到一个问题,就是尖叫使用"参数化"测试,而不是多次复制/粘贴相同的方法. 测试方法基本上是相同的,唯一改变的是传入的数据.在这种情况下,请考虑创建一个利用JUnit中的 ...

  4. junit测试spring_使用Spring JUnit规则进行参数化集成测试

    junit测试spring Spring 4.2附带了全新的JUnit规则: SpringClassRule和SpringMethodRule . 使用JUnit规则的主要优点是让开发人员摆脱Spri ...

  5. Android Junit测试

    2019独角兽企业重金招聘Python工程师标准>>> 本次要解决的问题是以下几个: 1)什么是Junit测试 Junit是对用java语言进行的,白盒性质的,单元测试框架.Ecli ...

  6. 测试学习java_使用Junit测试框架学习Java

    前言 在日常的开发中,离不开单元测试,而且在学习Java时,特别是在测试不同API使用时要不停的写main方法,显得很繁琐,所以这里介绍使用Junit学习Java的方法.此外,我使用log4j将结果输 ...

  7. JUnit测试类完成后事务是默认 回滚的。只能查询数据,不能增删改。

    JUnit测试类完成后事务是默认 回滚的.只能查询数据,不能增删改. 在测试类或者测试方法上面加上注解 @Rollback(false)  表示事物不回滚,这样数据就可以提交到数据库中了. 转载于:h ...

  8. 创建JUNIT测试类

    建立JUNIT测试类步骤: 1 建立正常的JAVA工程 2  在JAVA工程的build path 的LIB中导入JUNIT4 3 工程中新建一个普通TEST.JAVA,在该类中在随便的一个方法上,反 ...

  9. 行意天下正文 Android Day02-Android中单元测试(junit测试)monkey测试

    Android中junit测试有2种实现方式 第1种:一般Android工程的实现方式 1.在清单文件中添加2项内容 首先在AndroidManifest.xml中加入下面红色代码: <mani ...

最新文章

  1. Ubuntu环境变量
  2. c语言求阶乘和的流程图_C/C++编程笔记:C语言 rand() 随机函数,深入解析程序随机数!...
  3. 模糊数学笔记:六、模糊模型识别-II(择近原则)
  4. 【转】Postman安装与使用
  5. boost::bad_function_call用法的测试程序
  6. roads 构筑极致用户体验_长安马自达「悦马星空」计划上线,为用户带来极致服务体验...
  7. 03 CSS听课笔记
  8. 2 亚马逊_索泰称仅亚马逊渠道就收到2万块RTX 3080显卡订单,无法按时发货
  9. BZOJ 3674 可持久化并查集
  10. [Ext JS 7]7.6 内存泄露及处理
  11. 华为防火墙忘记密码,使用console口更改密码
  12. java游戏项目推箱子
  13. day01 -Web API介绍—DOM 介绍—获取元素—事件基础—操作元素—排他操作—自定义属性操作—节点操作—案例:动态生成表格—创建元素的三种方式(经典面试题)
  14. 微信小程序仿记事本,带下划线,自动换行,高度自增
  15. telegram java,telegram_bot
  16. unknown类型的使用
  17. HTML的语义化理解
  18. 在CMD上运行javac前应该这样做
  19. chrome源代码目录结构简介(版本4.1.249.1059)
  20. 学习opengl官方指南 01 opengl介绍

热门文章

  1. zookeeper  虚拟机zookeeper和 win10java代码连接
  2. kafka命令行操作
  3. java 十六进制浮点_Java十六进制浮点文字
  4. 队列和消息队列_消息队列概述[幻灯片]
  5. jboss fuse 教程_JBoss Fuse:使用JEXL的动态蓝图文件
  6. 装饰器模式java_Java 8的装饰器模式
  7. 将Visual Studio Code设置为jshell中的默认编辑器
  8. 维持硒测试自动化的完美方法
  9. 组织机构代码输入测试用例_测试代码以用于过大的输入
  10. activemq网络桥接_ActiveMQ –经纪人网络解释–第2部分