介绍:
背景:
数据库相关的单元测试一直是单元测试中最令人头疼的问题,虽然dbunit在这一领域已经比较强大,但是依然有很多的缺陷。
1、数据的准备繁琐
无论是xml、xls、cvs还是sql,准备数据起来都不尽如人意
2、数据文件的维护量大
当数据库结构发生变化时,所有的数据文件都需要修改,如果没有修改,相关的测试就报错,当单元测试的错误越来越多时,开发人员就基本没有兴趣去维护这些测试了
3、在单元测试的代码中需要去写数据准备的代码
我很讨厌写这些代码,我只想测试我写的类而已
anntest 或许可以帮助你
anntest特点:
1、注释式配置数据(代码侵入性小)
2、数据配置集中化(数据库结构改了可以只改这里)
3、列准备数据(1000条数据只用一条注释)
4、可以对每个测试个性化自己需要的数据
5、多数据源支持,可以给几个不同的数据库同时准备
6、基于Spring-test ,Spring-test的东西都可以用
7、多种类型数据库支持
8、多样化的字段数据类型配置
anntest使用:
0、建一个给单元测试使用的数据库
数据库的结构和开发库相同,在spring数据源的配置中使用这个库
1、引入jar
Spring2.5:
com.taobao.anntest anntest-spring2 1.4.0-SNAPSHOT
Spring3.0:
com.taobao.anntest anntest-spring3 1.4.0-SNAPSHOT
2、表配置文件 (已经不建议使用)
- NULL:null
- BLANK:空字符
- VARCHAR:字符串类型
- NUMBER:数字类型
- SYSDATE: 当前日期(只有年月日)
可以使用 value="yyyy-MM-dd" 指定固定日期
- SYSTIME: 当前时间
可以使用 value="yyyy-MM-dd HH:mm:ss" 指定固定时间
关于increase的说明:
适用于VARCHAR 、NUMBER、SYSDATE、SYSTIME类型
3、准备测试的基础类
@RunWith(AnnSpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
"classpath:/springbeans-data-source-test.xml",
"classpath:/springbeans-rpt-ds-test.xml",
"classpath:/springbeans-web-bo.xml"
})
@TransactionConfiguration(transactionManager="txManager",defaultRollback=true)
@Transactional
public abstract class BaseTestCase{
}
就 @RunWith(AnnSpringJUnit4ClassRunner.class) 不一样,其他和Spring-test的都一样
4、开始测试啦
(1)单表数据准备
@Test
@DataSet(tbName="z_member",number=10)
public void testGetMemberById(){
MemberDO memberDO = memberBO.getMemberById(99999901L);
assertEquals(99999901L,memberDO.getMemberid().longValue());
assertEquals("测试用户1",memberDO.getNickname());
}
(2)多个表
@Test
@DataSets({
@DataSet(tbName="z_member",number=10),
@DataSet(tbName="z_config",number=1)
})
(3)不同库的两个表
@Test
@DataSets({
@DataSet(tbName="z_member",number=10),
@DataSet(tbName="rpt_z_cpmprice",number=5,dataSource="dataSourceSds")
})
anntest默认的数据源是spring配置的第一个dataSource
(4)自定义数据 (已经不建议使用,可以使用 9 的功能进行替代)
@Test
@DataSets({
@DataSet(tbName="z_member",number=10),
@DataSet(tbName="z_config",
customColumns={"configkey","configvalue"},
customRows={
@CustomRow({"TEST_KEY","hello world"}),
@CustomRow({"CONTRACT_VERSION_KEY","2"})
})
})
注:定义了自定义列之后,number属性将无效,数据行数为自定义数据的行数
(5)自定义列(覆盖配置文件的列定义)(1.1.0新功能)(已经不建议使用)
@Test
@DataSet(tbName="CPX_CAMP_DETAIL_ADBOARD",number=3,columns={
@Column(name="ADID",valueType=ColumnType.NUMBER,value="99999901")
})
(6) 自定义数据 (推荐使用)
@Test
@DataSet(tbName="iface",number=16,
custom="age={3,4,7};" + //表示数组,第一条=3,第2条=4,…
"name=dcross^2;" + // ^表示递增,2表示步长
"nick=nickname^;" + //表示递增,步长为1
"money=2.45;" + //全部用这个值
"the_datetime=FUNC{now()}") //用函数
如果需要准备的数据中有 = ; , ^ 特殊字符,使用 \\= \\; 转义
(7)使用csv格式的自定义数据
1、指定csv文件的文件名:
@Test
@DataSet(tbName="SIZE_INFO",dataFile="size_info.csv")
文件如下:
注:不需要定义所有的列,只需要定义个性化的列,其他的列会取配置里的默认数据
定义了自定义列之后,number属性将无效,数据行数为自定义数据的行数
anntest会在当前目录查找这个文件
2、如果是公用的数据,可以在测试的根目录下新建anntest-data目录,将csv文件放在这里,在测试中按照如下方式指定:
@Test
@DataSet(tbName="DICT",dataFile="dict.csv")
anntest数据的优先级:
1、当前目录下指定文件
2、anntest-data目录下指定文件
如果加载到,后面的将被忽略
(8)清除数据
@Test
@DataSet(tbName="CPX_CAMP_DETAIL_ADBOARD",number=0)