tdd - ATDD与BDD以及框架的正确使用

标签 tdd bdd specflow

我只是进入BDD的概念,并听过Scott Bellware与Herding Code团队的谈话。我一直在玩SpecFlow,并且非常喜欢它。

我了解博客文章Classifying BDD Tools (Unit-Test-Driven vs. Acceptance Test Driven) and a bit of BDD history中描述的ATDD和TDD之间的区别,但这使我提出了一个问题。

如前所述,使用BDD工具(例如MSpec)不只是另一个单元测试框架吗?在我看来是这样。

此外,这似乎表明使用SpecFlow来确定较低级别的组件(例如您的存储库和服务)将是错误的。如果我可以对较低级别的组件的ATDD和TDD使用相同的工具,为什么不呢?这里似乎仍然有些模糊的线条,我觉得我不太了解。

最佳答案

快速解答

值得一提的非常重要的要点是行为驱动开发有两种风格。 两种口味是 xBehave xSpec

xBehave BDD:SpecFlow

SpecFlow(非常类似于Ruby堆栈中的cucumber)在促进xBehave BDD测试作为验收标准方面非常出色。但是,它不能提供在单元级别编写行为测试的好方法。还有其他一些xBehave测试框架,但是SpecFlow吸引了很多人。

xSpec BDD:NSpec

对于单位级别的行为驱动开发,我建议使用NSpec(由Ruby的RSpec直接启发)。您可以通过简单地使用NUnit或MSTest在单元级别上完成BDD ...但是它们有点不足(确实很难逐步建立上下文)。 MSpec也是一个选项,已经投入了很多工作,但是在NSpec中有些东西只是简单的(您可以在MSpec中逐步建立上下文,但是它需要继承,而继承会变得很复杂)。

长答案

BDD的两种味道主要是因为它们提供的正交利益而存在。

xBehave的优缺点(GWT语法)

优点

  • 通过称为(例如,给定....,给定....,何时......,何时.....,然后....)的通用方言帮助促进与企业的对话。 ,然后)
  • 然后可以将常用方言
  • 映射到可执行代码,该代码向企业证明您实际上完成了您说的内容
  • 的方言有局限性,因此企业必须消除歧义,并使其适合句子。

  • 缺点
  • 虽然xBehave方法适合于驱动高级接受标准,但通过属性将英语映射到可执行代码所需的周期使得在单元级别驱逐域变得不可行。
  • 将常用方言映射到测试是PAINFUL(在正则表达式上增强)。企业创建的每个句子都必须通过属性映射到可执行方法。
  • 必须严格控制通用方言,以免管理映射。每次更改句子时,都必须找到与该句子直接相关的方法并修复正则表达式匹配。

  • xSpec的优缺点(上下文/规范)

    优点
  • 允许开发人员逐步建立上下文。可以为测试设置上下文,并且可以针对该上下文执行一些断言。然后,您可以指定更多上下文(在已经存在的上下文基础上),然后指定更多测试。
  • 没有限制语言。开发人员可以对系统的特定部分表现得更具表现力。
  • 不需要英语和普通方言之间的映射(因为没有这种映射)。

  • 缺点
  • 企业难以接受。让我们面对现实吧,企业不希望歧义他们想要什么。如果我们为他们提供了基于上下文的BDD方法,那么该句子将显示为“Just make it work”。
  • 一切都在代码中。上下文文档在代码中交织在一起(这就是为什么我们不必担心将英语映射到代码)
  • 由于限制较少,所以不易读。

  • 样品

    Bowling Kata是一个很好的例子。

    SpecFlow样本

    这是SpecFlow在SpecFlow中的外观(再次,这很适合作为验收测试,因为它可以直接与业务进行通信):

    功能文件

    功能文件是测试的常用方言。

    功能:分数计算
    为了了解我的表现
    作为一名球员
    我希望系统计算我的总成绩

    场景:装订线游戏
    有了新的保龄球游戏
    当我所有的球都落入水槽时
    那我的总分应该是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,您会发现BDD的xBehave和xSpec flavor 都是必需的。 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
  • 关于tdd - ATDD与BDD以及框架的正确使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3359327/

    相关文章:

    specflow - 为 vs2013 mssing TechTalk.SpecFlow 引用安装specflow

    testing - Arquillian - 如何调试托管的 Wildfly 容器

    python - 我应该如何指示尚未用 Python 编写测试?

    c# - Specflow:具有不同可配置步骤的相同场景

    unit-testing - 那里有哪些 'styles' 测试框架?

    javascript - 毕竟 Hook 错误 - 使用 cucumber-js 和 selenium 时 'this' 并未引用我的世界构造函数

    c# - Specflow 和 HttpSelfHostServer

    c# - 结合 SpecFlow 表和 Moq 模拟对象

    ruby-on-rails - 如何使用 DCI 模式测试行为?

    unit-testing - 测试概率函数