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

标签 java spring grails testing functional-testing

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

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

A 版本允许测试用例通过构建工具的测试阶段或在 CI 作业中轻松测试系统的当前版本。那就是例如Grails functional test phase是为了。或者 Maven could be set up做这个。

B 版本要求系统已经运行,但系统可以在(或至少更接近)生产环境中。 Grails 可以在执行功能测试时通过 -baseUrl 选项来做到这一点。

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

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

我看到了不同的可能性:

  1. 使用相同的 API(例如 HTTP POST)创建实体。缺点:更改创建方法会破坏两个测试用例。此外,可能没有适用于所有 API 的创建方法。
  2. 添加一个额外的 CRUD API 用于测试并仅在非生产环境中激活它。然后使用该 API 进行测试。缺点:向生产系统添加额外的代码,API 逻辑可能并不简单,例如创建复杂的实体图(通过聚合/组合),我们需要确保 API 未激活用于生产。
  3. Grails Remote Control 插件基本上遵循相同的方法。它允许您“进入您的应用程序”并通过序列化调用任意代码。缺点:感觉“脆”。不同的语言/框架可能有类似的机制(这个问题不是特定于 Grails 的)。
  4. 直接访问关系数据库并创建/删除内容,例如使用 DbUnit 或只是通过 JDBC 手动创建实体。缺点:您在测试用例中复制了创建/删除逻辑和/或 ORM。尽管 SUT 仍然有效,但重构数据库会破坏测试用例。

除了这些可能性之外,当使用 (-inline) 选项进行功能测试时,Grails 允许访问 Spring 服务(因为应用程序实例与测试用例在同一 JVM 中运行)。同样适用于 Spring Boot "integration tests" .但是我无法针对已经运行的应用程序版本运行测试(如上面的选项 B 所述)。

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

此外,您如何保证每个测试用例自行清理,以便下一个测试用例看到 SUT 处于相同状态?

最佳答案

  • 与单元测试一样,您希望在运行功能测试之前拥有一个“干净”的数据库。您将需要一些设置/拆卸功能来使数据库进入定义的状态。

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

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

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

  • 不要在功能测试中测试太多细节,以免它变得更复杂。 :)

关于java - 如何管理功能测试的应用程序数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24881436/

相关文章:

Java/安卓 : Define object with unknown type

java - 在 OpenCV 中将两个点相加

java - MessageFormat 中的嵌套选择子句?

json - Grails - 使用 JSON 启动域类

hibernate - Grails/GORM/Hibernate:引用未保存的 transient 实例的域实例的属性列表

ajax - Grails Spring Security AJAX 响应请求页面的 HTML,而不是来自 ajaxSuccess() 的 JSON

java - 带前导零输出的长变量

java - 使用 REST 模板和 JSON 响应格式在 Spring MVC 上返回 Http Status 500

java - 带 @Secured 和 @PreAuthorize 注释的类不保护 super 方法

java - 星号-Java AGI。 DefaultAgiServer 在启动方法运行时卡住