`
jgsj
  • 浏览: 962099 次
文章分类
社区版块
存档分类
最新评论

一个通用的单元测试框架的思考和设计02-设计篇

 
阅读更多

第一节里介绍了我们框架设计的目标,这篇主要介绍的是这个框架主要的设计思路和关键技术点

1.如何扩展junit的功能,使junit在启动时可以做一些我们定制化的功能?

junit4建立了以Runner为核心的测试框架运行机制,在junit3的版本中,我们知道要运行一个junit测试用例,必须继承一个TestCase基类,junit4则不需要这个限制,只需要标注一下要运行测试的方法为@Test就可以了,怎么做到的呢?就是这个Runner机制,这里不介绍Junit4的运行机制,可以从org.junit.runner.BlockJUnit4ClassRunner中得到答案,像spring test框架也是扩展了这个类的功能来达到扩展目的的

2.如何让junit4框架提供更多的自定义注解的功能?

junit4提供了诸如@Test,@BeforeClass,@Before等注解来简化单元测试过程,在我们这个通用框架的设计中,我们系统提供更多自己定制的注解来扩展junit的功能,如我们希望提供一个@DataSet注解,当测试类有此注解时,框架自动解释这个注解,并把当前类同级目录下加载与类名相同的xsl文件,该文件里存放的是该单元测试类的准备数据,这样就能解决上一节中提到的测试文件和测试类之间约束的目的,开发只需要关注准备数据和写测试类,其他的事情都交给框架去搞吧,通过跟踪Junit的源码我们不难看出单元测试类的执行要经过Object createTest()方法(测试框架加载测试类)和Statement methodInvoker(FrameworkMethod method, Object test)(执行测试方法),这样我们就可以通过扩展BlockJUnit4ClassRunner类通过覆写这两个方法,让其支持我们更多的功能特性

3.回顾一个测试用例的测试过程

一个测试用例的执行大约可以包含这样几个步骤,在创建测试实例后,测试方法前,测试方法执行后,测试方法抛出异常后,因此我们可以根据这些功能定义一个统一接口IUnitTestExecuteListener,接口里定义这4个方法

prepareTestInstance --创建测试实例后

beforeTest --测试方法前

afterTest -测试方法执行后

afterThrowable -测试方法抛出异常后

这样对于不同的功能扩展,我们只需要提供相应的子类即可,如我们前面提到的那个@DataSet注解的方式来加载测试数据准备文件,就可以提供一个ExcelDataProviderListener类,只要在其prepareTestInstance 方法里把测试文件内容读出来,插入到数据库中即可-so easy!,对于要进行事务控制的测试方法@Transactional标签,我们也可以提供一个实现类来实现事务控制的目的--这样对于框架而言,新功能的扩展只需要添加对应的子类即可,体现了软件设计的‘开-闭’原则

4.框架执行流程图

解释:IUnit是我们为这个通用框架YY的名字:)

从这张流程图上可以看出,IunitRunner和IUnitTestExecutionListener是我们整个框架的核心,一个Runner有多个Listener,当测试的生命周期开始后,runner会循环调用已注册listener的prepareTestInstance ,beforeTest ,afterTest ,afterThrowable 方法执行对应的功能


5.详细设计-类图

解释:整个框架最核心的类和接口只有三个IunitRunner,这个是运行的切入点,用来注册每个测试类指定的listener(通过寻找测试中上的@IUnitTestExecuteListeners标注),所有的功能扩展都是围绕IUnitTestExecuteListener展开,如类图中描述的GuiceStrapupListener用来启动guice容器,DataProviderListener用来加载测试准备数据


6.千呼万唤始出来-最终的测试用例长什么样子

对于最终使用框架的开发者而言,根据自身需要通过注解来动态加载所需要的listener即可(可以指定多个),注意测试用例上要加个@RunWith标注,指定要执行的runner为IunitRunner这样junit框架才能用我们提供的runner来运行,实际使用的时候这些东东可以都放到一个测试父类中去完成,开发者只需要关注自身用到的listener即可

package com.crazycoder2010.iunit;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

import org.junit.Test;
import org.junit.runner.RunWith;

import com.crazycoder2010.iunit.annotation.IUnitDataSet;
import com.crazycoder2010.iunit.annotation.IUnitTestExecuteListeners;

@IUnitDataSet(dbunitFile="AppTest.xml")
@RunWith(IUnitRunner.class)
@IUnitTestExecuteListeners({TransactionalListener.class,DatasetProviderListener.class})
public class AppTest extends AbstractIUnitTestCase {
	@Test
	public void testHello(){
		assertThat("hello", equalTo("hello"));
	}
}


分享到:
评论

相关推荐

    性能测试从零开始:LoadRunner入门与提升

    12.1.2 Automation Center性能测试框架设计实例 319 12.1.3 定义XML格式的性能测试任务文件 325 12.1.4 Automation Center性能测试调度运行 329 12.1.5 性能测试报告诊断系统 330 12.2 核心技术及具体实现方法 332 ...

    asp.net知识库

    DbHelperV2 - Teddy的通用数据库访问组件设计和思考 也论该不该在项目中使用存储过程代替SQL语句 如何使数据库中的表更有弹性,更易于扩展 存储过程——天使还是魔鬼 如何获取MSSQLServer,Oracel,Access中的数据字典...

    java 编程入门思考

    15.2.1 一个简单的服务器和客户机程序 15.3 服务多个客户 15.4 数据报 15.5 一个Web应用 15.5.1 服务器应用 15.5.2 NameSender程序片 15.5.3 15.5.3 要注意的问题 15.6 Java与CGI的沟通 15.6.1 CGI数据的编码 15.6.2...

    软件设计规范

    如果我们所说非虚,那么如何为架构下一个定义-一定是一个由具体业务流量和模式支撑的架构) 软件(算法)的构造。一个是数据的复杂性(内在互相关系),一个是计算方法(步骤和缓冲)。从宏观角度,数据关系是更...

    信息架构:超越Web设计(第4版)(全彩).[美]Louis Rosenfeld(带详细书签) PDF 下载 高清 完整版

    为了引导你通过这个广阔的生态系统,本书为数字设计提供了经得起时间考验的基本概念、方法和技术。用户体验设计师、产品经理、开发人员和数字设计中涉及的所有人,都要学习如何创建帮助人们与你的信息进行交互的语义...

    传智播客扫地僧视频讲义源码

    15_信息系统框架集成第三方产品案例_框架实现第一个socket类厂商实现 16_信息系统框架集成第三方产品案例_第二个socket类厂商实现 17_信息系统框架集成第三方产品案例_加解密抽象类和加解密厂商类实现 18_信息系统...

    信息架构 超越Web设计(第4版).pdf

    其中描述了信息组织的普遍和永恒原则,这一原则也适用于不断增长的移动世界。在第4版中,作者运用大量最新的插图和例子为这些原则提供了当前实践中的情境,验证了那些与技术和供应商无关的工具,以及那些经受住时间...

    AFC.SocketNet项目基于TCP协议高并发多线程协议可配置的通迅模块.zip

    这项任务通常要求学生运用所学专业知识,通过独立研究和创新,完成一个实际问题的解决方案或者开展一项有价值的项目。 首先,毕业设计的选择通常由学生根据个人兴趣、专业方向以及实际需求来确定。学生需要在导师的...

    cascades:Go 中与语言无关的基于流的编程 (FBP) 框架

    Cascades 是一个通用编程框架,但我们创建了它,正如 JP Morrison 所描述的那样:一个数据工厂心理形象,其中应用程序表示为对数据流的一系列转换——这需要根本性的改变从老冯诺依曼程序员构建应用程序的方式思考。...

    Perl最佳实践(中文版).pdf

    《Perl最佳实践》讲述了许多关于Perl语言的编程规则、使用惯例、开发标准和最佳实践,这些内容不仅有助于程序员之间的交流和协同工作,同时也提供了一套思考问题的可靠框架和一种表述解决方案的通用语言。...

    Perl最佳实践 中文版

    《perl最佳实践》讲述了许多关于perl语言的编程规则、使用惯例、开发标准和最佳实践,这些内容不仅有助于程序员之间的交流和协同工作,同时也提供了一套思考问题的可靠框架和一种表述解决方案的通用语言。...

    Perl 最佳实践(CHM)

    《Perl最佳实践》讲述了许多关于Perl语言的编程规则、使用惯例、开发标准和最佳实践,这些内容不仅有助于程序员之间的交流和协同工作,同时也提供了一套思考问题的可靠框架和一种表述解决方案的通用语言。...

    Scala程序设计(第2版)

    19.1 一个较为激进的示例:Ruby on Rails框架中的ActiveRecord库 396 19.2 使用动态特征实现Scala 中的动态调用 397 19.3 关于DSL的一些思考 402 19.4 本章回顾与下一章提要 402 第20章 Scala的领域...

    Perl最佳实践

    《Perl最佳实践》讲述了许多关于Perl语言的编程规则、使用惯例、开发标准和最佳实践,这些内容不仅有助于程序员之间的交流和协同工作,同时也提供了一套思考问题的可靠框架和一种表述解决方案的通用语言。...

    行为驱动开发在Python开发测试中的应用

    基于这一思想,本文以Linux平台为基础,图文并茂的解析了其应用于Python的开发测试过程,并给出了Python语言Lettuce测试框架搭建的详细步骤。既有助于用户形象理解BDD理论,又对Python学习者有很好的借鉴意义。说到...

    PersonalBlog

    学习了著名开源社区CommunityServer(CS)的抽象数据库的设计,自己独立思考,站在哲学的角度上思考问题,并进一步抽象,最终设计出了一套非常抽象的通用数据库以及通用数据访问层。主要有以下优点:1)通过两个抽象...

    c#学习笔记.txt

    /* 你能看得出来,这不是一篇正规的技术文章,所以若你不小心从里边读到了一个爱情故事,可不要奇怪。有很多人用程序来表述爱情,在其中我能看到有Money,有Girl,有一些还涉及到Sex,但是我没有找到Love,我始终相信...

    【卷一/共两卷】AJAX实战pdf高清版90M

    第一部分 重新思考Web应用 第1章 一种新的Web设计方法 1.1 为什么需要Ajax富客户端? 1.1.1 比较用户体验 1.1.2 网络延迟 1.1.3 异步交互 1.1.4 独占或瞬态的使用模式 1.1.5 忘掉Web 1.2 Aiax的四个基本原则 1.2.1 ...

Global site tag (gtag.js) - Google Analytics