【发布时间】:2014-07-22 07:38:23
【问题描述】:
我们目前正在通过引入功能测试来提高我们正在运行的一组数据库支持的应用程序(或“服务”)的测试覆盖率。对我来说,功能测试将被测系统 (SUT) 视为一个黑盒,并通过其公共接口对其进行测试(无论是 Web 接口、REST 还是我们使用 AMQP 进入消息传递领域的潜在冒险) )。
为此,测试用例A) 引导应用程序的实例 或B) 使用已在运行的实例。
A 版本允许测试用例通过构建工具的测试阶段或 CI 作业内部轻松测试系统的当前版本。这就是例如Grails functional test phase 是为了。或Maven could be set up 这样做。
B 版本要求系统已经运行,但系统可能位于(或至少更接近)生产环境中。 Grails 可以在执行功能测试时通过-baseUrl 选项做到这一点。
现在让我感到困惑的是如何在每个测试用例执行之前实现服务的所需状态?
如果我例如想要测试一个执行基本 CRUD 的 REST 接口,如何在数据库中创建一个实体以便测试它的 HTTP GET?
我看到了不同的可能性:
- 使用相同的 API(例如 HTTP POST)来创建实体。缺点:更改创建方法会破坏两个测试用例。此外,可能没有适用于所有 API 的创建方法。
- 添加附加 CRUD API 用于测试,并且仅在非生产环境中激活它。然后将该 API 用于测试。缺点:向生产系统添加额外的代码,API 逻辑可能不是微不足道的,例如创建复杂的实体图(通过聚合/组合),我们需要确保 API 未激活用于生产。
- Grails 远程控制插件基本上遵循相同的方法。它允许您“进入您的应用程序”并通过序列化调用任意代码。缺点:感觉“脆弱”。不同的语言/框架可能有类似的机制(这个问题不是 Grails 特有的)。
- 直接访问关系数据库和创建/删除内容,例如使用 DbUnit 或仅通过 JDBC 手动创建实体。缺点:您在测试用例中重复创建/删除逻辑和/或 ORM。尽管 SUT 仍然有效,但重构 DB 会破坏测试用例。
除了这些可能性之外,Grails 在使用 (-inline) 选项进行功能测试时允许访问 Spring 服务(因为应用程序实例在与测试用例相同的 JVM 中运行)。同样适用于Spring Boot "integration tests"。但我无法针对已经运行的应用程序版本运行测试(如上面的选项 B 所述)。
那么你是怎么做到的呢?我错过了任何选择吗?
另外,您如何保证每个测试用例在自己之后正确清理,以便下一个测试用例看到 SUT 处于相同状态?
【问题讨论】:
标签: java spring grails testing functional-testing