我明白ATGD和TDD之间的区别,如博客文章Classifying BDD Tools (Unit-Test-Driven vs. Acceptance Test Driven) and a bit of BDD history所述,但是这让我有一个疑问。
如上所述,没有使用BDD工具(如MSpec)只是另一个单元测试框架?在我看来,它是。
此外,这似乎表明使用SpecFlow来指定较低级别的组件(例如您的存储库和服务)将是错误的。如果我可以使用相同的工具来为ATDD和TDD的低级组件,为什么不呢?在这里似乎还有一些模糊的线条,我觉得我不太了解。
提出的一个非常重要的一点是行为驱动发展有两种。两种口味是xBehave和xSpec。
xBehave BDD:SpecFlow
SpecFlow(非常类似于Ruby堆栈中的cucumber)非常适合促进xBehave BDD测试作为验收标准。然而,它不是提供在单位级别写行为测试的好方法。还有一些其他xBehave测试框架,但SpecFlow已经获得了很大的牵引力。
xSpec BDD:NSpec
对于单位级别的行为驱动开发,我建议您使用NSpec(由RSpec直接启用)。您可以通过简单地使用NUnit或MSTest来实现单元级别的BDD …但是它们有些缺陷(这是非常难以逐步构建上下文)。 MSpec也是一个选择,已经有了很多工作,但是NSpec中只是简单的一些东西(您可以在MSpec中逐步建立上下文,但需要继承,这可能变得复杂)。
长答案
BDD的两种味道主要存在,因为它们提供了正交的益处。
xBehave的优点和缺点(GWT语法)
优点
>通过所谓的常用方言(例如,给定…,和…,当……,当……,然后….)帮助促进与业务的对话。 , 接着)
>然后可以将共同方言映射到可执行代码,证明您的业务实际完成了您所说的完成
>方言正在收缩,所以企业必须消除歧视的要求,使其适合于句子。
缺点
>虽然xBehave方法有利于驱动高级别的接受标准,但通过属性将英语映射到可执行代码所需的周期使得在单元级别上排除域不可行。
>将普通方言映射到测试是PAINFUL(在正则表达式上)。业务创建的每个句子必须通过属性映射到可执行方法。
>共同方言必须严格控制,以便管理映射不会失控。任何时候你改变一个句子,你必须找到与该句子直接相关的方法,并修正正则表达式匹配。
xSpec的优点和缺点(上下文/规范)
优点
>允许开发人员逐步建立上下文。可以为测试设置上下文,并且可以针对该上下文执行一些断言。然后,您可以指定更多的上下文(建立在已存在的上下文上),然后指定更多的测试。
>没有收缩语言开发人员对于某个系统的某些部分的行为可能更具表现力。
英文和普通方言之间无需映射(因为没有映射)。
缺点
>不如业务平易近人让我们面对它,业务不想消除他们想要的东西。如果我们给他们一个基于上下文的方法来BDD,那么这个句子只会读“Just make it work”。
>一切都在代码中。上下文文档在代码中交织在一起(这就是为什么我们不必担心将英语映射到代码)
>由于限制较少的语言,不可读。
样品
Bowling Kata是一个很好的例子。
SpecFlow样本
以下是SpecFlow中的规格说明(再次,这是一个非常好的接受测试,因为它直接与业务通信):
特征文件是测试的常用方言。
Feature: score Calculation In order to know my performance As a player I want the system to calculate my total score Scenario: Gutter game Given a new bowling game When all of my balls are landing in the gutter Then my total score should be 0
步骤定义文件
步骤定义文件是测试的实际执行,此文件包含SpecFlow的映射
[Binding] public class BowlingSteps { private Game _game; [Given(@"a new bowling game")] public void GivenANewBowlingGame() { _game = new Game(); } [When(@"all of my balls are landing in the gutter")] public void WhenAllOfMyBallsAreLandingInTheGutter() { _game.Frames = "00000000000000000000"; } [Then(@"my total score should be (\d+)")] public void ThenMyTotalscoreShouldBe(int score) { Assert.AreEqual(0,_game.score); } }
NSpec示例,xSpec,上下文/规范
这是一个NSpec的保龄球卡塔的例子:
class describe_BowlingGame : nspec { Game game; void before_each() { game = new Game(); } void when_all_my_balls_land_in_the_gutter() { before = () => { game.Frames = "00000000000000000000"; }; it["should have a score of 0"] = () => game.score.should_be(0); } }
那么是… SpecFlow很酷,NSpec很酷
随着您越来越多的BDD,您会发现需要使用xBehave和xSpec风格的BDD。 xBehave更适合接受测试,xSpec更适合单元测试和域驱动设计。
相关链接
> RSpec vs Cucumber (RSpec stories)
> BDD with Cucumber and rspec – when is this redundant?
> NSpec Project Site
> Continuous Testing
> Introduction to BDD and Mocking
> BDD using NUnit and Moq