我都对 TDD 和 BDD 感到困惑 :) TDD 和 BDD 在以下各点有何不同?
- 开发:首先是测试用例,然后是开发
RestService(HTTP):不打休息电话?如果是这样,
a) 我们是否只使用模拟对象返回硬编码的 json?
b) 如何处理 REST 调用失败?我们也应该有测试用例吗?
特别是对于第 2 项,我在谷歌上搜索了很多文章,但找不到关于如何处理休息呼叫的示例(代码)方法。
我都对 TDD 和 BDD 感到困惑 :) TDD 和 BDD 在以下各点有何不同?
RestService(HTTP):不打休息电话?如果是这样,
a) 我们是否只使用模拟对象返回硬编码的 json?
b) 如何处理 REST 调用失败?我们也应该有测试用例吗?
特别是对于第 2 项,我在谷歌上搜索了很多文章,但找不到关于如何处理休息呼叫的示例(代码)方法。
BDD 和 TDD 不能相互比较,尽管它们都用于测试优先开发。
BDD 不仅仅是使用类似英语的语法编写测试,例如 Kiwi。BDD(也称为 ATDD — 验收测试驱动开发)从开发人员、QA 和设计师(例如业务和交互设计师)开始,共同开发对提议的解决方案的共同理解。通常使用示例来说明行为,也称为通过示例说明。
我发现思考抽象的一个有用方法是区分你做什么(抽象的,高级策略)和你如何做(具体的,低级细节)。每个具体细节的存在都是为了实现更高级别的政策。当您看到具体的内容时,确定它所服务的策略是有益的。
示例规范可用于创建高级验收测试,用于测试应用程序的功能,即其行为。
单元测试用于测试应用程序如何实现解决方案,即测试是否在适当的时间将适当的消息发送给其协作者/依赖项。
标准 TDD 循环的阶段是红色、绿色、重构。在绿色阶段,您的目标是尽可能快地通过测试,无论是不择手段还是不择手段——编写丑陋、无组织的代码是可以接受的。测试通过后,您将重构代码以使其更具可读性/可更改性。
同样,对于 BDD/ATDD 循环,您有 Red、Green、Refactor。在 BDD 的绿色阶段,只需通过验收测试即可。您编写的所有代码都可以存在于测试本身中。在 BDD 的重构阶段,您将测试代码提取到生产代码中。您可以使用 TDD 来指导提取。
因此,对于给定的 BDD 验收测试,您可能有多个 TDD 测试。
关于如何测试 REST 调用,让我们回到抽象的前提——区分我们做什么和怎么做。
调用 REST 服务是一个具体的操作。它满足的策略可能是提供模型对象的列表。
假设您正在实施的用例是邀请朋友共进午餐。部分用例职责是从服务器获取好友列表;它不关心服务器如何找到朋友。
您的 BDD 测试将处理获取朋友列表、挑选朋友和完成邀请。您的 BDD 测试不会担心实际进行 REST 调用。
当您使用 TDD 实现处理与服务器通信的类时,您可以进行从远程数据源(即服务器)检索 JSON 的测试,并确保将 JSON 正确解析为User
模型对象。您还可以进行测试以覆盖响应错误的数据源等。
在您实际进行 REST 调用时,在使用 REST 与后端服务器通信的远程数据源的实现中,我会将其归类为集成测试,因为您正在测试与您不使用的组件的集成控制,即实际的后端服务器。集成测试只需要确认服务器以您的应用程序期望的格式返回 JSON 数据,或者在适当的时候返回错误。
BDD 实际上是从 TDD 派生的,所以有一点混乱也就不足为奇了!BDD 与 TDD(或 ATDD,如果您正在为整个系统执行此操作)完全相同,但没有“测试”一词。事实证明,这可能非常强大。
特别是,它允许开发人员与非技术业务人员就系统应该做什么进行对话。你也可以用它来讨论一个类应该做什么,或者一个代码模块应该做什么,即使是技术专家。
因此,在您的 REST 服务示例中,您可以想象我是一名开发人员,而您是一位知道 REST 服务应该做什么的专家。
我:应该怎么办?
你:它应该让我读一个记录。
我:太好了!你能给我一个记录的例子吗?
你:我这里有一个...
我:有没有人不应该能够阅读记录的情况?
你:当然,如果他们没有权限。...
我:好的,所以我已经完成了阅读,让我们进行更新。你能给我一个典型更新的例子吗?
你:给你。
我:太棒了,你希望它只响应成功或失败。是否有任何情况下它应该失败?
你:当然。记录显示上次更新的时间。如果同时其他人已经更新了它,那么您在提交时应该会失败。
因此,您看到您可以使用 BDD 探索各种场景,包括围绕 REST 服务的场景。诀窍是问,“你能给我举个例子吗?” 然后你会得到一个具体的例子,如果你愿意,你可以自动化。这些对话帮助我们寻找我们可能错过的其他示例和场景。
不要使用 BDD 工具为技术受众自动化!Cucumber、JBehave 等 BDD 工具使用真正的英语,这比代码更难重构。如果您只是在做类似 REST 服务的事情,请使用 JUnit、NUnit 等。你可以在评论中加上“Given, When, Then”,或者做一些 DSL。
所以现在你可以看到你的 REST 调用失败,如果我正在编码它,我会有一个像这样的例子:
我:所以,这次通话失败……你能给我举个例子吗?
你:当然,如果你访问一条已被删除的记录,它就会失败。
我:给我一个可能被删除的记录的典型示例?
你:我们之前用的那个很好。
我:好的,有没有不应该删除记录的情况?
你:是的,如果它已经出版了……
等等。
你可以看到,我并没有真正使用“测试”这个词。测试是 BDD 中的一个很好的副产品。它更多地用于需求的探索和规范。BDD 中的对话是其中最重要的部分。
很难找到将 BDD 用于 REST 的示例的原因首先是因为 REST 故意简单并且通常不会有很多行为,其次是因为 BDD 的场景通常不会根据它们的实现来表述,而是专注于服务或系统提供的价值(“读取记录”)。
TDD 和 ATDD 是完全一样的,如果他们做得好的话。就示例和场景进行对话比讨论测试更容易。