- 浏览: 3470818 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
wanglf1207:
EJB的确是个不错的产品,只是因为用起来有点门槛,招来太多人吐 ...
weblogic-ejb-jar.xml的元素解析 -
qwfys200:
总结的不错。
Spring Web Flow 2.0 入门 -
u011577913:
u011577913 写道也能给我发一份翻译文档? 邮件437 ...
Hazelcast 参考文档-4 -
u011577913:
也能给我发一份翻译文档?
Hazelcast 参考文档-4 -
songzj001:
DbUnit入门实战
相信做过单元测试的人都会对JUnit 非常的熟悉了,今天要介绍的DbUnit(http://dbunit.sourceforge.net/ ) 则是专门针对数据库测试的对JUnit 的一个扩展,它可以将测试对象数据库置于一个测试轮回之间的状态。鉴于目前国内介绍DbUnit 的系统教程比较少见,本文将分从理论和实例两个方面带你领略DbUnit 的精彩世界。
DbUnit
设计理念
熟悉单元测试的开发人员都知道,在对数据库进行单元测试时候,通常采用的方案有运用模拟对象(mock
objects)
和stubs
两种。通过隔离关联的数据库访问类,比如JDBC
的相关操作类,来达到对数据库操作的模拟测试。然而某些特殊的系统,比如利用了EJB
的CMP(container-managed persistence)
的系统,数据库的访问对象是在最底层而且很隐蔽的,那么这两种解决方案对这些系统就显得力不从心了。
DBUnit
的设计理念就是在测试之前,备份数据库,然后给对象数据库植入我们需要的准备数据,最后,在测试完毕后,读入备份数据库,回溯到测试前的状态;
而且又因为DBUnit
是对JUnit
的一种扩展,开发人员可以通过创建测试用例代码,在这些测试用例的生命周期内来对数据库的操作结果进行比较。
DbUnit
测试基本概念和流程
基于DbUnit
的测试的主要接口是IDataSet
。IDataSet
代表一个或多个表的数据。
可以将数据库模式的全部内容表示为单个IDataSet
实例。这些表本身由Itable
实例来表示。
IDataSet
的实现有很多,每一个都对应一个不同的数据源或加载机制。最常用的几种 IDataSet
实现为:
FlatXmlDataSet
:数据的简单平面文件 XML
表示
QueryDataSet
:用 SQL
查询获得的数据
DatabaseDataSet
:数据库表本身内容的一种表示
XlsDataSet
:数据的excel
表示
一般而言,使用DbUnit
进行单元测试的流程如下:
1
根据业务,做好测试用的准备数据和预想结果数据,通常准备成xml
格式文件。
2
在setUp()
方法里边备份数据库中的关联表。
3
在setUp()
方法里边读入准备数据。
4
对测试类的对应测试方法进行实装:
执行对象方法,把数据库的实际执行结果和预想结果进行比较。
5
在tearDown()
方法里边,
把数据库还原到测试前状态。
DbUnit
开发实例
下面通过一个实例来说明DbUnit
的实际运用。
实例准备
比如有一个学生表[student]
,结构如下:
--------------------------------------------------------------------------------
id char(4) pk
学号
name char(50)
姓名
sex char(1)
性别
birthday date
出生日期
--------------------------------------------------------------------------------
准备数据如下:
--------------------------------------------------------------------------------
id name sex birthday
0001
翁仔 m 1979-12-31
0002
王翠花 f 1982-08-09
--------------------------------------------------------------------------------
测试对象类为StudentOpe.java
,里边有2
个方法:
findStudent(String id) :
根据主键id
找记录
addStudent(Student student)
:添加一条记录
在测试addStudent 方法时候,我们准备添加如下一条数据
--------------------------------------------------------------------------------
id name sex birthday
0088
王耳朵 m 1982-01-01
--------------------------------------------------------------------------------
那么在执行该方法后,数据库的student
表里的数据是这样的:
--------------------------------------------------------------------------------
id name sex birthday
0001
翁仔 m 1979-12-31
0002
王翠花 f 1982-08-09
0088
王耳朵 m 1982-01-01
--------------------------------------------------------------------------------
然后我们说明如何对这2 个方法进行单元测试。
实例展开
1
把准备数据和预想数据转换成xml
文件
student_pre.xml
--------------------------------------------------------------------------------
<?xml version='1.0' encoding="gb2312"?>
<dataset>
<student id="0001" name="
翁仔" sex="m" birthday="1979-12-31"/>
<student id="0002" name="
王翠花"
sex="f" birthday="1982-08-09"/>
</dataset>
--------------------------------------------------------------------------------
student_exp.xml
--------------------------------------------------------------------------------
<?xml version='1.0' encoding="gb2312"?>
<dataset>
<student id="0001" name="
翁仔" sex="m" birthday="1979-12-31"/>
<student id="0002" name="
王翠花"
sex="f" birthday="1982-08-09"/>
<student id="0088" name="
王耳朵"
sex="m" birthday="1982-01-01"/>
</dataset>
--------------------------------------------------------------------------------
2 实装setUp 方法,详细见代码注释。
--------------------------------------------------------------------------------
protected void setUp() {
IDatabaseConnection connection =null;
try{
super.setUp();
//
本例使用postgresql
数据库
Class.forName("org.postgresql.Driver");
//
连接DB
Connection conn=DriverManager.getConnection("jdbc:postgresql:testdb.test","postgres","postgres");
//
获得DB
连接
connection =new DatabaseConnection(conn);
//
对数据库中的操作对象表student
进行备份
QueryDataSet backupDataSet = new QueryDataSet(connection);
backupDataSet.addTable("student");
file=File.createTempFile("student_back",".xml");//
备份文件
FlatXmlDataSet.write(backupDataSet,new FileOutputStream(file));
//
准备数据的读入
IDataSet dataSet = new FlatXmlDataSet( new
FileInputStream("student_pre.xml"));
DatabaseOperation.CLEAN_INSERT.execute(connection,dataSet);
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(connection!=null) connection.close();
}catch(SQLException e){}
}
}
--------------------------------------------------------------------------------
3
实装测试方法,详细见代码注释。
* 检索类方法,可以利用assertEquals() 方法,拿表的字段进行比较。
--------------------------------------------------------------------------------
// findStudent
public void testFindStudent() throws Exception{
//
执行findStudent
方法
StudentOpe studentOpe=new StudentOpe();
Student result = studentOpe.findStudent("0001");
//
预想结果和实际结果的比较
assertEquals("
翁仔",result.getName());
assertEquals("m",result.getSex());
assertEquals("1979-12-31",result.getBirthDay());
}
--------------------------------------------------------------------------------
* 更新,添加,删除等方法,可以利用Assertion.assertEquals() 方法,拿表的整体来比较。
--------------------------------------------------------------------------------
public void testAddStudent() throws Exception{
//
执行addStudent
方法
StudentOpe studentOpe=new StudentOpe();
//
被追加的记录
Student newStudent = new Student("0088","
王耳朵","m","1982-01-01");
//
执行追加方法
Student result = studentOpe.addStudent(newStudent);
//
预想结果和实际结果的比较
IDatabaseConnection connection=null;
try{
//
预期结果取得
IDataSet expectedDataSet = new FlatXmlDataSet(new
FileInputStream("student_exp.xml"));
ITable expectedTable = expectedDataSet.getTable("student");
//
实际结果取得
Connection conn=getConnection();
connection =new DatabaseConnection(conn);
IDataSet databaseDataSet = connection.createDataSet();
ITable actualTable = databaseDataSet.getTable("student");
//
比较
Assertion.assertEquals(expectedTable, actualTable);
}finally{
if(connection!=null) connection.close();
}
}
--------------------------------------------------------------------------------
*
如果在整体比较表的时候,有个别字段不需要比较,可以用DefaultColumnFilter.excludedColumnsTable()
方法,
将指定字段给排除在比较范围之外。比如上例中不需要比较birthday
这个字段的话,那么可以如下代码所示进行处理:
--------------------------------------------------------------------------------
ITable filteredExpectedTable =
DefaultColumnFilter.excludedColumnsTable(expectedTable, new
String[]{"birthday"});
ITable filteredActualTable = DefaultColumnFilter.excludedColumnsTable(actualTable,new
String[]{"birthday"});
Assertion.assertEquals(filteredExpectedTable, filteredActualTable);
--------------------------------------------------------------------------------
4 在tearDown() 方法里边, 把数据库还原到测试前状态
--------------------------------------------------------------------------------
protected void tearDown() throws Exception{
IDatabaseConnection connection =null;
try{
super.tearDown();
Connection conn=getConnection();
connection =new DatabaseConnection(conn);
IDataSet dataSet = new FlatXmlDataSet(file);
DatabaseOperation.CLEAN_INSERT.execute(connection,dataSet);
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(connection!=null) connection.close();
}catch(SQLException e){}
}
}
<property name="dbUrl" value="jdbc:oracle:thin:@192.168.104.47:1521:esample" />
<property name="dbUser" value="esample" />
<property name="dbPassword" value="esample" />
<property name="operation" value="CLEAN_INSERT" />
<property name="file" value="partial.xml" />
<dbunit driver="${dbDriver}" url="${dbUrl}"
userid="${dbUser}" password="${dbPassword}">
<operation type="${operation}" src="${file}" format="xml" />
</dbunit>
</target>
<dbunit driver="${dbDriver}" url="${dbUrl}" userid="${dbUser}" password="${dbPassword}">
<export dest="partial.xml" format="xml">
<query name="QueryExhibtion" sql="SELECT Exhibition_Id FROM Ex_exhibition " />
<table name="ex_exhibition" />
</export>
</dbunit>
</target>
</project>
发表评论
-
Fitnesse使用
2012-05-05 13:27 23421Fitnesse 的使用 一,介绍 Fitnesse是一种 ... -
Customizing the new FitNesse parser
2012-05-05 13:13 2090FitNesse began its life using ... -
单元测试------理论篇
2011-03-12 12:20 1622测试是软件开发的重要 ... -
一个愚蠢农夫和奶牛的故事-转载
2011-03-07 09:20 1732Ivar Jacobson博士 ... -
Web测试工具Selenium入门心得
2011-02-16 23:50 34182009-02-05 ... -
selenium 和webdriver_入门实践
2011-02-16 23:47 8935我们一直非常强调建立以底层为核心的分层自动化测试 ... -
VPS服务器性能压力测试工具(转载)
2010-12-01 23:35 3212VPS服务器性能 压力测试工具 http_load、webb ... -
软件测试工具英雄榜
2010-08-24 11:12 4997几乎毫无悬念地, ... -
净室软件认证
2010-05-16 22:20 1551软件测试 的统计方 ... -
SVN—patch的应用
2010-03-07 14:43 26661.create patch 使用create ... -
diff和patch十分钟指南
2010-03-07 14:10 2664情景一:你正尝试从代码编译一个软件包,发现有人已经对代码进行了 ... -
patch用法(转)
2010-03-07 14:08 9111首先介绍一下 diff 和 patch 。 ... -
补丁Patch
2010-03-07 14:04 3085补丁Patch是天才程序员、Perl的发明者Larry ... -
开源性能测试工具Curl-Loader
2010-02-28 14:52 4832curl-loader 是一个用C语言 编写的Web 应用 ... -
用 easyb 驱动开发
2009-01-03 22:25 2182长期以来,定义需求 ... -
亲身体验行为驱动开发
2009-01-03 22:17 7045开始学习使用 JBehave 测试驱动的开发(TDD)在实践 ... -
软件测试之测试策略
2009-01-03 22:05 3442第一部分 软件测试 策略基础 为什么要编写测试策 ... -
自动化测试框架模型SAFS
2009-01-03 22:00 2567SAFS(Software A ... -
探索 JUnit 4.4 新特性
2008-12-22 18:34 2075随着当前 Java 开发的越发成熟,Agile 和 T ... -
Hamcrest指南
2008-12-22 18:22 26838Hamcrest 官方网站 Hamcrest Tutor ...
相关推荐
用dbunit的两个例子,很不错,有帮助
dbunit入门实例 dbunit入门实例 dbunit入门实例 dbunit入门实例
最新的最全的dbunit jar包以及入门教程
DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类...
dbunit-2.4.9 源码 http://www.dbunit.org/apidocs/index.html 代码 API
DBUNIT使用的详细文档
单元测试入门学习,和dbunit结合开发
dbunit的jar包,版本2.2
Junit,dbunit单元测试jar包
dbunit开发文档,供需要用dbunit进行开发的人使用
dbunit2.2完全包 数据库单元测试
Dbunit 基本原理就是在跑测试用例运行之前对数据表做用户定义的操作,清空不想要的数据,插入用户自定义的数据,使得该数据表处于用户知道的一种状态。而用户自定义的数据使用项目里的一个 xml 文件来表示。 Xml ...
dbunit-2.2.3..jar dbunit-2.4.2.jar dbunit-2.5.3.jar dbunit-2.7.0.jar 发现每个版本对JDK是有要求的,比如2.7 只能用于JDK1.8版本,所以整理好几个jar包挑选适合自己的
文档是关于DBUnit的ant的使用文档,通俗易懂
一个很好的DBUnit的例子 博文链接:https://virgoooos.iteye.com/blog/186859
直接从http://www.dbunit.org/apidocs/index.html上下载的HTML文件的压缩包。 因为没有做成CHM,所以只要1分就行~
dbunit使用必需Jar包,总共4个必需Jar包
dbunit-2.4.2.jar dbunit 必要的一个jar
dbunit是一个基于junit扩展的数据库测试框架。 更多资源详见: http://blog.csdn.net/fanxiaobin577328725/article/details/51894331 (包含图书各部分和随书源码,还有其它资源的详细下载地址)