`
futurep_p
  • 浏览: 65509 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Junit4参数化测试实现程序与用例数据分离

阅读更多

 

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

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

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

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

 

@RunWith(Parameterized.class)
@ContextConfiguration(locations = {"XXX.xml"})
public class BaseTestCase extends AbstractJUnit4SpringContextTests{
    /** 用例ID */
    protected String                     caseId;
    /** 描述 */
    protected String                     description;
    /** 期望值 */
    protected String                     expectValue;
    /** 测试上下文管理 */
    private final TestContextManager     testContextManager;

    public BaseTestCase(){
        this.testContextManager = new TestContextManager(getClass());
        this.caseId = caseId;
        this.description = description;
        this.expectValue = expectValue;
    }

    /**
     * 依靠<code>DependencyInjectionTestExecutionListener<code>完成注入上下文信息
     * @throws Throwable
     */
    @Before
    public void injectDependencies() throws Throwable {
        this.testContextManager.prepareTestInstance(this);
    }

    /**
     * 获取用例数据
     * @param caseFilePath
     * @return
     */
    protected static Collection<String[]> loadCaseData(String caseFilePath) {
        if (StringUtil.isBlank(caseFilePath)) {
            throw new IllegalArgumentException("未初始化用例文件信息");
        }
        List<String[]> caseDataList = FileParser.loadItems("cases/" + caseFilePath);
        if (CollectionUtils.isEmpty(caseDataList)) {
            throw new IllegalArgumentException("准备数据不能为空");
        }
        // 剔除第一行标题信息
        caseDataList.remove(0);

        return caseDataList;
    }
}

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

  下面再看下FileParser的实现

 

/**
 * <p>文件解析器</p>
 * @author Eric.fu
 */
public class FileParser {
    /** 分隔符 */
    private static final String SPLIT_TAG  = ",";
    /** 忽略标记 */
    private static final String IGNORE_TAG = "#";

    /**
     * 获取文件内容
     * @param filePath
     * @return
     */
    public static List<String[]> loadItems(String filePath) {
        List<String[]> itemList = new ArrayList<String[]>();
        ClassPathResource resource = new ClassPathResource(".");
        BufferedReader reader = null;
        try {
            String path = resource.getFile().getAbsolutePath();
            File file = new File(path + "/META-INF/" + filePath);
            reader = new BufferedReader(new FileReader(file));

            String tempString = null;
            // 一次读入一行,直到读入空为文件结束
            while (StringUtil.isNotBlank(tempString = reader.readLine())) {
                if (tempString.indexOf(IGNORE_TAG) == 0) {
                    continue;
                }
                itemList.add(tempString.split(SPLIT_TAG));
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }

        return itemList;
    }
}

 

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

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

 

public class SubTestCase extends BaseTestCase {
    /** 测试请求 */
    protected String            request;
    /**
     * 构造入款支付清算
     */
    public SubTestCase(String caseId, String description, String expectValue, String request){
        super(caseId, description, expectValue);
        this.request = request;
    }
 
    @Parameters
    public static Collection<String[]> caseData() {
        return loadCaseData("case.csv");
    }

    /**
     * 执行
     */
    @Test
    public void execute() {
        Assert.notNull(request);
    }
}
 

 

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

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

 

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

分享到:
评论

相关推荐

    feed4junit源码

    Feed4JUnit能够让编写JUnit的参数化测试变得简便,并为这些测试提供预定义或随机测试数据。它能够从业务分析人员定义好的CVS或 Excel文件读取测试用例数据并在构建/单元测试框架中报告测试成功。利用Feed4JUnit能够...

    基于JUnit4的关于个人所得税计算的等价类与边界值分析黑盒测试和路径覆盖白盒测试

    本文档中源码为软件测试课程实验相关内容,压缩包内也有详细需求说明。大致功能为测试一个输入为税前工资输出为税后工资的方法的单元测试,通过设计测试用例实现等价类划分测试,边界值分析测试以及路径覆盖测试

    junit(单元测试)入门

    ★测试夹具:(Test Fixture):就是测试运行程序会在测试方法之前自动初始化、回收资源的工作。 Junit4引入的是类级别的夹具,编写规范如下: ①创建测试用例的实例 ②使用注解BeforeClass修饰用于初始化夹具的方法 ...

    Junit单元测试所需要的两个jar包

    每个单元测试用例相对独立,由Junit 启动,自动调用。不需要添加额外的调用语句。 添加,删除,屏蔽测试方法,不影响其他的测试方法。 开源框架都对JUnit 有相应的支持。 4 测试方法注意事项 必须是public修饰的,...

    单元测试实战-Junit测试

    本文来自于cnblogs,本文主要介绍了没有junit工具下如何测试...是一套基于java的测试框架,目前有两个版本:Junit3,Junit4.Junit中最常用的两个测试方法是:assertEquals(expect,actual);用于非数组型的数据的比较;

    软件测试之单元测试和自动化测试及UTF应用

    (2)基于Junit5完成单元测试(至少基本测试与参数化测试) 2. 以下为JDK中ArrayList的remove()方法,请应用白盒测试方法设计测试用例,并应用JUnit5完成测试。要求:(1)完成分别满足语句覆盖、判定覆盖、条件...

    Junit4教程

    关于Junit4的教程,简单实用。里面介绍junit4与以前版本的比较优势,一个例子来演示创建测试用例,说明一些测试框架细节,以及方便使用的参数化测试。

    Unit-Testing-with-JUnit:使用JUnit测试一组方法(最大和总和)

    用JUnit进行单元测试使用JUnit测试一组方法(最大和总和)要求完整的NumberUtil.java 使用流实现max和sum方法。 在这些方法中,如果列表为空,则引发异常。编写一个JUnit测试类 在您的系统上安装JUnit。 通过使用...

    基于jmeter+Java+HttpclientUtil实现的接口测试工具

    基于jmeter+Java+HttpclientUtil实现的接口测试工具,通过Excel表格进行维护接口相关参数信息,借助Jmeter工具通过java请求设计接口测试自动化测试用例。代码重写了JavaSampleClient类,在使用过程中取出了冗余的...

    追求代码质量:JUnit4与TestNG的对比

    表面上的相似依赖性测试失败和重运行参数化测试高级参数化测试为什么只选择其一?JUnit4具有基于注释的新框架,它包含了TestNG一些最优异的特性。但这是否意味着JUnit4已经淘汰了TestNG?AndrewGlover探讨了这两种...

    Python自动化测试框架之pytest详解

    学习pytest的安装、配置,pytest fixture的使用,pytest的高阶用法如跳过测试函数、标记为预期失败函数、函数数据参数化、修改 Python traceback 输出、执行失败的时候跳转到 PDB、设置断点、获取用例执行性能数据、...

    xalanjava源码-Eclipse-Preferences:EclipseIDE的各种首选项

    参数化测试提供数据。 test :声明一个 JUnit 4 测试方法。 jMock 模板 context : 声明一个Mockery实例。 expectations :声明用于指定期望的上下文。 mock :声明一个模拟实例。 rv :声明一个模拟的返回值。 ...

    基于springboot框架的网上商城系统的设计与实现.zip

    测试用例:可能会有一些JUnit或Spring Boot Test的测试用例,用于验证系统的功能和性能。部署说明:虽然不包含安装步骤,但可能会提供如何将应用部署到服务器上的简要指南或建议。这个资源包是为了帮助开发者快速...

    Spring.3.x企业应用开发实战(完整版).part2

    17.5.4 编写BoardDao测试用例 17.6 服务层开发 17.6.1 UserService的开发 17.6.2 ForumService的开发 17.6.3 服务类Bean的装配 17.7 对服务层进行测试 17.7.1 编写Service测试基类 17.7.2 编写ForumService测试用例 ...

    TestNG测试框架(Author: Coast)

    TestNG是一个开源的自动化测试框架,它受JUnit框架启发而实现的,TestNG可以让开发者和测试者能够通过简单的注解、分组、指定顺序、参数化就可以编写更加灵活、更加强大的测试用例。 TestNG可以跟web自动化框架...

    Spring3.x企业应用开发实战(完整版) part1

    17.5.4 编写BoardDao测试用例 17.6 服务层开发 17.6.1 UserService的开发 17.6.2 ForumService的开发 17.6.3 服务类Bean的装配 17.7 对服务层进行测试 17.7.1 编写Service测试基类 17.7.2 编写ForumService测试用例 ...

    visible-assertions:JUnit断言的替代方案,可为您的测试提供更深入的日志描述

    Visible Assertions被设计用来代替标准的JUnit Assert类,从而提供了许多核心assert*方法的实现。 每个方法都带有一个附加参数,开发人员可以使用该参数来确切描述断言正在检查的内容。 关键区别在于,每个断言还...

    libcester:针对C和C ++编程语言的健壮的仅标头单元测试框架。 支持功能模拟,内存泄漏检测,崩溃报告

    允许共享实例TestInstance对象,每个测试用例均可在其中共享数据和访问命令行参数。 # include CESTER_TEST (test_one, inst, cester_assert_equal ( NULL , (( void *)0)); ) 测试结果可以输出为各种格式的...

Global site tag (gtag.js) - Google Analytics