SpecFlow 快速指南



SpecFlow - 简介

SpecFlow 是一个基于 BDD 模型构建的开源测试自动化工具。它主要用于为 .NET 构建的项目构建自动化测试。本教程将提供有关 SpecFlow 及其功能的知识。

Spec-Flow 主要用于构建、监控和运行人类可读的验收测试用例。它使用 **Gherkin** 创建,Gherkin 是一种纯文本语言。SpecFlow 具有 Gherkin 解析器,可以运行 70 多种语言。我们可以通过 SpecFlow 的内置测试运行器和 **SpecFlow+ Runner** 执行我们的测试。

组件

SpecFlow 的主要任务是绑定用 Gherkin 编写的特性文件。SpecFlow+ Runner 是一个测试运行器,它具有执行功能和报告生成功能。它也是免费的,我们需要为此创建一个 SpecFlow 帐户。

**SpecFlow+ LivingDoc** 是一组工具,可使 Gherkin 特性文件保持可读格式。这可以与团队中不熟悉 Visual Studio 等工具的利益相关者共享。

**SpecFlow+ LivingDoc** 生成器是一组用于 SpecFlow 的插件和工具,用于从 Gherkin 特性文件生成文档。这不需要创建帐户,并且可以轻松地与他人共享。

**SpecFlow+ LivingDoc Azure DevOps** 允许在 **Azure DevOps/TFS** 中查看输出。任何拥有系统访问权限的用户都可以在需要时查看规范。它是免费的,但需要一个 SpecFlow 帐户。

在 Visual Studio 扩展中编辑特性

此外,SpecFlow 还具有 **Visual Studio 扩展**,提供以下附加功能:

步骤和关键字的智能感知(自动完成)

为了方便使用 SpecFlow,智能感知提供了在键入时查找以限制建议列表的功能。智能感知可用于 Gherkin 文件、其关键字和代码文件。

在 Visual Studio 中,单击“编辑”,然后选择“智能感知”以获取各种选项。

Intellisense

下图显示了 Gherkin 文件中的智能感知。

Intellisense Gherkin

Gherkin 语法高亮显示

突出显示关键字、标签、注释、无界(紫色)步骤、有界(黑色)步骤、有界步骤参数(灰色斜体)。

特性文件大纲和注释

在 Visual Studio 中,“编辑”菜单中的大多数项目都可以为 SpecFlow 中的特性文件添加价值。我们可以使用 # 字符或内置快捷方式(如 **CTRL+K CTRL+V 或 CTRL+K + CTRL+V**)注释和取消注释特定行。

从“编辑”菜单中有多个选项可自定义特性文件的各个部分。

单击“编辑”,然后选择“大纲”选项。

我们可以定义自己的特性文件模板,在创建新测试用例时打开。

Intellisense case

格式化表格

我们可以修改表格大小,并在键入列名并输入其值时自动格式化表格。

Formatting Tables

但是 SpecFlow 不仅限于 Visual Studio,它也可以与 Mono 和 VSCode 一起使用。

SpecFlow - 测试驱动开发

**测试驱动开发** 也称为 TDD。它包含以下步骤,需要逐一执行:

**步骤 1** - 创建测试。

**步骤 2** - 验证测试是否失败。

如果测试通过,则创建第二个测试。

如果测试失败,则转到步骤 3。

**步骤 3** - 修复测试以使其通过。

如果测试通过,则转到步骤 4。

如果测试失败,则跳转到步骤 3。

**步骤 4** - 开始代码重构并重复所有上述步骤,直到开发完成。

TDD 的好处

TDD 的好处如下:

  • 开发人员需要理解需求,以了解场景的结果应该是什么以及如何测试它。

  • 仅当所有测试用例通过且代码重构完成时,才会执行模块的实现。因此,在将其移至下一个测试之前,应先进行验证和重构。

  • 完成重构后,需要运行单元测试套件。

  • 单元测试可以用作实时文档。

  • 如果发现错误,则会创建一个测试以获取错误的详细信息。脚本将更新以通过测试。同时,还执行其他测试以确保修复不会破坏现有功能。

  • 开发人员可以参与设计决策并在测试执行阶段随时对其进行改进,以确保应用程序正常工作。这样做是为了提高产品的可维护性。

  • 开发人员可以确定是否进行任何修改。这是因为,如果这影响了任何现有功能,它将通过执行测试反映出来。这样可以快速解决错误。

  • 通过连续运行测试,所有先前的错误修复也将得到验证,并且可以避免类似的错误。

  • 由于在开发阶段进行了主要测试,因此在交付之前所需的测试时间很短。

TDD 的缺点

TDD 的缺点如下:

  • 开发人员难以决定何时开始测试。

  • 开发人员对要测试什么感到困惑。

  • 开发人员不知道是否涵盖了所有需求规范。

  • 开发人员不确定他们的代码是否增加了业务价值。

围绕 TDD 的误解

围绕 TDD 的误解如下:

误解

事实

TDD 仅关注自动化测试。

TDD 是一种遵循测试优先方法的开发技术。

TDD 不包括设计。

TDD 具有根据需求进行的彻底研究和设计。设计在开发阶段完成。

TDD 仅用于单元测试。

TDD 也用于系统和集成测试。

TDD 无法用于正统的测试项目。

TDD 用于敏捷开发。但它也可以用于传统的测试项目。

TDD 被认为是一种工具。

TDD 是一种开发技术,每次新的单元测试通过后,它都会与自动化套件结合,只要代码发生修改并在重构活动后运行。

SpecFlow - 行为驱动开发

**行为驱动开发** 也称为 BDD,具有以下**特性**:

  • 提供共享的方法和工具,帮助建立开发人员、业务分析师和其他利益相关者之间的互动,共同努力进行产品开发。

  • 确保交付的产品增加了必要的业务价值。

  • 找出系统的功能以及如何开发它。

  • 确保产品具有良好的外观和结构。

  • 检查软件的功能,并确保满足最终用户的期望。

BDD 方法

BDD 采用的主要方法如下:

基于示例的规范

