一个项目能否发布上线,重要的环节就是测试。经过集成测试、性能测试、压力测试等不断循环的测试过后依据测试报告来确定上线。这些由专业的测试人员来完成,因此会导致程序开发者对自身的单元测试的弱化。若在代码中写入那些准备的数据代码片段,会让代码冗余,重用性不高,代码复杂度增加不易阅读,太多繁琐的低效的重复工作等会让开发人放弃这块的开发。
unit-test是基于junit框架 + csv文本结合的测试模板。JUnit 是一个回归测试框架,被开发者用于实施对应用程序的单元测试,加快程序编制速度,同时提高编码的质量。csv可以很方便使用excel来编辑(由于csv是文本结构,所以很多excel中的复杂表达不能兼容也是个麻烦的事)。
既然要作为一个测试模板,那就需要满足以下操作需求:
1、简单便捷的对数据库操作
2、读取封装csv文件的工具方法
3、封装csv数据与DB数据转换
4、转换关联csv、bean、db属性关联
5、断言对比csv、db数据,验证业务流程数据是否正确
测试流程一般分三步:
1、准备业务测试数据;
2、执行需要测试的业务方法接口;
3、校验方法结果
unit-test模板由dbutils + junit + csv组成的。列举几个主要的jar包:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
模板的机制是通过读取csv中准备的before数据,作为测试参数信息。调用被测试接口方法,获得返回的结果信息。然后从csv中after数据中与之对照验证,是否与期望值一致。
unitTest非表字段,只是用来标识这行数据的作用范围。 需要注意点是对应的字段要与数据库的表一致。如果表字段全是大写,此处可以小写程序内有统一转大写的。
依赖注解未使用spring 而是采用java 规范 JSR 330 inject
核心三个类,使用@Named依赖注入:
DbUtilsManager:利用dbutils框架与DB连接操作类,获取QueryRunner及一些简单的查询方法如:toBean,toBeanList。但需要注入数据源DataSource
AssertConvertManager:数据转换类。把csv转成对象、map等结构便于使用。
TestDataManager:加载csv文件并初始化TestDataContext内容和插入准备数据方法。
其它主要类:
AssertUtil:数据对比的工具类
TestDataContext:存储实体,记录表的相关信息(如表名,所有字段列表),csv加载的数据等。
以测试某查询接口为例子,摘取片段代码演示:
1、开发项目依赖引用
pom.xml
<dependency>
<groupId>com.unit</groupId>
<artifactId>unit-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
加载导入配置文件:/unittestConfig/spring-context.xml
2、初始化测试模板,加载测试数据,注入dataSource连接DB。
@PostConstruct
public void case_init() {
dbUtilsManager.setDataSource(dataSource);
queryRunner = dbUtilsManager.getQueryRunner();
if (dataContext== null) {
dataContext= testDataManager.loadDataContext("/csv/accountowner/account_owner.csv");
assertConvertManager.prepareColumnToFieldMapFromCsvAndClass(dataContext.tableName, dataContext.columnNameList, Member.class, null);
}
}
3、准备测试数据,清除相关的数据。
Long[] ids= new Long[] { 1000L };
String sql = "delete from HSDC."+table+" where id = "+ids[0];
queryRunner.update(sql);
testDataManager.putCsvDataToDb(queryRunner, dataContext, ids);
4、执行所测试的业务接口方法
Member member = service.query(ids[0]);
5、校验执行结果与期望值是否一致
Member fromCsv = assertConvertManager.buildDataObjectFromCsv(dataContext.dataBeforeTest.get(ids[0]), new Member(), dataContext.tableName);
AssertUtil.assertDO(fromCsv, member, null);
若想了解更多细节实现,码云地址:https://gitee.com/zss_376987715/unit-test
了解dbutils知识:DBUtils使用入门