如何管理功能测试的应用程序数据?

时间:2014-07-22 07:38:23

标签: java spring grails testing functional-testing

我们目前正在通过引入功能测试来改进我们正在运行的一组数据库支持的应用程序(或“服务”)的测试覆盖率。对我来说,功能测试将被测系统(SUT)视为一个黑盒子并通过其公共接口进行测试(无论是Web界面,REST还是我们使用AMQP进入消息传递领域的潜在冒险)。

为此,测试用例 A)引导应用程序实例 B)使用已经运行的实例

A版允许测试用例通过构建工具的测试阶段或CI作业内部轻松测试系统的当前版本。这就是例如Grails functional test phase是为了。或Maven could be set up执行此操作。

B版本要求系统已经运行,但系统可能在生产环境内(或至少更接近)。 Grails可以在执行功能测试时通过-baseUrl选项执行此操作。

现在让我感到困惑的是如何在执行每个测试用例之前实现所需的服务状态?

如果我是想要测试一个执行基本CRUD的REST接口,如何在数据库中创建一个实体,以便我可以为它测试HTTP GET?

我看到了不同的可能性:

  1. 使用相同的API (例如HTTP POST)来创建实体。缺点:更改创建方法会破坏两个测试用例。此外,可能没有适用于所有API的创建方法。
  2. 添加其他CRUD API 以进行测试,并仅在非生产环境中激活它。然后该API用于测试。下行:向生产系统添加额外的代码,API逻辑可能不是微不足道的,例如,创建复杂的实体图(通过聚合/组合),我们需要确保API不会被激活用于生产。
  3. Grails Remote Control插件基本上遵循相同的方法。它允许您抓住您的应用程序"并且通过序列化调用任意代码。缺点:感觉脆弱"。不同的语言/框架可能有类似的机制(这个问题不是Grails特定的)。
  4. 直接访问关系数据库并创建/删除内容,例如使用DbUnit或只是通过JDBC手动创建实体。缺点:您在测试用例中复制了创建/删除逻辑和/或ORM。尽管SUT仍然有效,但重构数据库会破坏测试用例。
  5. 除了这些可能性之外,Grails在使用(-inline)选项进行功能测试时允许访问Spring服务(因为应用程序实例在与测试用例相同的JVM中运行)。同样适用于Spring Boot "integration tests"。但我无法针对已经运行的应用程序版本运行测试(如上面的选项B所述)。

    那你怎么做的?我错过了任何选项吗?

    另外,你如何保证每个测试用例在自身之后正常清理,以便下一个测试用例看到SUT处于相同的状态?

1 个答案:

答案 0 :(得分:0)

  • 与单元测试一样,您希望有一个" clean"运行功能测试之前的数据库。您需要一些设置/拆卸功能才能使数据库进入已定义的状态。

  • 清理数据库的最简单/最快的解决方案是使用sql脚本删除所有内容。 (对于调试,在测试 setup 中运行它以在测试失败后保持数据库的状态也很有用。)这可以手动维护(它只包含delete <table>语句) 。如果您的数据库经常更改,您可以尝试生成干净的脚本(禁用外键(以避免排序问题),删除表)。

  • 生成测试数据也可以使用sql脚本,但很难维护,或者通过代码创建。代码可以放在普通的服务中。如果您不需要真实的生产数据,build-test-data插件可以帮助您简化测试数据的创建。如果您在代码方面,重新使用生产代码来创建测试数据以避免重复也是有意义的。

  • 调用测试数据设置只需使用远程控制。我不认为它比所有的http&amp;更脆弱。 ajax东西;-)。由于我们现在在服务中拥有所有创建代码,因此使用远程控制调用的唯一内容就是创建数据的服务。它不必比remote { ctx.testDataService.setupDataForXyz() }更复杂。如果它很简单,您甚至可以放弃远程控制并使用控制器/操作来运行它。

  • 不要用功能测试来测试太多细节,以使它不像现在这样复杂。 :)