它在交互中使用示例来描述软件特性及其业务场景。这种方法有助于消除开发人员、测试人员、产品负责人、业务分析师和团队中所有其他利益相关者之间对业务需求的任何知识差距。

测试驱动开发

在 BDD 的参考中,测试驱动开发将示例转换为纯文本和可执行规范。开发人员在实现新功能时将此作为文档参考。它有助于开发一个适当的代码库以及一个回归套件。因此,在整个产品生命周期中,总体维护成本降低。

BDD 工具

SpecFlow 是一个开源的 BDD 工具之一。它包含一个遵循 **Gherkin** 语法的**特性**文件。SpecFlow 的源代码托管在 GitHub 上。它主要用于为 .NET 构建的项目构建自动化测试。在功能上类似于 **Cucumber**。

SpecFlow 中特性文件的结构:

BDD Tool

它包括特性、背景场景和两个场景。特性文件包含应用程序中特性的验收标准。

SpecFlow - Visual Studio 安装

在本章中,我们将了解 Visual Studio 的安装过程和项目配置。

安装

导航到以下链接: https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx

对于 Visual Studio 的社区版,请单击“社区”部分下的“免费下载”。

Visual Studio Installation

一个 .exe 文件将下载到我们的系统中。双击它。

Visual Studio Downloaded

**Visual Studio 安装程序** 弹出窗口出现。单击“继续”。下载和安装过程开始。

Visual Studio Installer

安装完成后,选择.NET 桌面开发选项。然后点击安装

Desktop Development

软件包的下载和安装将开始。

Desktop Packages

完成后,点击重新启动

Desktop Restart

从开始菜单中,输入Visual Studio。

Desktop Type

点击Visual Studio,将出现欢迎屏幕。

Desktop Welcome Screen

同时,Visual Studio弹出窗口也会出现。如果您没有现有的

帐户,请点击现在不,以后再说链接并继续。

Desktop Pop-up

选择主题颜色,然后点击启动Visual Studio

Desktop Colour

项目配置

打开Visual Studio登录页面后,点击创建新项目

Desktop Configuration

我们将创建一个新的C#类库。在搜索框中输入class library core。选择类库(.NET Core)选项,然后点击下一步

Class Library Core

指定项目名称和位置,然后点击创建

Class Library Location

项目的代码实现

using System;
namespace ClassLibrary2 {
   public class Class1 {
      public int Number1 { get; set; }
      public int Number2 { get; set; }
      public int Subtraction() {
         throw new NotImplementedException();
      }
   }
}

要构建此解决方案,请转到生成菜单,然后选择生成解决方案

Build Solution

将显示生成成功的消息,我们已成功在Visual Studio中创建了一个项目。

SpecFlow - Visual Studio扩展安装

如前所述,Visual Studio扩展允许添加许多测试自动化所需的功能。此扩展适用于Visual Studio 2017和2019。

安装

打开Visual Studio并导航到扩展菜单,然后点击管理扩展选项。

Manage Extensions

管理扩展弹出窗口出现。在搜索框中输入SpecFlow。搜索结果填充后,点击下载

Manage Box

下载完成后,我们需要重新启动Visual Studio。安装完成后,如果我们再次转到管理扩展弹出窗口,可以在已安装选项卡中找到此扩展。

此外,我们现在可以找到禁用卸载SpecFlow的选项。点击关闭退出。

Manage Uninstall

SpecFlow - 项目设置

现在,我们将在之前构建的同一个项目中创建一个SpecFlow项目。

项目创建

右键点击解决方案资源管理器部分。点击添加选项。然后选择新建项目

Project Creation

在搜索框中输入SpecFlow,由于搜索结果,SpecFlow项目将显示。点击下一步继续。

Project proceed

输入项目名称和位置,然后点击创建

Project Create

创建新的SpecFlow项目弹出窗口的测试框架下拉列表中选择SpecFlow+ Runner选项。然后点击创建

Project Runner

解决方案资源管理器现在将有一个名为SpecFlowProject1的新项目创建。

Project Runners

项目文件夹

创建SpecFlow项目后,我们还会发现为该项目创建了一个定义良好的文件夹结构,其中包含驱动程序、依赖项、功能、钩子等等。

Project Dependencies

SpecFlow - 其他项目依赖项

我们需要为SpecFlow项目创建对我们创建的类库的项目引用。这对于测试项目中类库中的类非常重要。

添加项目依赖项

解决方案资源管理器中点击SpecFlowProject1项目。然后右键点击文件夹依赖项。选择添加项目引用选项。

Add Project Reference

引用管理器弹出窗口打开。选中类库的复选框,然后点击确定

Reference Manager

构建和运行测试

接下来,转到生成菜单并选择生成解决方案。我们应该获得生成成功的消息作为输出。

Build Succeeded

导航到测试菜单并选择测试资源管理器选项。

Build Menu

我们应该能够找到添加到SpecFlow项目的特性。通过在视图中运行所有测试选项执行它们。执行状态显示为未运行,因为测试尚未执行。

Not Run

特性之前的感叹号表示该特性的测试执行正在等待。

Exclamation Symbol

SpecFlow - 运行器激活

我们必须执行SpecFlow + Runner的激活。导航到视图菜单,然后选择输出选项。

Navigate

然后在显示来自下拉列表中选择测试

我们应该获得测试输出以及运行程序的激活链接。只有在项目设置时选择了SpecFlow+ Runner,我们才能获得此链接。

Activation Link

激活链接

在浏览器上打开激活链接。我们应该导航到SpecFlow登录页面。点击使用Microsoft登录

Landing Page

点击,允许Microsoft访问我们的SpecFlow帐户。

Microsoft Access

要设置帐户,请提供所需的信息。然后点击创建帐户

Microsoft Account

我们现在将成功激活SpecFlow帐户。

Microsoft Account Activated

现在,如果我们再次从文本资源管理器执行测试,它将显示正确的结果。

SpecFlow - HTML 报告

当所有测试执行完成后,SpecFlow会生成报告,其中包括测试结果的细目。

从资源管理器运行测试

要构建解决方案,请导航到生成菜单,然后点击生成解决方案

Explorer Link

