http://touchfu.iteye.com/blog/732930

现状:你是不是还在为自己的TestCase代码杂乱无章而苦恼,咎其根本还在于针对不同的用例,输入参数和mock信息的组装全部作为你的程序代码分布在各个单元测试程序中。

期望:因此为了让测试程序更加优雅的显示作为code的本质,我们需要把输入参数和mock内容与程序本身尽可能的达到松耦合的布局,即程序归程序,用例数据归用例数据。

如何:我们怎么来完成这样的一个分离动作呢,下面讲讲本人实现的基本思路。利用JUNIT4中的参数化测试为基础,通过解析文件来初始化参数信息,并对用例提供注销控制。

下面我们着重介绍下实现BaseTestCase.

  1. @RunWith(Parameterized.class)
  2. @ContextConfiguration(locations = {"XXX.xml"})
  3. public class BaseTestCase extends AbstractJUnit4SpringContextTests{
  4. /** 用例ID */
  5. protected String                     caseId;
  6. /** 描述 */
  7. protected String                     description;
  8. /** 期望值 */
  9. protected String                     expectValue;
  10. /** 测试上下文管理 */
  11. private final TestContextManager     testContextManager;
  12. public BaseTestCase(){
  13. this.testContextManager = new TestContextManager(getClass());
  14. this.caseId = caseId;
  15. this.description = description;
  16. this.expectValue = expectValue;
  17. }
  18. /**
  19. * 依靠<code>DependencyInjectionTestExecutionListener<code>完成注入上下文信息
  20. * @throws Throwable
  21. */
  22. @Before
  23. public void injectDependencies() throws Throwable {
  24. this.testContextManager.prepareTestInstance(this);
  25. }
  26. /**
  27. * 获取用例数据
  28. * @param caseFilePath
  29. * @return
  30. */
  31. protected static Collection<String[]> loadCaseData(String caseFilePath) {
  32. if (StringUtil.isBlank(caseFilePath)) {
  33. throw new IllegalArgumentException("未初始化用例文件信息");
  34. }
  35. List<String[]> caseDataList = FileParser.loadItems("cases/" + caseFilePath);
  36. if (CollectionUtils.isEmpty(caseDataList)) {
  37. throw new IllegalArgumentException("准备数据不能为空");
  38. }
  39. // 剔除第一行标题信息
  40. caseDataList.remove(0);
  41. return caseDataList;
  42. }
  43. }

由于在自己基类使用的runner为Parameterized,与使用SpringJUnit4ClassRunner的不同在于少了自动对测试上下文进行依赖注入关联,因此我们需要自己手工触发完成,大家在类源码里可以注意到这一点。主要还是依赖于DependencyInjectionTestExecutionListener完成。同时由于测试基类集成了AbstractJUnit4SpringContextTests了,在此类的源码里可以看到两个关键点DependencyInjectionTestExecutionListener和其中的ApplicationContext,因此我们在子类里不需要再自己写什么上下文的属性,也不需要再添加依赖注入的执行监听器。

下面再看下FileParser的实现

  1. /**
  2. * <p>文件解析器</p>
  3. * @author Eric.fu
  4. */
  5. public class FileParser {
  6. /** 分隔符 */
  7. private static final String SPLIT_TAG  = ",";
  8. /** 忽略标记 */
  9. private static final String IGNORE_TAG = "#";
  10. /**
  11. * 获取文件内容
  12. * @param filePath
  13. * @return
  14. */
  15. public static List<String[]> loadItems(String filePath) {
  16. List<String[]> itemList = new ArrayList<String[]>();
  17. ClassPathResource resource = new ClassPathResource(".");
  18. BufferedReader reader = null;
  19. try {
  20. String path = resource.getFile().getAbsolutePath();
  21. File file = new File(path + "/META-INF/" + filePath);
  22. reader = new BufferedReader(new FileReader(file));
  23. String tempString = null;
  24. // 一次读入一行,直到读入空为文件结束
  25. while (StringUtil.isNotBlank(tempString = reader.readLine())) {
  26. if (tempString.indexOf(IGNORE_TAG) == 0) {
  27. continue;
  28. }
  29. itemList.add(tempString.split(SPLIT_TAG));
  30. }
  31. reader.close();
  32. } catch (IOException e) {
  33. e.printStackTrace();
  34. } finally {
  35. if (reader != null) {
  36. try {
  37. reader.close();
  38. } catch (IOException e1) {
  39. }
  40. }
  41. }
  42. return itemList;
  43. }
  44. }

此类为相当普通的一段读文件的代码,这里有个特殊点在于加了一个忽略标记,用于注释用例数据,即把不跑的数据暂时注释掉,不作为读入参数。

下面再来看下一个简单的测试子类实现

  1. public class SubTestCase extends BaseTestCase {
  2. /** 测试请求 */
  3. protected String            request;
  4. /**
  5. * 构造入款支付清算
  6. */
  7. public SubTestCase(String caseId, String description, String expectValue, String request){
  8. super(caseId, description, expectValue);
  9. this.request = request;
  10. }
  11. @Parameters
  12. public static Collection<String[]> caseData() {
  13. return loadCaseData("case.csv");
  14. }
  15. /**
  16. * 执行
  17. */
  18. @Test
  19. public void execute() {
  20. Assert.notNull(request);
  21. }
  22. }

