使用人工数据设置和播种数据库以进行集成测试的正确方法是什么

时间:2017-10-30 16:08:57

标签: java api jvm kotlin integration-testing

假设我在数据库中有2个表,一个名为students,另一个名为departmentsstudents如下所示:

department_id, student_id, class, name, age, gender, rank

departments看起来像:

department_id, department_name, campus_id, number_of_faculty

我有一个API,可以查询数据库并从2个表中检索各种信息。例如,我有一个终点,可以通过加入2个表来获得每个校园的学生人数。

我想为我的API端点进行集成测试。为此,我启动了一个本地数据库,运行数据库模式的迁移以创建表,然后用人工记录填充每个表,以便我确切知道数据库中的内容。但是,提出一个良好的播种过程已经证明是不容易的。对于上面描述的简单示例,我当前的方法涉及为每列生成多个不同的记录。例如,我需要至少2个校区(比如mainsatellite)和3个部门(例如Electrical EngineeringMathematics代表main校园和{{{} 1}}用于English校园)。然后我需要每个部门至少2名学生或总共6名学生。如果我混合satellitegenderage,您可以很容易地看到人工记录的数量呈指数级增长。提出所有这些人工记录是手动的,因此很难维护。

所以我的问题是:一般来说,为集成测试设置和种子数据库的正确方法是什么?

3 个答案:

答案 0 :(得分:4)

首先,我不知道任何公共工具可以自动执行为任意场景生成测试数据的任务。

实际上,这是一项艰巨的任务。您可能会查找有关该主题的科学论文和书籍。可能有这些。不幸的是,我没有推荐一套“好”的。

一种非常简单的方法是生成从每个字段的一组潜在值(数据库案例中的列)中提取的随机数据。 (这就是你已经做过的。)对于较小的套装,你甚至可以生成全套的潜在组合。例如。您可以查看以下test data generator以获取应用此类方法的变体的示例。

但是,由于以下原因,这可能不合适:

  • 结果数据将显示出显着的冗余,但可能仍未涵盖所有有趣的案例。
  • 它可能会针对您的应用程序强制执行的逻辑约束创建不一致的数据(例如参照完整性)

您可以通过在生成测试数据的过程中添加一些约束来消除此类问题,以消除无效或冗余组合(与您的应用程序相关)。

然而,实际的限制(并且有意义)取决于您的业务和用例。因此,对此类限制没有一般规则。例如。如果您的API根据年龄和性别的性别组合对年龄值进行特殊处理对您的测试很重要,如果不存在这种区别,则年龄和性别的任何组合都可以。

只要您正在寻找白盒测试场景,您就需要输入您的实现(或至少是规范)细节。

对于黑匣子测试,一整套组合数据就足够了。然后,仅减少测试数据以将测试的运行时间保持在某个最大值是一个问题。

在处理白盒测试时,您可能会明确地寻找添加角落案例。例如。在你的情况下:没有任何学生的部门,有一个学生的部门,没有部门的学生,只要这种情况对你的测试目的有意义。 (例如,在测试错误处理或测试应用程序如何处理不一致的数据时。)

在您的情况下,您将API视为数据的视图。数据库内容只是实现该API的所有有趣输出所必需的输入。识别正确数据库内容的实际任务可以通过提供与应用程序提供的映射相反的数学问题来描述(从数据库内容到API结果)。

如果没有任何现成的工具,您可以应用以下步骤:

  1. 从简单的组合数据生成器开始
  2. 应用一些限制,消除无用的非法记录
  3. 运行测试捕获覆盖率数据添加额外的数据记录,以改善覆盖率重复测试,直到覆盖率正常

  4. 在对代码或架构进行任何更改后查看和调整数据

答案 1 :(得分:3)

我认为DbUnit可能是您尝试做的事情的正确工具。您可以在测试之前指定数据库的状态,并检查之后的预期状态。

答案 2 :(得分:0)

如果需要使用Junit初始化带有表和虚拟数据的数据库,

我正在使用UnitilsDbUnit

Unitils中的数据可以从资源文件夹中的XML文件加载,因此一旦测试运行器启动,它将从xml加载所有内容并将它们插入数据库,请查看其网站上的示例。 / p>