我们应该获得生成成功的消息。

Success Message

导航到测试菜单并选择测试资源管理器选项。

Test Explorer

我们应该能够找到添加到SpecFlow项目的特性。通过在视图中运行所有测试选项执行该特性。

SpecFlow Project

结果如以下图像中突出显示所示。

SpecFlow Highlighted

报告生成

转到输出菜单,然后从显示来自下拉列表中选择测试

menu select

总执行结果显示在输出控制台中。它包含有关测试用例数量、总成功、忽略、跳过、失败等等的信息。还捕获了执行发生的用户和机器名称。

此外,还显示执行持续时间以及HTML报告和日志文件路径的链接。

HTML Report

复制报告文件路径并在浏览器中打开它。我们将获得一份详细的HTML报告,其中包含项目名称、配置、执行开始时间、持续时间、线程数等等。

它将描述结果、测试时间线摘要和完整的特性摘要。

Timeline Summary

报告还包含错误摘要和场景摘要。它包含每个测试的成功率。要了解特定特性的详细信息,我们可以点击场景名称(以链接形式提供)。

Scenario Name

接下来,捕获每个步骤的执行详细信息。每个步骤的详细信息都显示为跟踪结果

Step Details

Step Details Captured

SpecFlow - 绑定测试步骤

特性文件中的测试步骤

要访问特性文件中的步骤,请转到解决方案资源管理器中的SpecFlow项目。然后点击特性文件夹。特性文件将显示。

Solution Explorer

特性文件可用于以纯文本格式记录应用程序的预期特性,也可用于自动化。Given、Then、When等关键字用于在SpecFlow中使用Gherkin语言描述场景。

测试步骤绑定

上述特性文件已由SpecFlow项目默认添加。它还会生成测试方法,这些方法将运行在特性文件中定义的场景。右键点击Scenario关键字后的任意一行。然后点击转到定义选项。

Run Scenarios

Visual Studio识别与此步骤对应的步骤定义。在此示例中,它将打开CalculatorStepDefinitions类并移动到GivenTheFirstNumberIs方法。

Studio Identifies

SpecFlow - 创建第一个测试

我们现在将在类库中创建一个执行两个数字减法操作的文件。

using System;
namespace ClassLibrary2 {
   public class Class1 {
      public int Number1 { get; set; }
      public int Number2 { get; set; }
      public int Subtraction(){
         return Number1 - Number2;
      }
   }
}

特性文件实现

File Implementation

步骤定义文件实现

上述特性文件的对应步骤定义文件,以及使用Class1执行减法操作。

using ClassLibrary2;
using FluentAssertions;
using TechTalk.SpecFlow;
namespace SpecFlowCalculator.Specs.Steps { 
[Binding]
   public sealed class CalculatorStepDefinitions {
      private readonly ScenarioContext _scenarioContext;
      
      //instantiating Class1
      private readonly Class1 _calculator = new Class1();
      private int _result;
      public CalculatorStepDefinitions(ScenarioContext scenarioContext) {
         _scenarioContext = scenarioContext;
      }
      [Given("the first number is (.*)")]
      public void GivenTheFirstNumberIs(int number){
         _calculator.Number1 = number;
      }
      [Given("the second number is (.*)")]
      public void GivenTheSecondNumberIs(int number){
         _calculator.Number2 = number;
      }
      [When("the two numbers are subtracted")]
      public void WhenTheTwoNumbersAreSubtracted(){
         _result = _calculator.Subtraction();
      }
      [Then("the result should be (.*)")]
      public void ThenTheResultShouldBe(int result){
         _result.Should().Be(result);
      }
   }
}

执行测试

构建上述解决方案,然后在从测试→测试资源管理器获得生成成功消息后执行测试。

选择SpecFlowProject1特性,然后点击在视图中运行所有测试

SpecFlowProject

结果显示为1通过以及执行持续时间。点击打开此结果的其他输出选项以获取结果详细信息。

Execution Duration

显示每个测试步骤的执行结果。

Execution Result

特性文件中的所有步骤都将执行,并显示为已完成状态。此外,步骤定义文件中的对应方法也将显示执行持续时间。

SpecFlow - 配置Selenium Webdriver

要在Visual Studio中配置Selenium Webdriver,我们将借助NUnit框架。此框架允许在C#中运行Selenium测试。

配置NUnit框架

我们首先将创建一个NUnit项目。

打开Visual Studio登录页面后,点击创建新项目

NUnit

创建新项目弹出窗口中出现的搜索框中输入NUnit。从搜索结果中选择NUnit测试项目(.NET Core)。点击下一步

NUnit Project

输入项目名称和位置。然后点击创建继续。

NUnit Project Name

在NUnit(.Net Core)上设置项目后,将默认定义SetupTest方法。此外,语句using NUnit.Framework应显示在顶部。这将证明NUnit框架已成功配置。

NUnit Test

配置Selenium WebDriver

设置NUnit框架后,导航到工具菜单,选择NuGet包管理器,然后点击包管理器控制台

Selenium

我们必须执行安装Selenium Webdriver和NUnit所需的包管理器命令。

对于Selenium安装,在包管理器控制台中运行以下命令:

Install-Package Selenium.WebDriver
Install-Package Selenium.Firefox.WebDriver

对于NUnit安装,在包管理器控制台中运行以下命令:

Install-Package NUnit
Install-Package UUnit3TestAdapter

要检查安装状态,请在包管理器控制台中运行以下命令:

Get-Package
Selenium Package

在C#中使用Selenium WebDriver实现

using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System;
namespace NUnitTestProject1{
   public class Tests{
      String u = "https://tutorialspoint.com/index.htm";
      IWebDriver d;
      [SetUp]
      public void Setup(){
         //creating object of FirefoxDriver
         d = new FirefoxDriver();        
      }
      [Test]
      public void Test1(){
         //launching URL
         d.Navigate().GoToUrl(u);
         Console.WriteLine("Url launched");
      }
      [TearDown]
      public void close_Browser(){
         d.Quit();
      }
   }
}

执行和输出

测试->测试资源管理器运行上述代码。测试资源管理器中的输出为:

