Java 使用自动化测试数据进行昂贵的维护

Java 使用自动化测试数据进行昂贵的维护,java,automated-tests,integration-testing,test-data,data-driven,Java,Automated Tests,Integration Testing,Test Data,Data Driven,在我的公司,我们有越来越多的在JavaWeb应用程序中使用JUnit的集成测试。每个测试都使用一些特定的外部XMLs文件,用测试所需的数据填充数据库。 问题是: 当模型发生变化时,我们需要花费很长时间来纠正所有XML文件(我们有数百个XML文件,其中很多是冗余的) 手动创建XML文件的复杂性不鼓励程序员探索不同的场景 我们在测试数据和测试之间没有链接(例如,在测试中,我不知道XML插入的用户的“名称”)。我们可以对需要的信息进行硬编码,但这也会增加维护时间,以保持XML和硬编码数据的同步 面对这

在我的公司,我们有越来越多的在JavaWeb应用程序中使用JUnit的集成测试。每个测试都使用一些特定的外部XMLs文件,用测试所需的数据填充数据库。 问题是:

  • 当模型发生变化时,我们需要花费很长时间来纠正所有XML文件(我们有数百个XML文件,其中很多是冗余的)
  • 手动创建XML文件的复杂性不鼓励程序员探索不同的场景
  • 我们在测试数据和测试之间没有链接(例如,在测试中,我不知道XML插入的用户的“名称”)。我们可以对需要的信息进行硬编码,但这也会增加维护时间,以保持XML和硬编码数据的同步
  • 面对这个问题,我开始考虑使用自己的系统CRUD为每个测试生成测试数据。在每个测试开始时,我会运行一些方法来保存测试所需的数据。 在我看来,它将解决所有3个问题,因为:

  • 对模型的更改无论如何都需要更改积垢,因此无需再更正测试数据
  • 这将更容易构建、测试数据,因为我们不必担心手动匹配实体的id和外键之类的事情
  • 我将在IDE保证的同步中拥有变量中的所有重要数据
  • 但是,对我来说,它缺乏启动这种方法的经验和知识。 问题是:
    这个解决方案有效吗?这种方法会导致其他问题吗?我在文献中哪里可以找到这种方法?对于列出的问题,有更好的解决方案吗?

    听起来您现有的系统使用了类似DBUnit的东西,测试从一个干净的数据库开始,测试包括一个设置步骤,将一个或多个XML文件中的数据加载到数据库中,然后针对该数据执行测试

    以下是这种方法的一些好处:

    • 如果crud层存在问题,则不会影响数据设置。当出现问题时,每个错误应该有一个测试失败,而不是每个失败的相关设置都有一个错误

    • 每个测试都可以非常明确地说明运行测试需要哪些数据。由于域模型有时介于可选关联和延迟加载之间,因此加载的对象可能并不确定。(这里我特别想到Hibernate,其中很多时候映射的结果可能很复杂。)相反,如果数据是以更具声明性的方式设置的,说明哪些行在哪个表中,那么起始状态是显式的

    保持测试简单、明确,并且与其他部分的耦合最小,意味着要解决的问题更少,出错的机会也更少。如果您的测试变得如此复杂,以至于测试中的代码比测试中的代码更不可能出现任何问题,那么人们就会不愿意运行和更新测试

    使用DBUnit,您可以编写一个脚本,从数据库内容自动创建XML,这样您就可以重新创建所需的状态并将其保存为XML。不需要手动生成测试数据

    测试数据可能变得支离破碎,难以更新,特别是如果它是以一种临时方式创建的,没有考虑重用的话。您可能会考虑通过测试并将测试设置数据分解为可以重用的片段。
    你所描述的痛点在我看来并不需要极端的措施,比如重做所有的测试设置。即使您这样做了,您仍然需要重构您的测试数据。可以使用较小的项目作为较大更改的试验场,并对大多数现有代码进行较小的增量更改。

    提高可维护性的关键是保持干燥。测试数据设置不应该是冗余的,如果您的测试技术没有提供有效的重用方法,那么您使用的是错误的技术

    为测试数据设置编写Java代码为您提供了熟悉的好工具,可以提高测试中的代码重用。它还提供了比XML更好的重构支持,并明确了测试数据和测试代码之间的链接,因为它们位于同一个源文件(甚至是同一个方法!)。然而,它确实需要程序员编写和维护测试(而不是不懂Java的业务分析师、经理或测试人员)

    因此,如果测试数据主要由程序员编写和维护,我会使用Java,通过实际应用程序的CRUD层(甚至是成熟的域层)来编写和维护。然而,如果大多数测试数据来源于某些数据导出,或者由非程序员编写,那么纯数据驱动的方法可能更适合。也可以结合这些方法(即为每个实体选择最合适的策略)


    个人经验:我们的团队曾经使用DBUnit进行集成测试,但现在已经切换到使用真实数据访问层将测试数据设置为测试代码的一部分。通过这样做,我们的测试更能揭示意图,更易于维护。测试工作量减少了,但测试覆盖率提高了,用更少的刺激编写了更多的测试。这是可能的,因为测试完全由开发人员编写和维护。

    对于程序员来说可能是一个更好的问题。StackExchange我对第3点有一个答案:创建XML文件来封装测试数据和预期结果。我还建议看一下TestNG,它支持将多个测试用例输入到一个测试方法中,将测试数据存储在数据库中并从中生成XML。在SQL中修改数据然后创建XML更容易。为什么不使用生成XML文件的对象/类呢?这样,模型中的任何更改都必须更新类-这将影响所有测试