代码之家  ›  专栏  ›  技术社区  ›  egervari

有没有一个类似于dbunit的框架不适合java/scala?

  •  59
  • egervari  · 技术社区  · 15 年前

    我在考虑建立一个新的、轻量级的数据库人口框架。我绝对讨厌dbunit。在我做之前,我想知道是否有人已经做了。

    我不喜欢dbunit的地方:

    1) 不推荐使用最简单的编写和入门格式。他们希望你使用臃肿的格式。有些甚至需要xml模式。是的,随便。

    2) 它们不是按照您编写行的顺序填充行,而是按照xml文件中定义的顺序填充表。这真的很糟糕,因为您不能以外键约束不会导致问题的方式对数据进行排序。这只会迫使你经历完全关闭它们的麻烦。

    这也会浪费时间,并使junit基类膨胀,以包含禁用外键约束的代码。您可能需要测试数据库类型(hsqldb等),并以特定于数据库的方式禁用它们。这太糟糕了。

    如果dbunit帮助自动禁用外键约束作为其框架的一部分可能会更好,但它们不会这样做。他们确实在追踪方言。。。为什么不用它们来做这个呢?最终,所有这些都会迫使程序员浪费时间,而不是快速起来进行测试。

    3) XML是一个很难写的东西。我不需要再多说了。他们也提供了很多方法,我认为这只是使事情复杂化。只要提供一个真正可靠的方法,并完成它。

    另外,如果你一个月都没有在一个项目上工作,你怎么记得用户1是管理员,用户2是业务用户,用户3是工程师,用户4是其他人?回去检查这是在浪费更多的时间。应该有一种有意义的方法来检索它,而不是任意的数字。

    5) 很慢。我发现,除非使用hsqldb,否则速度会非常慢。这不一定。也有很多方法来搞乱它的配置,因为它不容易做到“开箱即用”。为了让它正常工作,你必须经历一个困难。所有这些都鼓励人们不要使用它,或者当他们开始使用它的时候感到愤怒。

    6) 有些价值观往往会重复很多次,比如约会。最好指定默认值,甚至让框架自动放入默认值,即使不告诉它在其中放入默认值。这样,您就可以只使用所需的值创建对象,而不使用其他值。如果不需要,这肯定比指定列的每个角落和缝隙要好。

    7) 可能最烦人的事情是,第一个条目必须包含所有值(甚至是空占位符),否则以后的行将不会选择实际指定的列。

    DBunit也没有将[NULL]转换为实际空值的合理默认值。你必须手动添加它。告诉我,谁没用过dbunit?每个人都有。不应该是这样!

    这意味着,如果您有一个多态对象,那么必须声明第一行中每个子类的联接表的所有外键,即使它们是空的。如果为所有子类模式创建一个表,则仍必须指定第一行上的所有字段。这太糟糕了。

    有什么能让我满意的,或者我应该成为一个更好的数据库测试框架的下一个框架开发人员吗?

    13 回复  |  直到 15 年前
        1
  •  100
  •   Community Mohan Dere    9 年前

    我不知道DbUnit的真正替代品,也不知道 @Joe 在我眼里:

    • Incanto :不与数据库无关
    • SQLUnit :用于测试数据库存储过程的回归和单元测试工具(DbUnit不是这样的)
    • Cactus
    • Liquibase :数据库迁移工具(不加载/验证数据)
    • ORMUnit :可以初始化数据库,但仅此而已
    • JMock :根本不与DbUnit竞争

    也就是说,我个人已经成功地多次在小型和大型项目中使用了DbUnit,我发现它非常有用,特别是在使用 Unitils 以及它的DbUnit模块。这并不意味着它是完美的,无法改进,但有了体面的工具(定制或类似Unitils),使用它已经是一个体面的经验。

    1) 不推荐使用最简单的编写和入门格式。他们希望你使用臃肿的格式。有些甚至需要xml模式。是的,随便。

    DbUnit支持平面或结构化XML、XLS、CSV。您想使用什么革命性的格式?顺便说一下,在使用XML时,DTD或模式不是必需的。但它给了你一些好东西,比如验证和自动完成,这有什么不好?Unitils可以很容易地为你生成它 Generate an XSD or DTD of the database structure .

    如果dbunit帮助自动禁用外键约束作为其框架的一部分可能会更好,但它们不会这样做。他们确实在追踪方言。。。为什么不用它们来做这个呢?最终,所有这些都会迫使程序员浪费时间,而不是快速起来进行测试。

    同时,Unitils提供了透明处理约束的支持,请参见 Disabling constraints and updating sequences .

    3) XML是一个很难写的东西。我不需要再多说了。他们也提供了很多方法,我认为这只是使事情复杂化。只要提供一个真正可靠的方法,并完成它。

    我想疼痛是主观的,但我不觉得疼痛,特别是在使用模式和自动完成时。你说的银弹是什么?

    把它们放小一点,就知道了 best practice . 你违背了一个已知的最佳实践,然后抱怨。。。

    另外,如果你一个月都没有在一个项目上工作,你怎么记得用户1是管理员,用户2是业务用户,用户3是工程师,用户4是其他人?回去检查这是在浪费更多的时间。应该有一种有意义的方法来检索它,而不是任意的数字。

    是的,任务转换是反作用的。但是,由于您使用的是低级数据,因此必须知道它们是如何表示的,因此,除非您使用更高级的API,否则没有什么神奇的解决方案(但这不是DbUnit的目的)。

    5) 很慢。我发现,除非使用hsqldb,否则速度会非常慢。这不一定。也有很多方法来搞乱它的配置,因为它不容易做到“开箱即用”。为了让它正常工作,你必须经历一个困难。所有这些都鼓励人们不要使用它,或者当他们开始使用它的时候感到愤怒。

    这是数据库和JDBC的固有特性,而不是DbUnit。如果你想让事情越快越好(如果你有更好的不可知论方法,我很乐意了解它),那么就使用像H2这样的快速数据库。

    6) 可能最烦人的事情是,第一个条目必须包含所有值(甚至是空占位符),否则以后的行将不会选择实际指定的列。

    当使用如演示中所述的单元时 Unitils - Home - JavaPolis 2008 或 Unit testing: unitils & dbmaintain .

    有什么能让我满意的,或者我应该成为一个更好的数据库测试框架的下一个框架开发人员吗?

    如果你认为你能让事情变得更好,也许可以为现有的解决方案做出贡献。如果这是不可能的,如果你认为你可以创建杀手数据库测试框架,我能说什么,做它。但别忘了,咆哮是很容易的,用你自己的解决方案想出解决方案就不那么容易了。

        2
  •  28
  •   Jonathan    12 年前

    作为一名DbUnit开发人员,我非常感谢您的批评,我必须部分同意您的观点。我们目前正在开始设计下一个DbUnit主要版本,我希望邀请您参与讨论和开发。

    我不打算回答您的问题,因为您的问题实际上与DbUnit无关,而是与DbUnit替代方案有关。无论如何,我只想强调你的第7点是完全错误的:你不再需要指定第一行的所有列,这个特性被称为列感知。我不会告诉你为什么默认情况下不启用它,因为你一定很聪明,可以自己理解它。

    我将对scaladbtest进行深入的研究,希望我们能整合他们的想法。

        3
  •  16
  •   blue-sky    13 年前

    面对使用DBUnit的类似问题,我发现: http://dbsetup.ninja-squad.com/index.html 可能会解决问题。例如,所有DB内容都包含在java类本身中,而不是在单独的文件中表示测试数据。

        4
  •  4
  •   Chriki    11 年前

    如果您使用Spring框架(或者不介意至少用于测试),那么 Spring DBUnit 是目前我所知道和使用的最好的(维护的)普通DBUnit替代品。引用他们的网站:

    Spring DBUnit提供了Spring测试之间的集成 框架和流行的DBUnit项目。它允许您设置和 使用简单注释和检查拆分数据库表 测试完成后需要的表内容。

    Spring DB unit似乎是用于DB单元测试的某种正式的Spring解决方案(使用DBUnit);至少库的作者/维护者Phil Webb正在SpringSource/Pivotal工作。

        5
  •  3
  •   retronym    15 年前

    我使用DBUnit,用一些包装纸来平滑粗糙的边缘。一个可以补充或重叠功能的好工具是 Jailer . 它可以从引用数据库中提取数据子集,并将其存储为与DBUnit兼容的XML文件,或者存储为“拓扑排序的DML文件”,其中考虑了外键约束。

        6
  •  3
  •   edrdo    10 年前

    我刚刚发布了一个名为JDBDT(Java数据库增量测试)的库

    看一看 http://jdbdt.org

    最好的, 爱德华多

        7
  •  2
  •   Stijn Geukens    13 年前

    你说得很对。

    在过去的几年里,我为很多门户网站工作,主要是使用PHP,但也偶尔使用一些Java。
    像你一样,我不明白这些年来,框架和单元测试开发人员似乎没有意识到在过去的十年中,存储处理发生了多大的变化。 仅仅向某个数据库发送create/insert/truncate语句是不够的! 如果你在大规模运营,你最终会使用各种各样的存储后端,分层组织以快速推出热门内容。另外,在数据库前面还有数据分区的问题。如果您没有一个适当的外键抽象,那么当您的存储设置更改时,您肯定会发疯。当我们在这里的时候:按外键优先顺序排序的fixture有很多陷阱,我还没有看到一个真正的解决方案 DBUnit .

    不管怎么说,关键是仅仅为单元测试准备一个基本的数据库存储是不够的,因为对于复杂的存储设置来说,它们常常无法在实际环境中重现问题,而且维护起来非常麻烦。

    不想听起来像个粉丝:有一个地方一切都很好 ruby on rails . 它有一个持久的模型概念,人们似乎已经实际投入了一些思考。如果你在交易 PHP , Symfony 是去的地方。它通过默认包含 Doctrine ,with也相当以DB为中心,但它有干净的接口和极大的扩展性,完全复制了rails fixture系统。从专业角度来说,我现在需要坚持自制解决方案,但它们可以正常工作。

        8
  •  1
  •   Joseph Weissman    15 年前

    下面是一些我特别喜欢或感兴趣的工具的简短列表(除了DBunit)。至少他们可以提供一些灵感:

    注意,在范围或特性集方面,这些都不是DBunit真正的竞争对手。不过,有一些有趣的想法可能值得一看。祝你好运!

        9
  •  1
  •   Lars    14 年前

    我们在写 Daleq 作为DbUnit的包装器来解决一些提到的问题。它允许在单元测试中填充数据库,而不是依赖于编辑XML文件。

        10
  •  1
  •   Jeff S    11 年前

    我对DBUnit也有类似的问题。尤其是用于填充本地开发数据和从真实数据库导出数据。我遇到了一些情况,它会导出一个数据集,但它无法导入。

    这激励我为它写了一个新的图书馆: https://github.com/jeffskj/phonydata

    它使用groovy DSL来定义数据集,这使得数据的表示变得非常紧凑,并且可以做一些很酷的事情,比如生成随机数据,因为它只是groovy代码。

        11
  •  1
  •   niels    10 年前

    DBUnit的情况有时确实令人沮丧。有些问题是从 Marc Philipp 具有 dbunit-datasetbuilder ,特别是如果你把它和 validator SZE .

    免责声明:所有引用的github资源都由我维护。

        12
  •  0
  •   pagoda_5b    13 年前

    春天 配置和 规格2 可以找到测试 here

        13
  •  0
  •   Καrτhικ    11 年前

    我刚刚发布了一个基于groovy DSL的框架,名为pedal loader,可通过 github . 文档 here .

    它允许您直接使用JPA实体级抽象。因为它是一个groovy脚本,所以您可以使用所有的groovy构造。

    要将行插入到由名为Student的JPA实体支持的表中,并使用名为id、name和grade的字段(不是数据库列,而是映射字段),请执行以下操作:

    allStudents = table(Student, ['id', 'name', 'grade']) {
        row 1, 'Joe', Grade.A
        rowOfInterest = row 2, 'John', Grade.B
    }
    

    Grade是Student类中映射到数据库列的枚举(可能使用JPA 2.1@Convert注释)。allStudents是一个包含行的列表,rowOfInterest是对特定行的引用。这些属性(所有学生和感兴趣的行)可用于单元测试。

        14
  •  0
  •   sxc731 Paul Samsotha    6 年前

    另一种选择是用现代库包装DBUnit,以提高可用性和简洁性。我的选择是 database-rider ,这使得DBUnit很容易使用,甚至支持JUnit 5,如下例所示:

    @RunWith(JUnitPlatform.class)
    @ExtendWith(DBUnitExtension.class)
    @DBUnit(cacheConnection = true, cacheTableNames = true)
    class TestInstrumentQueryService {
    
        private ConnectionHolder connHolder = () -> EntityManagerProvider.instance("my-jta-unit").connection();
    
        @DBRider
        @DataSet("datasets/instrumentIds.yml")
        void testFindInstrumentById() {
    
            InstrumentQueryService iqs = new InstrumentQueryService(EntityManagerProvider.em());
    
            Instrument instr = iqs.findInstrumentById(InstrumentIdType.TICKER_BBG, "AAPL");
            assertEquals(100, instr.getId());
        }
    }
    

    注意这是如何无缝地利用(简洁的)YAML测试数据集的(YAML而不是XML,尽管我相信DBUnit实际上支持这些数据集)。