Selenium Test

点击打开此结果的其他输出链接,我们将获得测试结果标准输出

Test Outcome

启动的URL作为输出获取,如代码中使用Console.WriteLine方法实现的那样。

SpecFlow - Gherkin

Gherkin是一组重要的关键字,用于构建规范的有意义的体系结构。每个关键字都转换为像英语这样的普通语言。

Gherkin中的规则

下面列出了一些Gherkin中的规则:

  • Gherkin中的文档以关键字开头。

  • 可以在特性文件新行的开头添加注释。它们以空格或不带空格后跟#符号和文本开头。但是,到目前为止,在SpecFlow中无法添加块注释。

  • 要缩进代码,可以使用空格或制表符。建议缩进使用两个空格。

  • 每个步骤的关键字后面的内容都有一个对应的代码块。这称为步骤定义

Gherkin示例

以下是Gherkin示例:

Feature: Payment Functionality

# Example 1
   Scenario: Member Payment Method
      When a member is on Payment screen
      Then the payment amount is displayed.

# Example 2
   Scenario: Member Payment Dues
      When a member is on Payment Due screen
      Then the payable amount is displayed.

在上述示例中,Feature、Scenario、Given、WhenThen被称为Gherkin关键字。

SpecFlow - Gherkin 关键字

主要的Gherkin关键字有:

  • Feature
  • Scenario
  • Rule(到Gherkin 6)
  • Example或Scenario
  • Background
  • Scenario Outline
  • Examples
  • | 用于数据表
  • """ 用于文档字符串
  • @ 用于标签
  • # 用于注释
  • Given
  • When
  • Then
  • But
  • And

Gherkin使用本地化支持多种语言,以上每个关键字在其各自语言中都有等效的术语。

让我们探索一些重要的Gherkin关键字:

Feature

添加Feature是为了对应用程序的总体功能进行描述,并将相关的场景组合在一起。这是Gherkin文档中最重要的关键字。

Feature后面跟着一个冒号:符号,然后是关于该功能的简短描述。我们可以添加多行以进行更多描述。这些在执行时不会被SpecFlow考虑,但会添加到html报告中。

colon

完成Feature的描述后,我们应该用关键字Background、Example等开始新的一行。我们可以在Feature上方添加标签,将类似的特性组合在一起,而不管文件或目录的结构如何。

标签

标签是添加到场景或功能的标记。为功能添加标签就像将该标签标记到该功能文件中的每个场景一样。标签名称在@符号后提及。

我们可以使用标签过滤和组合要运行的测试。例如,我们可以用@important标记一个紧急测试,并经常运行它。SpecFlow将@ignore标签视为一个重要的标签,并根据带有此标签的场景生成一个被忽略的单元测试方法。

Tags

这里,功能文件包含两个带有@Calculator标签的场景。同样也应反映在Test Explorer中,以选择要运行的测试。

Calculator Tags

Scenario

场景是一个完整的实例,描述了业务逻辑。它有多个步骤。它通常被认为是关键字Example的同义词。场景没有固定的步骤数量。但建议每个场景有3到5个步骤。

如果步骤太多,它可能会失去作为规范和文档的价值。场景就像开发生命周期中的一个测试。此外,它可以分为前提条件、测试步骤和验证。

Scenario

Given

Given是用于描述系统预先存在条件的步骤。它通常处理过去发生的事件。当执行Given步骤时,它应该设置数据库中的对象、测试数据并使系统处于适当的状态。

因此,Given步骤有助于在用户与系统交互之前定义系统处于已知状态。我们可以有多个Given步骤。两个或多个Given步骤可以与And关键字一起使用。简而言之,它用于定义前提条件。

Given

When

When是用于描述操作或事件的步骤。这可以是人与系统的交互,也可以是另一个系统引起的事件。在一个场景中只有一个When步骤是一个好习惯。

如果我们被迫使用多个When步骤,我们应该理想地将场景分解成更小的场景。

When

Then

Then是用于描述预期结果的步骤。Then步骤对应的步骤定义应该有一个断言来验证实际结果与预期结果。

因此,它基本上处理从测试中获得的输出(消息、报告等),而不是系统的内部特性,例如数据库记录。换句话说,它用于从最终用户角度可以注意到的结果。

Then

但是,And

如果我们重复了Given、When和Then步骤,那么我们可以通过用And、But步骤替换连续的Given、When、Then步骤来使场景更有条理。

But And

上面的示例显示了And和But的使用。

* 符号

* 符号用于代替另一个步骤关键字。这可以用于表示项目列表的步骤。它更像是一个项目符号。对于下面的示例,两个And步骤一个接一个地出现。

Symbol

连续的And步骤应这样表示:

Symbols

Background

有时,我们可能需要在功能文件中的所有场景中重复相同的步骤。我们可以通过将这些步骤组合在Background部分下将其移到后台。

它有助于为场景添加上下文。它可以有多个Given步骤。因此,它将在每个场景执行之前执行,但在任何Before hooks之后执行。

Background位于第一个ExampleScenario之前,在相同的缩进级别。简而言之,Background用于声明所有测试的公共步骤。

Background

在上面的示例中,有两个场景,Background步骤将在每个场景执行之前运行一次。

Scenario Outline

Scenario Outline用于使用不同的数据集复制相同的场景。使用不同的值编写相同的测试既麻烦又耗时。例如,

Scenarios

我们可以使用Scenario Outline组合以上两个场景。

Scenario Outline

因此,我们看到Scenario Outline应该与关键字Examples一起使用。Scenario Outline为Examples部分下方出现的每一行执行一次。

此外,我们已经看到Given步骤具有<>分隔符。它指向Examples表的标题。SpecFlow将在匹配步骤与步骤定义的任务之前将值放入此表中。

数据表

数据表用于以列表的形式将一组值发送到步骤定义文件。它对于处理大型数据集很有用。SpecFlow在步骤定义文件中有一个丰富的用于表操作的API。

SpecFlow Assist Helpers包用于处理表格。此外,我们还必须将命名空间TechTalk.SpecFlow.Assist添加到我们的代码中。

Data Table

SpecFlow - 特性文件

SpecFlow测试执行从功能文件开始。这里所有功能及其相应的场景都以纯文本形式解释。它具有作为自动化元素以及文档的双重作用。功能文件包含一个或多个场景,以列表形式呈现。功能文件的扩展名应始终为.feature

添加Feature是为了对应用程序的总体功能进行描述,并将相关的场景组合在一起。这是Gherkin文档中最重要的关键字。

Feature后面跟着一个冒号:符号,然后是关于该功能的简短描述。我们可以添加多行以进行更多描述。这些在执行时不会被SpecFlow考虑,但会添加到html报告中。

Gherkin Document

完成Feature的描述后,我们应该用关键字Background、Example等开始新的一行。我们可以在Feature上方添加标签,将类似的特性组合在一起,而不管文件或目录的结构如何。

功能文件创建

创建SpecFlow项目后,转到解决方案资源管理器并展开它。

Solutions Explorer

右键单击Features文件夹。单击添加,然后选择新建项选项。

Explorer Features

添加新项弹出窗口出现。在搜索框中键入SpecFlow Feature。从搜索结果中选择SpecFlow Feature File选项。单击添加并继续。

Explorer Pop-up

功能文件生成,默认情况下SpecFlow创建了一些步骤。

Explorer SpecFlow

创建功能文件后的项目文件夹

以下是创建功能文件后的项目文件夹。

Gherkin SpecFlow

功能文件主要由Gherkin关键字组成,以形成一个具有一个或多个场景的功能。

SpecFlow - 步骤定义文件

要执行功能文件,我们必须为每个步骤添加实现逻辑。为了在SpecFlow中添加步骤的定义,使用C#语言。因此,步骤定义文件包含在类中用C#开发的方法。

这些方法具有注释以及用于将步骤定义连接到每个匹配步骤的模式。SpecFlow将运行代码以执行Gherkin中的关键字。

步骤定义文件是应用程序接口和功能文件之间的桥梁。为了提供可读性功能,步骤定义文件可以具有参数。这意味着不需要为每个具有细微差异的步骤提供步骤定义。

例如,Given Login to admin applicationGiven Login to payment application步骤可以通过将adminpayment作为参数传递给一个步骤定义来自动化。正则表达式(.*)用于声明方法的参数。

正则表达式的规则

正则表达式的规则如下:

  • 即使我们没有使用标记^$,它也会与整个步骤匹配。

  • 正则表达式中的捕获组按顺序描述方法的参数。

步骤定义方法的规则

步骤定义方法应遵循的规则如下:

  • 它应该具有[Binding]属性并位于公共类中。

  • 它可以具有静态或非静态方法。如果它是非静态方法,则应为其所在的类的每个场景实例化一个对象。

  • 它不应该有refout参数。

  • 它不能有返回值。

步骤定义文件创建

右键单击功能文件的任何步骤,然后单击生成步骤定义选项。

关于如何创建功能文件的详细信息在第章 - 功能文件中详细讨论。

Step Definition

生成步骤定义骨架弹出窗口中,检查我们想要为其生成实现的步骤。添加类名,然后单击生成按钮。

Step Skeleton

提供保存步骤定义文件的位置,然后单击保存。

Step Saving

步骤定义文件将为功能文件中的所有匹配步骤打开。它还包含正则表达式属性。

Step Opened

创建步骤定义文件后的项目文件夹

以下是创建步骤定义文件后的项目文件夹:

Step Definition

SpecFlow - 钩子

钩子是事件绑定,用于在某些步骤中添加更多自动化逻辑。例如,对于任何需要在特定场景之前运行的步骤。为了在代码中引入钩子,我们必须添加[Binding]属性。

钩子具有全局访问权限。但可以通过声明作用域绑定使其对功能和场景可用。作用域绑定可以使用标签进行过滤。

SpecFlow+ Runner 限制

如果我们使用SpecFlow+ Runner从多个线程执行测试,则After和Before钩子(如BeforeTestRunAfterTestRun)每个线程仅运行一次。

钩子属性

钩子属性如下:

BeforeTestRun/AfterTestRun - 用于在整个测试执行之前/之后运行自动化逻辑。它适用的方法应该是静态的。

BeforeFeature/AfterFeature - 用于在单个功能执行之前/之后运行自动化逻辑。它适用的方法应该是静态的。

BeforeScenario 或 Before/AfterScenario 或 After - 用于在单个场景或场景大纲执行之前/之后运行自动化逻辑。

BeforeScenarioBlock/AfterScenarioBlock - 用于在单个场景块执行之前/之后运行自动化逻辑。(在When和Given步骤之间)。

BeforeStep/AfterStep - 用于在单个场景步骤执行之前/之后运行自动化逻辑。

钩子执行顺序

相同类型的钩子,例如两个AfterScenario钩子,将以随机顺序运行。为了使执行按特定顺序进行,我们必须在钩子属性中添加Order属性。

示例

[AfterScenario(Order = 1)]
public void CloseBrowser() {
   // we require this method to execute first...
}
[AfterScenario(Order = 2)]
public void VerifySessionIdAfterBrowserClose() {
   // ...so we require this method to execute after the CloseBrowser //method is run
}

数字表示顺序,这意味着具有最小数字的钩子将首先运行。如果省略数字,则默认值为10000。依赖它不是一个好习惯,而是为各个钩子指定顺序。

此外,如果抛出未处理的异常,则将跳过所有后续相同类型的钩子。为了防止这种情况,我们应该处理所有异常。

SpecFlow - 背景说明

Background关键字用于在功能文件中的所有场景之前复制相同的步骤。我们可以通过将这些步骤组合在Background部分下将其移到后台。

它有助于为场景添加上下文。它可以有多个Given步骤。因此,它将在每个场景执行之前执行,但在任何Before hooks之后执行。

在第一个示例场景之前会保留一个背景,并保持相同的缩进级别。简而言之,它用于声明所有测试的通用步骤。

Step Background

在上面的示例中,有两个场景,Background步骤将在每个场景执行之前运行一次。

背景规则

让我们描述一些应用背景时的规则:

  • 除非我们被迫将应用程序置于需要执行复杂步骤的状态,否则应将其用于定义简单的步骤。如项目利益相关者所要求的。

  • 它应该简洁且现实。

  • 所有场景也应该简明扼要。

背景示例

让我们看一个示例,其中我们使用了背景步骤在特性文件中所有测试之前执行。例如,要为应用程序添加普通用户和管理员用户,我们需要在执行“普通用户添加”场景之前运行以下步骤:

  • 启动应用程序 URL。

  • 提交用户名和密码

步骤 1:创建特性文件

关于如何创建功能文件的详细信息在第章 - 功能文件中详细讨论。

Feature: Member addition

   Background:
      Given launch URL
      Then enter name and password

   Scenario: Normal user addition
      Given user is on normal user addition screen
      When enters normal user details
      Then user should be added as normal user

   Scenario: Admin user addition
      Given user is on admin user addition screen
      When enters admin user details
      Then user should be added as admin user

步骤 2:创建步骤定义文件

关于如何创建步骤定义文件的详细信息在“步骤定义文件”章节中有详细讨论。

using System;
using TechTalk.SpecFlow;
namespace SpecFlowProject1.Features{
   [Binding]
   public class MemberAdditionSteps{
      [Given(@"launch URL")]
      public void GivenLaunchURL(){
         Console.WriteLine("Url launched");
      }  
      [Given(@"user is on normal user additon screeen")]
      public void GivenUserIsOnNormalUserAdditonScreeen(){
         Console.WriteLine("User is on normal user addition screen");
      }   
      [Given(@"user is on admin user addition screen")]
      public void GivenUserIsOnAdminUserAdditionScreen(){
         Console.WriteLine("User is on admin user addition screen");
      }  
      [When(@"enters normal user details")]
      public void WhenEntersNormalUserDetails(){
         Console.WriteLine("User enters normal user details");
      }     
      [When(@"enters admin user details")]
      public void WhenEntersAdminUserDetails(){
         Console.WriteLine("User enters admin user details");
      }      
      [Then(@"enter name and password")]
      public void ThenEnterNameAndPassword(){
         Console.WriteLine("User enters name and password");
      }    
      [Then(@"user should be added as normal user")]
      public void ThenUserShouldBeAddedAsNormalUser(){
         Console.WriteLine("User should be added as normal user");
      }     
      [Then(@"user should be added as admin user")]
      public void ThenUserShouldBeAddedAsAdminUser(){
         Console.WriteLine("User should be added as admin user");
      }
   }
}

步骤 3:执行和结果

选择SpecFlowProject(2),然后点击在视图中运行所有测试

Execution Results

选择普通用户添加场景,然后点击打开此结果的附加输出链接

addition Scenario

addition Scenarios

在上面的输出中,背景步骤 - 给定 URL 启动然后输入名称和密码在实际的普通用户场景之前执行。

选择管理员用户添加特性,然后点击打开此结果的附加输出链接。

Admin addition

在上面的输出中,背景步骤 - 给定 URL 启动然后输入名称和密码在实际的管理员用户场景之前执行。

SpecFlow - 使用示例进行数据驱动测试

我们可以借助关键字示例执行数据驱动测试。我们还将借助关键字场景轮廓在多个值上执行相同的场景。

要考虑的数据集应在“示例”部分下方逐个传递,并以|符号分隔。因此,如果有三行,我们将从单个场景执行三个测试用例。

Scenario Outline用于使用不同的数据集复制相同的场景。使用不同的值编写相同的测试既麻烦又耗时。例如,

User Credential

我们可以使用Scenario Outline组合以上两个场景。

User Credentials

因此,我们看到Scenario Outline应该与关键字Examples一起使用。Scenario Outline为Examples部分下方出现的每一行执行一次。

此外,我们已经看到给定步骤有<>分隔符。它指向“示例”表的表头。SpecFlow 将在将步骤与步骤定义匹配之前将此表中的值放入其中。

要验证登录模块,我们需要执行以下步骤:

  • 用户输入用户名和密码。

  • 验证用户应该能够登录。

我们将把上述步骤整合到特性文件中。

步骤 1:创建特性文件

关于如何创建功能文件的详细信息在第章 - 功能文件中详细讨论。

Feature: User credential
Scenario Outline: Login module
   Given user types <username> and <password>
   Then user should be able to login
   Examples:
   | username       | password |
   | tutorialspoint1| pwd      |
   | tutorialspoint2| pwd1     |

步骤 2:步骤定义文件

关于如何创建步骤定义文件的详细信息在“步骤定义文件”章节中有详细讨论。

using System;
using TechTalk.SpecFlow;
namespace SpecFlowProject1.Features{
   [Binding]
   public class UserCredentialSteps{
      //regular expression used to point to data
      [Given(@"user types (.*) and (.*)")]
      public void GivenUserTypesUserAndPwds(string username, string password){   
         Console.WriteLine(username);
         Console.WriteLine(password);
      }  
      [Then(@"user should be able to login")]
      public void ThenUserShouldBeAbleToLogin(){
         Console.WriteLine("User should be able to login");
      }
   }
}

步骤 3:执行和结果

选择用户凭据(2),然后点击在视图中运行所有测试。

Executions Result

选择登录模块,tutorialspoint1 场景,然后点击打开此结果的附加输出链接。

Executions Scenario

Executions Scenarios

该场景使用用户名 - tutorialspoint1 和密码 - pwd执行,如“示例”(第一行)中指定。

选择登录模块,tutorialspoint2 场景,然后点击打开此结果的附加输出链接。

Login Module

Login Modules

该测试使用用户名 - tutorialspoint2 和密码 - pwd1执行,如“示例”(第二行)中指定。

SpecFlow - 无需示例进行数据驱动测试

我们可以无需借助关键字示例执行数据驱动测试。这可以通过将数据直接传递到特性文件中的步骤(括在('')中)来完成。然后,它将作为输入提供给步骤定义文件。

让我们验证一个模块,该模块需要执行以下步骤:

  • 用户启动 URL
  • URL 应打开

步骤 1:创建特性文件

关于如何创建功能文件的详细信息在第章 - 功能文件中详细讨论。

Feature: Launching application

Scenario: Launch URL
   Given User hits URL 'https://tutorialspoint.com/index.htm'
   Then URL should be launched

步骤 2:创建步骤定义文件

关于如何创建步骤定义文件的详细信息在“步骤定义文件”章节中有详细讨论。

using System;
using TechTalk.SpecFlow;
namespace SpecFlowProject1.Features{
   [Binding]
   public class LaunchingApplicationSteps{
      [Given(@"User hits URL '(.*)'")]
      public void GivenUserHitsURL(string url){
         Console.WriteLine(url);
      }   
      [Then(@"URL should be launched")]
      public void ThenURLShouldBeLaunched(){
         Console.WriteLine("URL should be launched");
      }
   }
}   

步骤 3:执行和结果

选择启动应用程序特性,然后点击在视图中运行所有测试。

Application Feature

选择启动 URL 场景,然后点击打开此结果的附加输出链接。

Application Features

Applications Features

在上面的输出中,获取了 URL(https://tutorialspoint.com/index.htm),该 URL 是直接从特性文件中的给定步骤传递的。

SpecFlow - 表格转换为数据表

表格经常与场景轮廓混淆。场景轮廓适用于整个测试,而表格仅适用于其定义下的单个步骤。

但是,需要构建编程逻辑来理解数据,然后才能将其整合到我们的测试中。示例关键字用于场景轮廓,但数据表不需要任何关键字。

SpecFlow 中的表格有多种可用方法,让我们看看如何通过表头将表格转换为表格。

表格用于以列表形式将一组值发送到步骤定义文件。它对于处理大型数据集很有用。SpecFlow 在步骤定义文件中有一个丰富的 API 用于表格操作。

SpecFlow Assist Helpers包用于处理表格。此外,我们还必须将命名空间TechTalk.SpecFlow.Assist添加到我们的代码中。

SpecFlow Assist

步骤 1:创建特性文件

关于如何创建功能文件的详细信息在第章 - 功能文件中详细讨论。

Feature: User credential

Scenario: Login module
   When User types details
   | Name | Password |
   | t1   | pwd      |
   | t2   | pwd1     |

然后用户应该能够登录。

步骤 2:创建 C# 文件以访问表格数据

我们必须通过System.Data包将表格转换为数据表。我们将在项目中创建一个新文件夹,并在其中包含一个 C# 文件。右键点击 SpecFlow 项目,然后点击添加。

选择新建文件夹选项。

Access Table Data

将文件夹命名为Utils

右键点击创建的新文件夹,然后选择添加选项。点击

Access Tables Data

在搜索框中输入C# 类并搜索。从搜索结果中选择选项,然后点击添加继续。

Access Search Box

项目文件夹结构

Folder Structure

C# 类实现

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using TechTalk.SpecFlow;
namespace SpecFlowProject1.Utils {
   class Class1 {
      public static DataTable DT(Table t) {
         var dT = new DataTable();
         foreach (var h in t.Header) {
            dT.Columns.Add(h, typeof(string));
         }
         // iterating rows
         foreach (var row in t.Rows) {
            var n = dT.NewRow();
            foreach (var h in t.Header) {
               n.SetField(h, row[h]);
            }
            dT.Rows.Add(n);
         }
         return dT;
      }
   }
}

步骤 3:创建步骤定义文件

关于如何创建步骤定义文件的详细信息在“步骤定义文件”章节中有详细讨论。

using System;
using System.Data;
using TechTalk.SpecFlow.Assist;
using TechTalk.SpecFlow;
namespace SpecFlowProject1.Features {
   [Binding]
   public class UserCredentialSteps {
      [When(@"User types details")]
      public void WhenUserTypesDetails(Table t) {
         //Accessing C# class method from Step Definition
         var dTable = Utils.Class1.DT(t);
         
         //iterating rows 
         foreach (DataRow r in dTable.Rows) {
            Console.WriteLine(r.ItemArray[0].ToString());
            Console.WriteLine(r.ItemArray[1].ToString());
         }
      }   
      [Then(@"user should be able to login")]
      public void ThenUserShouldBeAbleToLogin() {
         Console.WriteLine("User should be able to login");
      }
   }
}

步骤 4:执行和结果

选择用户凭据(1)特性,然后点击在视图中运行所有测试

Access search boxs

选择登录模块场景,然后点击打开此结果的附加输出链接

additional output

additional outputs

该场景使用从特性文件中的 When 步骤(转换为数据表)的表格传递的数据执行。

SpecFlow - 表格转换为字典

表格可以在特性文件中以水平和垂直方向保存数据。使用字典对象,我们将了解如何在特性文件中以键值对的形式垂直访问数据。

步骤 1:创建特性文件

关于如何创建功能文件的详细信息在第章 - 功能文件中详细讨论。

Feature: User credential
Scenario: Login module
   When User types details
   | KY       | Val            |
   | username | tutorialspoint |
   | password | pwd1           |
Then user should be able to login

步骤 2:创建 C# 文件以访问表格数据

我们必须通过System.Collections.Generic包将表格转换为字典。我们将在项目中创建一个新文件夹,并在其中包含一个 C# 文件。右键点击SpecFlow 项目,然后点击添加

选择新建文件夹选项。

SpecFlow Assists

将文件夹命名为Utils

右键点击创建的新文件夹,然后选择添加选项。点击

Utils

项目文件夹结构

Utilses

C# 类实现

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using TechTalk.SpecFlow;
namespace SpecFlowProject1.Utils {
   class Class1 {
      public static Dictionary<string, string> ToDT(Table t) {
         var dT = new Dictionary<string, string>();
         
         // iterating through rows
         foreach (var r in t.Rows) {
            dT.Add(r[0], r[1]);
         }
         return dT;
      }
   }
}

步骤 3:创建步骤定义文件

关于如何创建步骤定义文件的详细信息在“步骤定义文件”章节中有详细讨论。

using System;
using TechTalk.SpecFlow;
namespace SpecFlowProject1.Features {
   [Binding]
   public class UserCredentialSteps {
      [When(@"User types details")]
      public void WhenUserTypesDetails(Table t) {  
         
         //Accessing C# class method from Step Definition
         var dict = Utils.Class1.ToDT(t);
         Console.WriteLine(dict["username"]);
         Console.WriteLine(dict["password"]);
      }   
      [Then(@"user should be able to login")]
      public void ThenUserShouldBeAbleToLogin() {
         Console.WriteLine("User should be able to login");
      }
   }
}

步骤 4:执行和结果

选择用户凭据(1)特性,然后点击在视图中运行所有测试

Tests View

选择登录模块场景,然后点击打开此结果的附加输出链接

Tests Views

Tests Views

该场景使用从特性文件中的 When 步骤(转换为字典)的表格传递的数据执行。

SpecFlow - 使用 CreateInstance 的表格

CreateInstance<T>是 Table 方法的扩展。它将表格中的数据转换为对象。它是垂直对齐数据参数化的一种常用技术。

SpecFlow Assist Helpers包用于处理表格。此外,我们必须将命名空间TechTalk.SpecFlow.Assist添加到我们的代码中。

特性文件中的表格标题可以是任何名称,例如:KEY、VALUE。但是,第一列应指向属性的名称,第二列应指向其对应值。

步骤 1:创建特性文件

关于如何创建功能文件的详细信息在第章 - 功能文件中详细讨论。

Feature: User credential

Scenario: Login module
   When User types details
   | KEY      | VALUE          |
   | username | tutorialspoint |
   | password | pwd1           |
Then user should be able to login

步骤 2:创建 C# 文件以访问字符串对象

我们将在项目中创建一个新文件夹,并在其中包含一个 C# 文件。右键点击SpecFlow 项目,然后点击添加

选择新建文件夹选项。

String Objects

将文件夹命名为Utils

右键点击创建的新文件夹,然后选择添加选项。点击

New Folder

在搜索框中输入C# 类并搜索。从搜索结果中选择选项,然后点击添加继续。

New Folders

项目文件夹结构

Folder Structures

C# 类实现

using System;
using System.Collections.Generic;
using System.Text;
namespace SpecFlowProject1.Utils {
   class Class1 {
      public class Input {
         //Declaring string objects
         public string Input1 { get; set; }
         public string Input2 { get; set; }
      }
   }
}

步骤 3:创建步骤定义文件

关于如何创建步骤定义文件的详细信息在“步骤定义文件”章节中有详细讨论。

using System;
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;
namespace SpecFlowProject1.Features {
   [Binding]
   public class UserCredentialSteps {
      [When(@"User types details")]
      public void WhenUserTypesDetails(Table t) {
         //access data with CreateInstance method using C# class method
         var i = t.CreateInstance<Utils.Class1.Input>();
         Console.WriteLine(i.Input1);
         Console.WriteLine(i.Input2);
      }
      [Then(@"user should be able to login")]
      public void ThenUserShouldBeAbleToLogin() {
         Console.WriteLine("User should be able to login");
      }
   }
}

步骤 4:执行和结果

选择用户凭据(1)特性,然后点击在视图中运行所有测试

Definition File

选择登录模块场景,然后点击打开此结果的附加输出链接

Definition Files

Definitions File

该场景使用从特性文件中的 When 步骤中使用 CreateInstance 方法传递的表格数据执行。

SpecFlow - 使用 CreateSet 的表格

CreateSet<T>是 Table 方法的扩展。它将表格中的数据转换为一组对象。它是水平对齐数据参数化的一种常用技术。

我们可以使用此方法处理一行或多行数据。SpecFlow Assist Helpers包用于处理表格。此外,我们必须将命名空间TechTalk.SpecFlow.Assist添加到我们的代码中。

CreateSet<T>方法根据表格中匹配的数据获取IEnumerable<T>。它包含所有对象的值。它确保从字符串到链接属性的类型转换正确。

步骤 1:创建特性文件

关于如何创建功能文件的详细信息在第章 - 功能文件中详细讨论。

Feature: User credential

Scenario: Login module
   When User types details
   | Name | Password |
   | t1   | pwd      |
   | t2   | pwd1     |
Then user should be able to login

步骤 2:创建 C# 文件以访问字符串对象

我们将在项目中创建一个新文件夹,并在其中包含一个 C# 文件。右键点击SpecFlow 项目,然后点击添加

选择新建文件夹选项。

String Object

将文件夹命名为Utils

右键点击创建的新文件夹,然后选择添加选项。点击

Folder created

在搜索框中输入C# 类并搜索。从搜索结果中选择选项,然后点击添加继续。

Folders Created

项目文件夹结构

Folders Structures

C# 类实现

using System;
using System.Collections.Generic;
using System.Text;
namespace SpecFlowProject1.Utils {
   class Class1 {
      public class Input {
         //two string objects declared
         public string Input1 { get; set; }
         public string Input2 { get; set; }
      }
   }
}

步骤 3:创建步骤定义文件

关于如何创建步骤定义文件的详细信息在“步骤定义文件”章节中有详细讨论。

using System;
using TechTalk.SpecFlow;
using TechTalk.SpecFlow.Assist;
namespace SpecFlowProject1.Features {
   [Binding]
   public class UserCredentialSteps {
      [When(@"User types details")]
      public void WhenUserTypesDetails(Table t) {
         
         //access Table data with CreateSet method
         var i = t.CreateSet<Utils.Class1.Input>();
         
         //iterate over rows
         foreach (var r in i) {
            Console.WriteLine(r.Input1);
            Console.WriteLine(r.Input2);
         }
      }
      [Then(@"user should be able to login")]
      public void ThenUserShouldBeAbleToLogin() {
         Console.WriteLine("User should be able to login");
      }
   }
}

步骤 4:执行和结果

选择用户凭据(1)特性,然后点击在视图中运行所有测试。

Test Views

选择登录模块场景,然后点击打开此结果的附加输出链接

Additional Outputs

Scenario link

该场景使用从特性文件中的 When 步骤中使用 CreateSet 方法传递的表格数据执行。

广告

© . All rights reserved.