65.9K
CodeProject 正在变化。 阅读更多。
Home

迎接行为驱动开发 (BDD) - 第二部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.74/5 (38投票s)

2011年1月26日

CPOL

7分钟阅读

viewsIcon

223672

downloadIcon

1027

本文包含使用 Specflow 和 MBUnit 在 .NET 项目中实现 BDD 的分步说明。

引言

这是“认识行为驱动开发”系列两部分文章的第二部分。

本系列的第一部分是 认识行为驱动开发 (BDD)- 第一部分

在本文中,我将尝试向您展示如何在实际开发任何模块或项目时遵循 BDD。请注意,本文将仅侧重于展示在实际项目中使用 BDD 方法论的路径,而不是 100% 完全使用 BDD 开发的项目。
我附带了一个 .NET 项目的骨架(在此作为 UI 组件,我使用了 WPF),该项目已按照以下步骤开发。

背景

归根结底,要实现 BDD,您需要编写一些单元测试代码,并且需要一个支持单元测试的工具,如 NUnit、MSTest(集成到 Visual Studio 中)或任何您喜欢的其他工具。在此示例中,我将使用 MBUnit。但您可以自由使用任何您喜欢的此类工具。
为了将 Gherkin 转换为单元测试代码,我将使用 SpecFlow。我喜欢 Specflow,因为它是迄今为止我见过的最酷的 .NET BDD 工具。

对于 IDE,我将使用 Visual Studio 2010。我很幸运拥有 ReSharper 的许可证,并且在此示例中,我将借助 ReSharper,因为它提供了一些集成的测试输出结果。如果您没有 ReSharper,请不要担心,因为我只使用了该工具来简化某些步骤。当然,您可以在没有 Resharper 的情况下继续。

表演开始!

请系好安全带,我们要起飞了!

由于我们将按照行为驱动开发来开发内容,因此首先,我们应该在 Gherkin 中获得一些需求。所以这里有一个简单的需求。

Given that we have a search form that searches over Name, Address and Profession table 
When The user enters non empty text 
And the length of the text is more than 3 alphanumeric character long 
Then The user will get the search result 
And if the search result is empty he will get an message box asking him 
to do the search again.

第一步

因此,让我们打开 Visual Studio 2010 并创建两个类库项目,如下所示

Step_1.png

由于我们是从头开始创建一切的,所以我们创建了两个项目。SearchSpec 主要将包含从 Gherkin 到 CS 的规范代码。请仔细注意,项目名称是SearchSpec 而不是SearchTest,因为我们将编写行为或规范而不是测试。

我们还有另一个名为 SearchModule 的类库项目,它将包含满足我们规范的所有必要代码。

第二步

我们将在 SearchModule 项目中添加一个配置文件,如下所示

Step_2--1.png

之后,我们将以下配置粘贴到App.Config文件中

<?xml version="1.0"?>
<configuration>
 <configSections>
    <section name="specFlow" 
      type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow"/>
 </configSections>
 <specFlow>
    <unitTestProvider name="MbUnit"/>
 </specFlow>
 <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
 </startup>
</configuration>

Step_2--2.png

粘贴此内容后,App.config 文件将如下所示。第一个配置节与 Specflow 相关,第二个配置节与我们将使用的单元测试工具相关。如图片所示,您可以使用任何您喜欢的单元测试工具。

我们使用此配置文件是因为当 Gherkin 被转码为 CS 代码时,它是根据配置文件中提到的单元测试工具编写的。

第三步

现在我们将添加一个 Feature 文件。由于 SpecFlow 假定已安装,因此在 Visual Studio 中我们将获得 3 个额外的 SpecFlow 模板。在这 3 个模板中,我们将选择 Feature 文件,如下所示。我们将它命名为Search.feature 并按 OK。

Step_3--1.png

Visual Studio 将为我们创建两个文件。一个 feature 文件包含 Gherkin 中的规范功能,一个与 feature 文件关联的代码隐藏文件,其中包含与 feature 相关的已生成 C# 代码,即 Gherkin 的 C# 表示形式,如下所示。请注意,每当 Visual Studio 创建任何 feature 文件时,它都会提供一个与某些数学相关的虚拟 feature。

Step_3--2.png

Needless to say here, you need to add necessary reference of Spec Flow, Gallio and MBUnit in your project like below that can be found in their respective installation folder.

Step_3--3.png

第四步

