【问题标题】:Nunit Framework vs SpecFlow FrameworkNunit 框架与 SpecFlow 框架
【发布时间】:2015-11-25 13:43:23
【问题描述】:

我是 NUnit 新手,对 SpecFlow 测试框架和 NUnit 测试框架感到困惑。

现有项目使用 NUnit,如下所示。所有具有 [Test] 属性的方法都显示在 NUnit GUI 中(如果我从方法中删除 [Test],则测试用例不会显示在 NUnit GUI 中):

[TestFixture]
public class AccountTest
{
  [Test]
  public void TransferFunds()
  {
    Account source = new Account();
    source.Deposit(200m);
  }

  [Test]
  public void TransferWithInsufficientFunds()
  {
  }
}

当我在同一个项目中使用 SpecFlow 进行编码时,SpecFlow 框架是不同的,从 [Given]、[When]、[Then] 开始。每个 SpecFlow 场景都显示在 Nunit GUI 上。

我正在做的是将每个 [Test] 方法替换为一个 SpecFlow 方法。 例如:

[Test]
public void TransferFunds()
{
  Account source = new Account();
  source.Deposit(200m);
}

转向

[Then(@"I Transfer Funds")]
public void ITransferFunds()
{
  Account source = new Account();
  source.Deposit(200m);
}

这是我的问题:

  1. 看起来 SpecFlow 无法识别 NUnit 属性 [Test] 或 [Setup]。用SpecFlow做项目,是不是需要去掉所有的NUnit框架,换成SpecFlow的框架?

  2. 我可以看到有很多文章在谈论“SpecFlow + NUnit”,但它们要么是 SpecFlow [Given]、[When]、[Then],要么是 NUnit [Test]、[TestCase]。如何使两者在一个项目中工作还是我对 NUnit 的理解完全错误?

我的问题可能非常入门,感谢您的回答!

【问题讨论】:

    标签: c# nunit specflow


    【解决方案1】:

    我需要摆脱所有 NUnit 框架并用 SpecFlow 的框架替换吗?

    我认为您需要了解的第一件事是NUnitSpecFlow 并不相互排斥。

    SpecFlow作为一个整体有很多组件,但是你现在需要了解的是SpecFlow是用来将Gherkin写的特征文件绑定到C#可以通过测试运行的代码亚军。 C# 代码有两部分,一个是自动生成的,另一个是您和您的团队编写的。


    您编写的部分是具有GivenWhenThen 属性的方法。它们是步骤定义(阅读更多here)。这些绑定需要遵循以下规则:

    • 必须在公共类中,并用[Binding] 属性标记。
    • 必须是公共方法。
    • 可以是静态方法或实例方法。如果是实例方法,则包含 >* 的类将在每个场景中实例化一次。
    • 不能有 out 或 ref 参数。
    • 不能有返回类型。

    自动生成的部分生成使用NUnitMSTestxUnit 以及其他可用的unit test providers 编写的测试方法。如您所见,使用相同的 Gherkin(herehere)您最终会得到不同的自动生成文件(herehere


    我们来看一个具体的场景(source

    Scenario: One single spare
        Given a new bowling game
        When I roll the following series:   3,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
        Then my total score should be 29
    

    如果单元测试提供程序是NUnit,该步骤将生成以下测试方法 (source):

    [NUnit.Framework.TestAttribute()]
    [NUnit.Framework.DescriptionAttribute("One single spare")]
    public virtual void OneSingleSpare()
    {
        TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("One single spare", ((string[])(null)));
    #line 7
        this.ScenarioSetup(scenarioInfo);
    #line 8
        testRunner.Given("a new bowling game");
    #line 9
        testRunner.When("I roll the following series:\t3,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1");
    #line 10
        testRunner.Then("my total score should be 29");
    #line hidden
        testRunner.CollectScenarioErrors();
    }
    

    如果单元测试提供程序是xUnit,该步骤将生成以下测试方法 (source):

    [Xunit.FactAttribute()]
    [Xunit.TraitAttribute("FeatureTitle", "Score Calculation (alternative forms)")]
    [Xunit.TraitAttribute("Description", "One single spare")]
    public virtual void OneSingleSpare()
    {
        TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("One single spare", ((string[])(null)));
    #line 7
        this.ScenarioSetup(scenarioInfo);
    #line 8
        testRunner.Given("a new bowling game");
    #line 9
        testRunner.When("I roll the following series:\t3,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1");
    #line 10
        testRunner.Then("my total score should be 29");
    #line hidden
        testRunner.CollectScenarioErrors();
    }
    

    无论您使用什么单元测试提供程序,您的步骤定义方法看起来几乎*相同(如您所见here for NUnithere for xUnit)。

    您可以使用几种不同的步骤定义样式。他们被描述为here

    *唯一的区别可能是你的断言。

    【讨论】:

    • 非常感谢,我现在对 specflow 有了更深入的了解
    • 我的回答@Yan 中是否有我没有涵盖的内容?
    • 指向GitHub 项目的所有链接 - 已损坏。 :-(
    • 哦,很抱歉 @itsho ,会尽快修复
    【解决方案2】:

    您需要了解的是,Specflow 是一个单元测试生成框架。您使用 gherkin 语法编写功能文件,然后创建使用 [Given], [When] and [Then] 属性的绑定方法,然后 specflow 使用这些方法在您想要使用的任何类型的单元测试框架(NUnit、MSTest、XUnit 等)中生成单元测试)

    一旦开始使用 specflow,就不应将其与“原始”NUnit 属性混用,这只会导致混淆和难以调试的问题。对 Specflow 进行更改并让它管理测试的生成

    【讨论】:

      猜你喜欢
      • 2018-02-21
      • 1970-01-01
      • 2011-12-24
      • 1970-01-01
      • 2021-08-06
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多