在子类里通过构造方法初始化参数,参数数据来源为case.csv文件。

文件格式为caseId,description,expectValue,request

本文主要介绍的利用JUNIT4中的参数化测试来完成程序与测试数据的分离,当然如果你用的testNG,则可以用更优雅的provider来完成此项工作。在测试用例中除了让数据与程序分离还是不够的,还需要将mock部分也分离出去,这样才能更好的达到扩展的效果。

Junit4参数化测试实现程序与用例数据分离的更多相关文章

  1. JUnit4参数化测试实例

    在JUnit中,可以同时使用@RunWith 和 @parameter 注解来为单元测试传递参数. 注意: 在Eclipse中因为版本问题,可能无法使用@parameters(name = " ...

  2. 同时使用Junit4的@Parameterized参数化测试和Spring容器

    转载:http://www.jianshu.com/p/d191fe54915f 整合Spring容器 @SpringApplicationConfiguration(classes = Applic ...

  3. 用JUnit4进行参数化测试

    参数化测试是一个JUnit 3不具备的功能. 基本使用方法 @RunWith 当类被@RunWith注解修饰,或者类继承了一个被该注解修饰的类,JUnit将会使用这个注解所指明的运行器(runner) ...

  4. Junit4进行参数化测试

    @RunWith, 当类被@RunWith注解修饰,或者类继承了一个被该注解修饰的类,JUnit将会使用这个注解所指明的运行器(runner)来运行测试,而不是JUnit默认的运行器. 要进行参数化测 ...

  5. 参数化测试与Mock

    参数化测试与Mock 转载自https://blog.csdn.net/sunliduan/article/details/42026509 单元测试概念 说到测试,大家都不会陌生,从我们开始学习编程 ...

  6. 计算某天的下一天:黑盒测试之等价类划分+JUnit参数化测试

    题目要求 测试以下程序:该程序有三个输入变量month.day.year(month.day和year均为整数值,并且满足:1≤month≤12.1≤day≤31和1900≤year≤2050),分别 ...

  7. Google C++单元测试框架GoogleTest---值参数化测试

    值参数化测试允许您使用不同的参数测试代码,而无需编写同一测试的多个副本. 假设您为代码编写测试,然后意识到您的代码受到布尔参数的影响. TEST(MyCodeTest, TestFoo) { // A ...

  8. MSTest不支持参数化测试的解决方案

    之前的项目中做单元测试一直用的是NUnit,这次做新项目,负责人要求统一用MsTest,理由是MsTest是Visual Studio内置的.用就用吧,我没什么意见.不过用了两天,我就发现一个大问题: ...

  9. 参数化测试--sheet表的应用

    自动化测试对录制和编辑好的测试步骤进行回放,这种是线性的自动化测试方式,其缺点是明显的,就是其测试覆盖面比较低.测试回放的只是录制时做出的界面操作,以及输入的测试数据,或者是脚本编辑时指定的界面操作和 ...

随机推荐

  1. 第二章 搭建Android开发环境--读书笔记

    俗话说,工欲善其事,必先利其器,对于Android驱动开发来说,首先我们要做的就是搭建Android开发环境,我们首先要配置Linux驱动的开发环境,接着还得配置开发Android应用程序以及Andr ...

  2. asp.net fileupload上传大文件时提示404.13错误

    IIS 7 默认文件上传大小时30M 要突破这个限制,需要做如下操作: 1. 修改IIS的applicationhost.config     打开 %windir%\system32\inetsrv ...

  3. Makefile拆分编写

    在实际开发项目中,我们通常将一个工程划分为多个文件夹,每个文件夹代表不能的功能,如:我的一个项目cpl,它分为两个文件夹:src和test.当在cpl文件夹中运行make的时候,它的一级目录都会自动运 ...

  4. Java 在指定目录建立指定文件名的文件 并输入内容

    package runoob; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream ...

  5. SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT 'OpenRowset/OpenDatasource' 的访问

    消息 15281,级别 16,状态 1,第 2 行SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT 'OpenRowset/Open ...

  6. iOS开发之APP上线

    APP 上线有两种途径: 一种是 Xcode->openDeveloperTool->applicationLoader,这种打开后登陆appleID就可以选取并且交付您的应用程序了.这种 ...

  7. angular2 笔记

    动态添加一个component: import { ViewContarinerRef, Component, ComponentFactoryResolver, ViewChild } from ' ...

  8. Linux下压缩mp3文件

    apt-get install lame lame -b 64 a.mp3 b.mp3 lame是压缩mp3的一个小工具 参数 -b 64 是输出文件的采样率64 a.mp3 是源文件 b.mp3 是 ...

  9. 前端学习 第三弹: JavaScript语言的特性与发展

    前端学习 第三弹: JavaScript语言的特性与发展 javascript的缺点 1.没有命名空间,没有多文件的规范,同名函数相互覆盖 导致js的模块化很差 2.标准库很小 3.null和unde ...

  10. Kali Linux additional tools setup

    The steps are pretty straight forward. The only tool that might cause some confusion is SMBexec. Thi ...