dbunit 性能最佳实践

除了在实际dbunit站点上推荐的最佳实践/原则之外,还需要遵循哪些最佳实践/原则,可以大大加快测试并保持可维护性?我渴望一个像java的工厂女孩这样的库,但由于静态类型,它看起来是不可能的。

我目前的想法是,在这一点上,每个测试类有1个xml数据集 - 也许我分享其中一些,也许我没有。虽然有些测试数据可能会跨数据集重复,但我发现在3000个单元/集成测试中维护共享数据集太难了 - 而且我还有很长的路要走。

希望遵循任何导致测试效果良好且易于维护的原则。


答案 1

在我之前的一项任务中,我们有数百个涉及数据集的集成测试,尽管不是在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() { ... }
}

答案 2

Junit in Action 2e 中的建议实际上不是创建太多数据集(例如每个测试类一个),而是足够多,被认为是可维护的。除了少数例外情况外,我发现可以将主数据集用于大多数单元测试,而将单个数据集用于集成测试。限制预期数据集的使用也是一种选择。

此外,我将Unitils与dbunit结合使用,以简化测试数据的一些设置和加载,因此您可能需要在适当的时候考虑它。