什么时候使用 BDD,什么时候只进行单元测试?

When to use BDD and when just unittests?

我的任务是为未来的 Django Channels+DRF 项目编写测试,不要问为什么(我们现在只有 swagger 文档)。所以测试必须测试用户用例(比如可能很复杂的场景)。我对此进行了研究并发现了 BDD。这是一个问题,考虑到我们的项目以后也可能有简单的单元测试我应该使用什么,即 BDD 看起来不错但我认为它可能过度使用并且可能有一种方法可以为用户用例场景编写单元测试我可以做到这一点。有没有人有这方面的经验?如果能提供文章和代码示例就更好了

场景与用例有点不同。一个用例通常涵盖多个功能。例如,在简单的洗衣用例 shown here 中,管家在洗衣服时会做几件事:

  • 洗涤每件衣物
  • 烘干每件衣物。
  • 折叠某些物品
  • 熨烫一些物品

所有这些都进入 "weekly laundry" 用例。

BDD 中的场景更加精细。它描述了在特定上下文或一组上下文中发生的 one 能力。所以例如你可能有:

Given the weekly laundry has been washed and dried
And it contains several sheets
And some underpants
When the housekeeper does the folding
Then the sheets should be folded
But the underpants should not.

您可以看到我们跳过了几个功能。这个场景着重于 folding 的能力,并展示了一个乖巧的管家是如何做到的。洗涤和干燥必须在不同的场景中涵盖。

这就是用例和场景之间的区别。现在让我们看一个单元测试。

当我们写代码时,我们不会把它全部写在一个大 class 或函数中。我们把它分成小块。与场景从用户的角度描述系统的行为示例相同,单元测试描述[=104=的行为] 或其他从用户角度来看的一小段代码 - 通常是其他 classes!

让我们假设我们在一个汽车购买网站上。我们有几个能力:

  • 身份验证
  • 正在搜索汽车
  • 买车
  • 列出汽车
  • 正在从列表中删除一辆车

其中每一个都有 很多 个不同的 class 组成。甚至搜索汽车也可能涉及前端、搜索组件、汽车数据库、持久层、网络服务器等。对于每一段代码,我们都描述了该代码的行为。

(BDD 实际上是从这个级别开始的;通过示例说明 classes 的行为方式 - JBehave 旨在取代 JUnit。但 JUnit 变得更好,我们不再需要这一点了。我仍然发现将这些视为示例而不是测试很有帮助。)

通常我的代码库中会有两种场景单元测试;其中一组从用户/利益相关者的角度看待整个系统,另一组更详细地描述了我的 classes。

这些场景帮助我展示了系统的行为方式以及它的价值所在。单元测试帮助我实现良好的设计和分离职责。他们都提供活文档,这有助于保持系统的可维护性,并使新手更容易上手。

通常我是这样编程的:

  • 我对自己想要达到的目标有一个大概的了解
  • 我和别人谈过并写下一些场景
  • 如果我们不太清楚我们在寻找什么,我会找到一些有用的东西(尖峰)
  • 一旦我们更好地理解了我们正在寻找的东西,我会首先自动化场景
  • 我以最简单的情况开始写 UI
  • 当 UI 需要另一个 class 工作时,我写了一些代码应该如何工作的例子(单元测试)first
  • 然后我写代码(或者重构它,因为尖峰很乱)
  • 当该代码需要另一个 class 才能工作时,我会写一些它的示例
  • 如果我在单元测试中没有任何时候需要的代码,我会使用模拟。

通常我们将场景和单元测试放在不同的地方。

您可以看到我如何完成此操作的一些示例 here。这是一款俄罗斯方块游戏,其场景通过 UI 和较低级别的单元测试来自动化整个游戏,这些单元测试描述了特定部分的行为,例如心跳使形状下降。

话虽如此 - 如果您的代码库非常简单,您可能只需要场景或单元测试即可;你可能不需要两者。但是,如果它开始变得更加复杂,请考虑重构并添加您需要的任何内容。务实一点也行,只要容易改就行。