我有一个与验收测试驱动开发 (ATDD) 相关的问题。我的应用程序是作为 REST 服务开发的,它可能有多个客户端 - 网站、移动设备、桌面。ATDD 概念说我应该从端到端测试开始每个功能。由于我的服务可能有多个提供相同用例的客户端应用程序(端),所以在编写验收测试时应该使用什么方法?验收测试是否应该将对 REST 服务或客户端应用程序的直接请求作为输入?或两者?我知道如果我的验收测试从 REST 请求开始,我会省略客户端部分,这绝对不行。如果这些从客户端开始,我将为每个客户端重复基本相同的功能测试。我需要找到一种位于这些边缘中间某处的方法。
2 回答
正如@bcarlso 建议的那样,您可以根据业务规则编写验收测试,因此它们并不特定于某个特定平台。
使用这些规范在每个平台上端到端地测试每个场景当然是可能的,许多组织都这样做。但是您可能会以一个非常大、速度慢的测试套件结束,这将难以维护。
Cucumber 和类似工具 ATDD 不要求您进行端到端测试。您可以使用它们来验证某些事物中的行为,就像一个类中的单个方法一样。
集中精力编写好的单元测试,以便在集成之前捕获绝大多数缺陷。不要依赖自动化验收测试来作为糟糕开发过程的 QA。使用少量高级端到端测试来测试通过应用程序的主要成功路径。
这里有一个权衡:一些与集成相关的问题可能会漏网。执行根本原因分析,并尝试确定将来如何避免类似的缺陷。在适当的级别添加额外的测试。只是不要让您的项目淹没在自己的测试套件中。
在练习 ATDD 时,我认为验收测试只是另一个用户界面。话虽如此,我将在业务层的 UI 下方进行测试。假设我有一个功能:
Given I have an addend of 5
and an augend of 3
When I calculate the sum
Then I should receive 8
在实施此测试时,我的接缝将位于业务层。假设一个 Java/Spring 类型的应用程序我的测试看起来像:
@Given("I have an addend of (\\d+)")
public void addend(int addend) { this.addend = addend; }
@Given("I have an augend of (\\d+)")
public void augend(int augend) { this.augend = augend; }
@When("I calculate the sum")
public void calculate() {
calculator = applicationContext.getBean(ScientificCalculator.class);
actualResult = calculator.sum(addend, augend);
}
@Then("I should receive (\\d+)")
public void verifyResult(int result) { assertEquals(result, this.actualResult); }
一旦我开发了背后的业务逻辑ScientificCalculator
并且所有的测试场景都通过了,我就知道从功能的角度来看,应用程序做了它需要做的事情。因为这完全绕过了 UI,所以不需要为每个 UI 重复测试。UI 现在完全没有业务规则(一件好事),您可以将 XML、JSON、HTML 以及您想要的任何 UI 放在前面。假设我们使用 Spring MVC,控制器将像这样简单:
@GET("calculate/sum/{addend}/{augend}")
public void addSomeNumbers(String addend, String augend) {
result = calculator.sum(Integer.parseInt(addend), Integer.parseInt(augend));
// Render the view with the result.
}
我会测试 UI 吗?大概。但几乎没有那么彻底,因为现有测试涵盖了主要的业务规则,而且一般来说,UI 错误的风险要低一些,并且比被误解或错误实现的业务逻辑更容易修复。
希望有帮助!
布兰登