现在,我们将更改 feature 文件的内容以适应我们的简单规范。我们只需将规范粘贴到那里并保存 feature 文件。保存 feature 文件后,相应的 CS 代码将在代码隐藏文件中生成。很酷,不是吗?feature 文件和代码隐藏文件将如下所示

Step_4.png

第五步

我们已经用 CS 编写了 feature。现在我们需要另一个级别的抽象,以便可以为我们的 feature(当然还有feature.cs)文件中描述的每个步骤进行定义。(看,我没有使用“test”这个词。我本来可以写“以便每个步骤都可以被测试”。由于我们使用的是 BDD,我们将通过定义步骤来开发我们的 feature,而不是定义测试!)

幸运的是,Specflow 为我们提供了一个创建步骤定义的文件模板。所以我们将添加一个名为SearchStepDefination.cs的步骤定义文件,如下所示

Step_5--1.png

但一旦生成了步骤定义文件,您会再次看到一些与数学相关的预加载代码,这与我们的 feature 完全无关。如下所示,删除这些虚拟代码是显而易见的。但是问题是,我如何编写步骤定义,因为我不知道如何编写步骤定义。(一个阻塞状态!!!)

Step_5--2.png

别担心!我们有一个简单的解决方案,这段代码也将由 SpecFlow 引擎生成,但方式并不寻常!让我一步一步地向您展示如何根据 feature 生成步骤定义(是的!这些是一些子步骤)。

  1. 首先,删除SearchStepDefinition 类中的所有代码,使其看起来像
    [Binding]
    public class SearchStepDefinition
    {
    }
  2. 然后运行Search.Feature.cs文件中的单元测试。如果您安装了 re-sharper,您会在 SearchingInDataBaseTables 方法旁边获得一个上下文菜单。否则,如果您使用的是 VS 2010 Ultimate,您可以通过单击**Test->Run->Test in Current Context** 来运行单元测试。如果您两者都没有,请按照您在 IDE 中运行单元测试的方式进行操作。运行单元测试后,请查看测试结果输出窗口,它将类似于以下内容

    Step_5--3.png

    我知道此刻您正在微笑。正如您所注意到的,输出窗口正在告诉您需要在步骤定义文件中实现哪些函数,并附带正确的签名!

  3. 这是最后一个子步骤。您所要做的就是将输出窗口中的函数复制到我们的步骤定义文件中。之后,我们的步骤定义文件将如下所示

    Step_5--4.png

第六步

我们的基础已经创建,现在我们可以通过纯粹的 BDD 开始开发了。我们现在将编写每个步骤定义方法的正文,并在编写此内容时,我们将实际编写与原始开发相关的代码。

让我们专注于第一个方法。

[Given(@"that we have a search form that searches over Name, Address and Profession table")]
public void GivenThatWeHaveASearchFormThatSearchesOverNameAddressAndProfessionTable()
{
    ScenarioContext.Current.Pending();
}

为了编写这个方法的正文,我们需要创建一个表单,该表单将从用户那里获取输入。所以我们需要一些占位符来包含输入文本。因此,我们将在 SearchModule 项目下创建一个类。该类将如下所示

namespace SearchModule
{
 public class UserInput
 {
   public string Input { get; set; }
 }
}

我们还需要创建一个表单。为此,我们可以在同一解决方案下创建另一个项目。我将选择一个 WPF 项目,这样我们就有一个 WPF 窗口,其中包含一个文本框和一个搜索按钮,它看起来会像这样

Step_6--1.png

现在我们需要一个能够搜索NameAddressProfession 表的类。所以我们接下来的步骤将是

  1. 为了搜索数据库表,我们需要编写一些 SQL、Linq 2 SQL 或一些存储过程。
  2. 我们需要编写一些数据访问层代码来处理此搜索。
  3. 搜索将返回一个对象列表,该列表将包含姓名、地址和职业信息。所以我们需要创建一个类来保存这些属性。

我不会向您展示如何完成上述 3 个步骤,因为这些是您日常生活中最简单的任务。

结论

正如您所看到的,我们现在正在尝试创建类和变量,只是为了满足步骤定义函数,并且一步一步地,我们实际上正在创建我们的模块,以满足项目的行为(即规范),从而我们已经开始按照行为驱动开发方法论来开发一个模块。

我本可以再写几百行代码来完成一个完整的 BDD 模块,但我的目标是向您展示一条道路,最终将引导您在自己的项目中实现 BDD。

我希望您已经掌握了从下一个项目开始行为驱动开发的基本思路和技巧。祝您一切顺利!!

© . All rights reserved.