在我之前的一项任务中,我们进行了数百个涉及数据集的集成测试,但不是在 DBUnit 中——测试环境是从头开始编写的,因为它是一家可以负担得起这种东西的大公司。
数据集是分层组织的。被测系统由几个(5-10)个模块组成,测试数据遵循该模式。单元测试脚本如下所示:
include(../../masterDataSet.txt)
include(../moduleDataSet.txt)
# unit-specific test data
someProperty=someData
属性名称被一些我不记得的奇怪工具直接映射到数据库记录。
同样的模式可以应用于 DBUnit 测试。在主数据集中,您可以放置总是需要的记录——比如字典,数据库的初始加载,就好像它要从头开始安装一样。
在模块数据集中,您可以将涵盖大多数测试的测试用例的记录放在一个模块中;我认为您的平均测试不会涉及所有 70 个数据库表,是吗?即使应用程序是单片的,您肯定也必须有一些可以构成模块的功能组。尝试围绕它组织模块级测试数据。
最后,在测试级别,您只需使用此特定测试所需的最少记录数来修改您的测试集。
这种方法具有学习的巨大好处;因为数据文件很少,所以随着时间的推移,您实际上开始记住它们。与其看到数百个大数据集的区别仅在于不明显的细节(您必须在每次返回测试时发现),而是可以轻松判断任意两个数据集的不同之处。
最后谈谈性能。在我的 2.4 GHz 2 核 WinXP 机器上,一个 DBUnit 测试涉及:
- 删除 14 个表,
- 创建 14 个表,
- 插入约100 条记录,
- 执行测试逻辑,
需要 1-3 秒。日志显示前 3 次操作耗时不到一秒,大部分测试时间都被 Spring 消耗了。此逻辑由每个测试执行,以避免测试顺序依赖性。一切都在一个带有嵌入式 Derby 的 VM 中运行,这可能就是它如此之快的原因。
编辑:我认为 DBUnit XML 数据集不支持包含其他测试文件,可以通过对所有集成测试使用基类来克服它,例如:
public class AbstractITest {
@Before
public void setUp() throws Exception {
//
// drop and recreate tables here if needed; we use
// Spring's SimpleJdbcTemplate executing drop/create SQL
//
IDataSet masterDataSet = new FlatXmlDataSetBuilder().build("file://masterDataSet.xml");
DatabaseOperation.CLEAN_INSERT.execute(dbUnitConnection, dataSet);
}
}
public class AbstractModuleITest extends AbstractITest {
@Before
public void setUp() throws Exception {
super.setUp();
IDataSet moduleDataSet = new FlatXmlDataSetBuilder().build("file://moduleDataSet.xml");
DatabaseOperation.CLEAN_INSERT.execute(dbUnitConnection, moduleDataSet);
}
}
public class SomeITest extends AbstractModuleITest {
// The "setUp()" routine only here if needed, remember to call super.setUp().
@Test
public void someTest() { ... }
}