我刚刚进入BDD的概念,并听取了Scott Bellware与Herding Code人员的谈话.我一直在玩SpecFlow,并且非常喜欢它.
我理解ATDD和TDD之间的区别,如博客文章分类BDD工具(单元测试驱动与接受测试驱动)和一些BDD历史中所述,但这引出了一个问题.
如上所述,是不是使用BDD工具(如MSpec)只是另一个单元测试框架?在我看来它是.
此外,这似乎表明使用SpecFlow来规划较低级别的组件(例如您的存储库和服务)将是错误的.如果我可以将同一工具用于较低级别组件的ATDD和TDD,为什么我不应该?这里似乎仍然有一些模糊的线条,我觉得我不太了解.
Ami*_*mir 29
提出一个非常重要的一点是,行为驱动开发有两种风格. 这两种口味是xBehave和xSpec.
SpecFlow(非常类似于Ruby堆栈中的黄瓜)非常适合将xBehave BDD测试作为Acceptance Criteria.然而,它并没有提供在单元级别编写行为测试的好方法.还有一些其他xBehave测试框架,但SpecFlow已经获得了很大的吸引力.
对于单元级别的行为驱动开发,我建议使用NSpec(直接受RSpec for Ruby 启发).您可以通过简单地使用NUnit或MSTest来完成单元级别的BDD ...但它们有点不足(很难逐步建立上下文). MSpec也是一个选项,已经有很多工作,但在NSpec中只有一些简单的东西(你可以在MSpec中逐步建立上下文,但它需要继承,这可能变得复杂).
两种BDD主要存在,因为它们提供了正交的好处.
该保龄球卡塔是一个很好的例子.
以下是规范在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);
}
}
这是同一个保龄球kata 的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);
}
}
当您执行越来越多的BDD时,您会发现需要BDD的xBehave和xSpec风格.xBehave更适合验收测试,xSpec更适合单元测试和域驱动设计.
Chr*_*ken 11
真正的行为驱动工具就像Cucumber.我们在针对.NET代码的工作中使用它.这允许我们编写定义系统整体行为的功能,然后我们可以执行这些功能并验证系统是否符合我们的预期.整个过程对我们来说非常有效.
有一个名为NStep的.net实现,它通过有线协议连接到黄瓜,它允许你使用lambdas在C#中编写步骤定义...它非常棒.
步骤定义如下所示:
When("^I go to the \"([^\"]*)\" (?:[Ss]creen|[Pp]age)$", (string pageName) =>
{
var screen = ParseScreen(pageName);
GoToScreen(screen);
World.Browser.Wait(1000);
});
Run Code Online (Sandbox Code Playgroud)
http://github.com/clearwavebuild/nStep