在BDD中如何/如何模拟

Rya*_*son 22 testing bdd acceptance-testing

我知道丹北的制订BDD的意图之一是移动的词汇从测试域的复杂性了.但是,在实现从外到内的方法时,似乎我们仍然需要对模拟行为(或者如果您愿意,还是存根行为)有所了解.North在这段视频中建议,如果我从最外层的域对象开始并向内工作,我会在发现它们时模拟协作者,然后用适当的实现替换它们.所以最后,我最终得到了一系列端到端测试.

Martin Fowler似乎在这篇博文中看到了一点不同,当时他定义了两个TDD阵营:"经典TDD"尽可能使用真实对象,必要时使用模拟,而"mockist TDD"在大多数情况下更喜欢模拟.他看到BDD倾向于后者.也就是说,在开发一个功能的最后,"mockist"方法会在实际测试中留下嘲笑(很遗憾在BDD讨论中使用该词).

公平地说,这两种材料都已经存在多年了,随着BDD在单元级应用和接受级别之间的界限发展,事情也变得更加清晰.

但我对社区的问题基本上是:当我的故事完成后,我的场景实际上应该进行多少端到端测试? North 解释说BDD需要抽象.例如,当我测试登录行为时,我的方案将详细说明登录过程的含义.但是,当我正在做其他需要但不是登录的场景时,我不想一遍又一遍地执行这些步骤.我想要一个简单的抽象,简单地说"鉴于我已登录",所以我可以执行我的其他行为.

因此,我的抽象方法似乎是我模拟某些协作者(或提供"测试双重"),并且某些场景可能比其他场景更多地使用它们.例如,我是否总是模拟外部资源,例如数据库或邮件服务器?

也许我问的是错误的问题.BDD就是沟通,缩短反馈周期,发现你不知道的东西.即使我们感兴趣的行为确实有效,也许什么也不是模拟是一个无关紧要的问题.我很好奇其他人的方法是什么.

foo*_*ode 8

对我来说BDD允许我验证我已经构建了正确的东西.这意味着如果我将我的应用程序插入真实数据库并使用真实UI,它应该正常运行.那是你正在谈论的端到端.

现在,如果我将我的应用程序插入内存存储器中,并通过其API级别与应用程序通信(那么就在UI下方).我希望它的行为方式完全相同.

现在就是这样,我们需要清楚我们的行为是什么意思,当我们做BDD时我们感兴趣的行为是什么.

在我的例子中,如果我从一个用户故事开始并编写场景,我主要对通过我的应用程序API,服务层,域实体,帮助器等的行为感兴趣...主要是我不是那么感兴趣在UI和数据库中会发生什么.真正的肉是服务器端编写的所有代码.这就是我感兴趣的行为.如果你认为这样摆脱UI和数据库是有道理的,因为我们不关心这些人.UI的预期行为是显示我的应用程序提供的数据.用户界面是一个愚蠢的事情.DB的预期行为是存储和检索应用程序提供或想要的实体.这也是一件非常愚蠢的事情.现在其他一切,这就是所有的聪明才智,我负责.

因此,我很乐意在没有UI的情况下运行我的BDD场景,并使用内存版本的存储库.我从中获得的奖励实际上是非常快速,专注和可维护的测试.

关于UI和数据库,我会编写javascript单元测试来测试那里的行为,今天一些UI可以有很多隐藏和显示东西的显示逻辑,但这种行为不同于我的用户故事中的行为bdd场景(他们不应该谈论UI).

对于DB,我会编写集成测试,以检查我的真实存储库是否能够在DB上读写内容.

最后,我只编写了一些端到端测试,以便在连接在一起时检查一切正常.


Sax*_*att 7

我认为关键是关注BDD的B - 行为.

目前我倾向于忽略UI元素并模拟持久层 - 在这些日子之后,这些层中几乎没有任何业务逻辑(我们倾向于使用预先存在的和直接将对象模型绑定到UI或DB)经过严格测试的框架).

作为一个例子,在我正在构建的最近(简单)WPF应用程序中:验收测试使用ViewModel作为应用程序的入口/外部点 - 并且数据存储库中的所有内容都被模拟.应用程序的所有规则和逻辑都存在于两者之间 - 实际上,这些是应用程序需要指定和测试的行为.