上篇文章罗列了整个框架的核心接口,这篇文章将提供IunitExecutionListener的一个实现类-DatasetProviderListener,主要用来将测试数据插入到数据库中,待测试完成后自动删除数据
1.dbunit为核心的db测试
dbunit是个很好的数据库测试框架,提供了多种准备数据的操作策略来简化测试数据的插入或更新操作,参考http://www.dbunit.org/components.html#deleteall
操作 | 描述 |
---|---|
DatabaseOperation.UPDATE | 使用准备数据更新现有db中的数据(根据准备数据主键ID值),如果数据库中不存在准备数据中的ID,报错退出 |
DatabaseOperation.INSERT | 将测试数据插入到数据库中,如果数据库中已经有对应id的数据,则报错退出 |
DatabaseOperation.DELETE | 删除数据库中id在准备数据中的记录 |
DatabaseOperation.DELETE_ALL | 删除准备数据中相关的数据库表中的所有数据 |
DatabaseOperation.TRUNCATE | 删除准备数据中相关的数据库表中的所有数据 |
DatabaseOperation.REFRESH | 先根据准备数据中的id查询数据库,如果有对应的记录则更新,若无则插入新记录 |
DatabaseOperation.CLEAN_INSERT | 先做一个DELETE_ALL,然后做一个INSERT操作 |
DatabaseOperation.NONE | 什么也不做处理 |
2.@IUnitDataSet注解
我们的dbunit只对那些需要用到数据库测试的类才加载,这里用这个注解来标识(后期我们可以对这个注解进行扩展,如添加filename和format字段,前者表示测试文件名,后者表示文件格式,比如我们后期可能提供以excel格式来准备测试数据)
3.约定
这里框架默认要求测试类和测试类的准备数据放在同一级目录下,如类的路径为com.crazycoder2010.iunit.AppTest.java则其测试数据文件为com/crazycoder2010/iunit/AppTest.xml框架会自动去加载,同时因为需要链接数据库,因此需要配置数据库的jdbc,username,password等,这里要求程序提供一个iunit.properties文件放置在classpath下
##configuration for dbunit dbunit.connectionUrl=jdbc:hsqldb:hsql://localhost/ dbunit.driverClass=org.hsqldb.jdbcDriver dbunit.password= dbunit.username=sa dbunit.schema=4.DatasetProviderListener类的源码
package com.crazycoder2010.iunit; import java.io.IOException; import java.util.Properties; import org.dbunit.IDatabaseTester; import org.dbunit.JdbcDatabaseTester; import org.dbunit.PropertiesBasedJdbcDatabaseTester; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; import org.dbunit.operation.DatabaseOperation; import com.crazycoder2010.iunit.annotation.IUnitDataSet; /** * 用来加载测试数据到db中 * * @author Kevin * */ public class DatasetProviderListener extends IUnitTestExecuteListenerAdapter { private IDatabaseTester databaseTester; private boolean handleDataSet = true;//标志位,表示当前测试类是否启用了@IUnitDataset标注,如果没用,不做数据库插入删除操作 private static final Properties PROPERTIES = new Properties(); static { try { PROPERTIES.load(DatasetProviderListener.class .getResourceAsStream("/iunit.properties")); } catch (IOException e) { e.printStackTrace(); } } private Object testInstance; /** * 将Excel中的测试数据插入到数据库中 * @throws Exception * * @see com.crazycoder2010.iunit.IUnitTestExecuteListenerAdapter#prepareTestInstance(com.crazycoder2010.iunit.TestContext) */ @Override public void prepareTestInstance(TestContext testContext) throws Exception {
IUnitDataSet dataset = testContext.getTestInstance().getClass().getAnnotation(IUnitDataSet.class); if(dataset == null){ handleDataSet = false; return; } this.testInstance = testContext.getTestInstance(); databaseTester = new JdbcDatabaseTester(//创建数据库链接对象 PROPERTIES .getProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS), PROPERTIES .getProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL), PROPERTIES .getProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME), PROPERTIES .getProperty(PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD)); } @Override public void beforeTest(TestContext testContext) throws Exception { if(!handleDataSet){ return; }//测试开始前将数据插入到db databaseTester.setDataSet(getDataSet()); databaseTester.setSetUpOperation(DatabaseOperation.REFRESH); databaseTester.onSetup(); } //测试数据文件和测试类之间的‘潜规则’ protected IDataSet getDataSet() throws Exception { String pack = testInstance.getClass().getName() ; String filePath = "/"+pack.replaceAll("[.]", "/")+ ".xml"; return new FlatXmlDataSetBuilder().build(this.getClass().getResourceAsStream(filePath)); } /** * 将文件中准备的测试数据从数据库中清空 * * @throws Exception * @see com.crazycoder2010.iunit.IUnitTestExecuteListenerAdapter#afterTest(com.crazycoder2010.iunit.TestContext) */ @Override public void afterTest(TestContext testContext) throws Exception { if(!handleDataSet){ return; } databaseTester.setTearDownOperation(DatabaseOperation.DELETE); databaseTester.onTearDown(); } }