junit参数化测试
在前面的junit4初体验中我就说过,junit参数化测试是一只小怪兽,只逼编码痛点,现在我们这里来整理一下。
看过我前面的那篇初体验的就会发现一个问题,我们的测试代码大量的重复了。在这里先贴出原来的那2篇代码:
测试源码:
- package test.junit4test;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- public final class Linkin
- {
- /**
- * @创建时间: 2016年1月28日
- * @相关参数: @param name
- * @相关参数: @return
- * @功能描述:格式化一个Java驼峰规则的字符串成数据库规则。
- */
- public static final String underscoreName(String name)
- {
- if (name == null)
- {
- return null;
- }
- if ("".equals(name))
- {
- return "";
- }
- StringBuilder result = new StringBuilder().append(name.substring(0, 1).toLowerCase());
- for (int i = 1; i < name.length() - 1; i++)
- {
- String s = name.substring(i, i + 1);
- String slc = s.toLowerCase();
- String pres = name.substring(i - 1, i);
- String preslc = pres.toLowerCase();
- if (!s.equals(slc) && pres.equals(preslc))
- {
- result.append("_").append(slc);
- }
- else
- {
- result.append(slc);
- }
- }
- return result.append(name.substring(name.length() - 1, name.length()).toLowerCase()).toString();
- }
- /**
- * @创建时间: 2016年1月28日
- * @相关参数: @param name Java对象名称
- * @相关参数: @return 格式化后的名称
- * @功能描述: 将Java对象名称(每个单词的头字母大写)按照数据库命名的习惯进行格式化
- * <p>
- * 格式化后的数据为小写字母,并且使用下划线分割命名单词。
- * 如果参数name为null,则返回null。
- * 例如:employeeInfo 经过格式化之后变为 employee_info
- * </p>
- */
- public static final String wordFormat4DB(String name)
- {
- if (name == null)
- {
- return null;
- }
- Pattern p = Pattern.compile("[A-Z]");
- Matcher m = p.matcher(name);
- StringBuffer sb = new StringBuffer();
- while (m.find())
- {
- if (m.start() != 0)
- {
- m.appendReplacement(sb, ("_" + m.group()).toLowerCase());
- }
- }
- return m.appendTail(sb).toString().toLowerCase();
- }
- }
测试代码:
- package test.junit4test;
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertNull;
- import org.junit.Before;
- import org.junit.Test;
- public class LinkinTest
- {
- private static final String JAVANAME = "userInfo";
- private static final String DBNAME = "user_info";
- Linkin linkin = null;
- @Before
- public void setUp()
- {
- linkin = new Linkin();
- }
- @Test
- // 测试字符串正常的情况
- public void testUnderScoreName4Normal()
- {
- String underscoreName = linkin.underscoreName(JAVANAME);
- assertEquals(DBNAME, underscoreName);
- }
- @Test
- // 测试字符串为null的情况
- public void testUnderScoreName4Null()
- {
- String underscoreName = linkin.underscoreName(null);
- assertNull(underscoreName);
- }
- @Test
- // 测试字符串为空字符串的情况
- public void testUnderScoreName4Empty()
- {
- String underscoreName = linkin.underscoreName("");
- assertEquals("", underscoreName);
- }
- @Test
- // 测试当首字母大写时的情况
- public void testUnderScoreName4Begin()
- {
- String underscoreName = linkin.underscoreName("UserInfo");
- assertEquals(DBNAME, underscoreName);
- }
- @Test
- // 测试当尾字母为大写时的情况
- public void testUnderScoreName4End()
- {
- String underscoreName = linkin.underscoreName("userInfO");
- assertEquals(DBNAME, underscoreName);
- }
- @Test
- // 测试多个相连字母大写时的情况
- public void testUnderScoreName4Together()
- {
- String underscoreName = linkin.underscoreName("userINfo");
- assertEquals(DBNAME, underscoreName);
- }
- }
为了保证单元测试的严谨性,我们模拟了不同类型的字符串来测试方法的处理能力,为此我们编写大量的单元测试方法。可是这些测试方法都是大同小异:代码结构都是相同的,不同的仅仅是测试数据和期望值。有没有更好的方法将测试方法中相同
的代码结构提取出来,提高代码的重用度,减少复制粘贴代码的烦恼?在以前的 JUnit 版本上,并没有好的解决方法,而现在您可以使用 JUnit 提供的参数化测试方式应对这个问题。
参数化测试的编写稍微有点麻烦(当然这是相对于 JUnit 中其它特性而言):
1,为准备使用参数化测试的测试类指定特殊的运行器 org.junit.runners.Parameterized。
2,为测试类声明几个变量,分别用于存放期望值和测试所用数据。
3,为测试类声明一个使用注解 org.junit.runners.Parameterized.Parameters 修饰的,返回值为 java.util.Collection 的公共静态方法,并在此方法中初始化所有需要测试的参数对。
4,为测试类声明一个带有参数的公共构造函数,并在其中为第二个环节中声明的几个变量赋值。
5,编写测试方法,使用定义的变量作为参数进行测试。
我们按照这个标准,重新改造一番我们的单元测试代码:
- package test.junit4test;
- import java.util.Arrays;
- import java.util.Collection;
- import org.junit.Assert;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.junit.runners.Parameterized;
- import org.junit.runners.Parameterized.Parameters;
- @RunWith(Parameterized.class)
- public class LinkinTest
- {
- private String expected;
- private String target;
- @Parameters
- public static Collection<String[]> words()
- {
- return Arrays.asList(new String[][] { { "employee_info", "employeeInfo" }, // 测试一般的处理情况
- { null, null }, // 测试 null 时的处理情况
- { "", "" }, // 测试空字符串时的处理情况
- { "employee_info", "EmployeeInfo" }, // 测试当首字母大写时的情况
- { "employee_info_a", "employeeInfoA" }, // 测试当尾字母为大写时的情况
- { "employee_a_info", "employeeAInfo" }// 测试多个相连字母大写时的情况
- });
- }
- /**
- * @创建时间: 2016年1月28日
- * @相关参数: @param expected 期望的测试结果,对应参数集中的第一个参数
- * @相关参数: @param target 测试数据,对应参数集中的第二个参数
- * @构造描述: 参数化测试必须的构造函数
- */
- public LinkinTest(String expected, String target)
- {
- this.expected = expected;
- this.target = target;
- }
- /**
- * 测试将 Java 对象名称到数据库名称的转换
- */
- @Test
- public void wordFormat4DB()
- {
- Assert.assertEquals(expected, Linkin.wordFormat4DB(target));
- }
- }
很明显,代码瘦身了。在静态方法 words 中,我们使用二维数组来构建测试所需要的参数列表,其中每个数组中的元素的放置顺序并没有什么要求,只要和构造函数中的顺序保持一致就可以了。现在如果再增加一种测试情况,只需要在静态方法 words 中添加相应的数组即可,不再需要复制粘贴出一个新的方法出来了。运行上面的测试,将会根据@Parameters注解修饰的方法返回一个Collection,然后进行相同次数的循环。
现在我们来逐步分析下parameters这只小怪兽在junit中的运行过程,以理解这份强大的功能:
1,首先junit调用了静态方法words,然后junit为words这个集合中的每个数组进行循环。
2,junit调用唯一的构造器,注意这个时候,如果该测试类存在多个构造器,junit就会抛出一个断言错误。
3,junit使用由该数组参数构成的一系列参数来调用构造器,然后开始一次测试。
4,重复上面的步骤,直到都运行完Collection集合中的数组元素。
junit的parameterized类是junit众多测试运行器的一个。测试运行器可以让你控制junit如何运行测试。我们可以使用别的运行器,也可以自定义自己的运行器来使用,使用RunWith就可以。下一篇我们就来整理下junit运行器。
junit参数化测试的更多相关文章
- junit参数化测试的使用方法
JUnit参数化测试的五个步骤:(1)为准备使用参数化测试的测试类指定特殊的运行器 org.junit.runners.Parameterized.(2)为测试类声明几个变量,分别用于存放期望值和测试 ...
- 计算某天的下一天:黑盒测试之等价类划分+JUnit参数化测试
题目要求 测试以下程序:该程序有三个输入变量month.day.year(month.day和year均为整数值,并且满足:1≤month≤12.1≤day≤31和1900≤year≤2050),分别 ...
- Junit参数化测试Spring应用Dubbo接口
一.创建基础类. package com.tree.autotest; import org.junit.Before;import org.springframework.context.annot ...
- JUnit实战(1) - JUnit起步(Parameterized参数化测试)
创建Java Project项目,项目名称:ch01-jumpstart Calculator.java public class Calculator { public double add(dou ...
- junit 单元测试 - 参数化测试
junit4.x版本需要引入如下jar包: hamcrest-core-1.3.jar junit-4.12-beta-3.jar 新建一个计算器类,如下: package com.pt; publi ...
- JUnit之参数化测试、套件/成组测试的使用
原文地址http://blog.csdn.net/yqj2065/article/details/39967065 参数化测试 正如数组替代int a0,a1,a2一样,测试加法时assertEqua ...
- 测试 | 单元测试工具 | JUnit | 参数化
被测试类: package project; public class MyCalendar2 { public int getNumberOfDaysInMonth(int year, int mo ...
- 同时使用Junit4的@Parameterized参数化测试和Spring容器
转载:http://www.jianshu.com/p/d191fe54915f 整合Spring容器 @SpringApplicationConfiguration(classes = Applic ...
- 用JUnit4进行参数化测试
参数化测试是一个JUnit 3不具备的功能. 基本使用方法 @RunWith 当类被@RunWith注解修饰,或者类继承了一个被该注解修饰的类,JUnit将会使用这个注解所指明的运行器(runner) ...
随机推荐
- linux 常见操作指令
1.ssh root@ip ssh 登录 2.ll ls 列出当文件夹下 所以文件 3. cd ./xx 进入 xx 文件夹 4. vim vi xxx 进入 xx文件的 编辑模式. i 开始编辑 e ...
- 从Unity中的Attribute到AOP(六)
本文将重点对Unity剩下常用的Attribute进行讲解,其他不常用的Attribute各位可以自行去官方文档查阅. 首先是UnityEngine命名空间下的. ColorUsage,这个主要作用于 ...
- 【转载】从头编写 asp.net core 2.0 web api 基础框架 (4) EF配置
Github源码地址:https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-template-from-scratc ...
- datalist标签小结
在Web设计中,经常会用到如输入框的自动下拉提示,这将大大方便用户的输入.在以前,如果要实现这样的功能,必须要求开发者使用一些Javascript的技巧或相关的框架进行ajax调用,需要一定的编程工作 ...
- vue.js之数据传递和数据分发slot
一.组件间的数据传递 1.父组件获取子组件的数据 *子组件把自己的数据,发送到父级 *vm.$emit(事件名,数据); *v-on: @ 示例用法:当点击send按钮的时候,"111&qu ...
- 使用quartz实现不重启服务器修改自定义配置
为了方便维护系统,开发中通常会设置一些自定义参数,写在单独的配置文件里,需要调整时可直接登录服务器修复配置文件,而不需要修改程序.但尴尬的是,web服务器并不会自动重新加载配置文件,重启服务器又会中断 ...
- hdu_1028_母函数
虽然我很想自己写母函数讲解...但是最近事情太多了,就贴个很入门的讲解吧给出一个经典的模板A了这个题 http://blog.csdn.net/vsooda/article/details/79754 ...
- 94、存储库之MongoDB、mysql
本篇导航: 简介 MongoDB基础知识 安装 基本数据类型 CRUD操作 其它 存储库之mysql 一.简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库1.易用性 MongoDB是 ...
- c++(单词统计)
在面试环节中,有一道题目也是考官们中意的一道题目:如果统计一段由字符和和空格组成的字符串中有多少个单词? 其实,之所以问这个题目,考官的目的就是想了解一下你对状态机了解多少. (1) 题目分析 从题目 ...
- vi 方向键和Backspace键失效问题的解决方法
安装的ubuntu默认的编辑器是vi,遇到了两个问题: ① insert模式下,按方向键将产生A.B.C.D等字符,解决方案: :set nocompatible ② insert模式下Backspa ...