- SpecFlow 教程
- SpecFlow - 主页
- SpecFlow - 简介
- 测试驱动开发
- Behave驱动开发
- SpecFlow - Visual Studio 安装
- Visual Studio 扩展安装
- SpecFlow - 项目设置
- 其他项目依赖项
- SpecFlow - 运行器激活
- SpecFlow - HTML 报告
- SpecFlow - 结合测试步骤
- SpecFlow - 创建第一个测试
- 配置 Selenium Webdriver
- SpecFlow - 小Cucumber
- SpecFlow - 小Cucumber关键词
- SpecFlow - 特征文件
- SpecFlow - 步骤定义文件
- SpecFlow - 挂钩
- SpecFlow - 背景插图
- 数据驱动测试示例
- 没有示例的数据驱动测试
- 表转换为数据表
- 表转换为字典
- 带有 CreateInstance 的表
- SpecFlow - 带有 CreateSet 的表
- SpecFlow 有用资源
- SpecFlow - 快速指南
- SpecFlow - 有用的资源
- SpecFlow - 讨论
SpecFlow - 快速指南
SpecFlow - 简介
SpecFlow 是一个基于 BDD 模型构建的开源测试自动化工具。它主要用于为 .NET 构建的项目构建自动化测试。本教程将提供有关 SpecFlow 及其功能的知识。
Spec-Flow 主要开发用于构建、监控和运行人类可读的验收测试用例。它是用Gherkin创建的,Gherkin 是一种纯文本语言。SpecFlow 拥有可运行 70 多种语言的 Gherkin 解析器。我们可以通过 SpecFlow 内置的测试运行器和SpecFlow+ Runner执行测试。
成分
SpecFlow 的主要任务是绑定用 Gherkin 编写的特征文件。SpecFlow+ Runner 是具有执行能力和报告生成功能的测试运行器。这也是免费的,我们需要为其创建一个 SpecFlow 帐户。
SpecFlow+ LivingDoc是一组工具,可将 Gherkin 特征文件保持为可读格式。这可以与团队中不熟悉 Visual Studio 等工具的利益相关者共享。
SpecFlow+ LivingDoc Generator 是 SpecFlow 的一组插件和工具,用于从 Gherkin 功能文件生成文档。这不需要创建帐户,并且可以轻松地与其他人共享。
SpecFlow+ LivingDoc Azure DevOps允许在 Azure DevOps/TFS 中查看输出。任何具有系统访问权限的用户都可以在需要时查看规格。它是免费的,但需要 SpecFlow 帐户。
在 Visual Studio 扩展中编辑功能
此外,SpecFlow 具有Visual Studio 扩展,可提供额外的功能,如下所述 -
步骤和关键字的智能感知(自动完成)
为了方便使用 SpecFlow,intellisense 提供了“键入时查找”功能来限制建议列表。Intellisense 可用于 Gherkin 文件、其关键字和代码文件。
在 Visual Studio 中,单击“编辑”,然后选择“智能感知”以获取各种选项。
下图显示了 Gherkin 文件中的 Intellisense。
Gherkin 语法突出显示
突出显示关键字、标签、评论、无界(紫色)步骤、有界(黑色)步骤、有界步骤参数(灰色斜体)。
功能文件大纲和评论
在 Visual Studio 中, “编辑”菜单中的大多数项目都可以为 SpecFlow 中的功能文件添加值。我们可以使用 # 字符或使用内置快捷键(例如CTRL+K CTRL+V 或 CTRL+K + CTRL+V )来注释和取消注释特定行。
“编辑”菜单中有多个选项可用于自定义功能文件的各个部分。
单击“编辑”,然后选择“大纲”选项。
我们可以定义自己的功能文件模板以在创建新测试用例时打开。
格式化表格
当我们键入列名并输入其值时,我们可以修改表大小并自动设置其格式。
但 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 - Behave驱动开发
Behave驱动开发也称为 BDD 具有以下功能-
提供共享的方法和工具,有助于与开发人员、业务分析师和其他利益相关者建立交互,共同进行产品开发。
确保交付的产品增加必要的业务价值。
找出系统的功能以及如何开发它。
确保产品美观并具有良好的结构。
检查软件的功能并确保满足最终用户的期望。
BDD方法论
BDD 采用的主要方法如下:
举例说明
它利用交互中的示例来描述软件特性及其业务场景。这种方法有助于消除开发人员、测试人员、产品所有者、业务分析师和团队中所有其他利益相关者之间对业务需求的任何知识差距。
测试驱动开发
在 BDD 的参考中,测试驱动开发将示例转换为纯文本和可执行规范。开发人员在实现新功能时将此作为文档引用。它有助于开发适当的代码库以及回归套件。因此,整个产品生命周期的总体维护成本降低。
业务驱动开发工具
SpecFlow 是开源的 BDD 工具之一。它包含一个遵循Gherkin语法的功能文件。SpecFlow 的源代码托管在 GitHub 上。它主要用于为 .NET 构建的项目构建自动化测试。它的功能与Cucumber类似。
SpecFlow 中特征文件的结构 -
它由功能、背景场景和两个场景组成。功能文件包含应用程序中功能的验收标准。
SpecFlow - Visual Studio 安装
在本章中,我们将看到Visual Studio的安装和项目配置的过程。
安装
导航到链接 - https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx
对于 Visual Studio 的社区版本,请单击“社区”部分下的“免费下载”。
.exe 文件被下载到我们的系统中。双击它。
出现Visual Studio 安装程序弹出窗口。单击继续。下载和安装过程开始。
安装完成后,选择选项.NET 桌面开发。然后单击“安装”。
开始下载并安装软件包。
完成后,单击“重新启动”。
从开始菜单中,键入 Visual Studio。
单击 Visual Studio,出现欢迎屏幕。
与此同时,Visual Studio弹出窗口也会出现。如果您没有现有的
帐户,单击“现在不,可能稍后”链接并继续。
选择主题颜色,然后单击“启动 Visual Studio”。
项目配置
Visual Studio 登录页面打开后,单击“创建新项目”。
我们将创建一个新的 C# 类库。在搜索框中输入类库核心。选择选项“类库 (.NET Core)”,然后单击“下一步”。
提供项目名称和位置,然后单击“创建”。
项目代码实现
using System; namespace ClassLibrary2 { public class Class1 { public int Number1 { get; set; } public int Number2 { get; set; } public int Subtraction() { throw new NotImplementedException(); } } }
要构建此解决方案,请转到“构建”菜单,然后选择“构建解决方案”。
显示构建成功消息,我们已在 Visual Studio 中成功创建了一个项目。
SpecFlow - Visual Studio 扩展安装
如前所述,Visual Studio 扩展允许添加测试自动化所需的许多功能。此扩展适用于 Visual Studio 2017 和 2019。
安装
打开 Visual Studio 并导航到“扩展”菜单,然后单击“管理扩展”选项。
管理扩展弹出窗口出现。在搜索框中输入SpecFlow 。一旦搜索结果被填充。单击“下载”。
下载完成后,我们需要重新启动Visual Studio . 安装完成后,如果我们再次转到“管理扩展”弹出窗口,我们可以在“已安装”选项卡中找到此扩展。
此外,我们现在还可以找到 SpecFlow 的“禁用”和“卸载”选项。单击“关闭”退出。
SpecFlow - 项目设置
现在,我们将在之前构建的同一项目中创建一个 SpecFlow 项目。
项目创建
右键单击“解决方案资源管理器”部分。单击添加选项。然后选择新建项目。
在搜索框中输入SpecFlow ,搜索结果将显示 SpecFlow 项目。单击“下一步”继续。
输入项目名称和位置,然后单击“创建”。
从创建新的 SpecFlow 项目弹出窗口中的测试框架下拉列表中选择SpecFlow+ Runner选项。然后点击创建。
解决方案资源管理器现在应创建一个名为SpecFlowProject1的新项目。
项目文件夹
创建 SpecFlow 项目后,我们还将找到为该项目创建的定义良好的文件夹结构,其中包括驱动程序、依赖项、功能、挂钩等。
SpecFlow - 其他项目依赖项
我们需要有一个对我们为 SpecFlow 项目创建的类库的项目引用。这对于测试项目中类库中的类非常重要。
添加项目依赖项
单击“解决方案资源管理器”中的项目SpecFlowProject1。然后右键单击文件夹“依赖项”。选择选项添加项目参考。
参考管理器弹出窗口打开。选中类库的复选框,然后单击“确定”。
构建和运行测试
接下来,转到“生成”菜单并选择“生成解决方案”。我们应该得到构建成功消息作为输出。
导航到“测试”菜单并选择“测试资源管理器”选项。
我们应该能够找到添加到 SpecFlow 项目中的功能。通过“在视图中运行所有测试”选项执行它们。执行状态显示为“未运行”,因为测试尚未执行。
功能之前的感叹号表示该功能的测试执行正在等待。
SpecFlow - 运行器激活
我们必须执行SpecFlow + Runner的激活。导航至“查看”菜单,然后选择“输出”选项。
然后在显示输出- 下拉列表中选择测试。
我们应该获得测试输出以及运行器的激活链接。仅当我们在项目设置时选择了SpecFlow+ Runner时,此链接才应可用。
激活链接
在浏览器上打开激活链接。我们应该导航到 SpecFlow 登录页面。单击“使用 Microsoft 登录”。
单击“是”以允许Microsoft访问我们的 SpecFlow 帐户。
为了设置帐户,请提供所需的信息。然后点击创建帐户。
我们现在应该成功激活 SpecFlow 帐户。
现在,如果我们再次从文本资源管理器执行测试,它将显示正确的结果。
SpecFlow - HTML 报告
当所有测试完成执行后,SpecFlow 会生成报告,其中包括测试结果的细分。
从资源管理器测试运行
要构建解决方案,请导航至“构建”菜单,然后单击“构建解决方案”。
我们应该收到构建成功的消息。
导航到“测试”菜单并选择“测试资源管理器”选项。
我们应该能够找到添加到 SpecFlow 项目中的功能。通过“在视图中运行所有测试”选项执行该操作。
结果如下图突出显示。
报告生成
转到输出菜单并从显示输出- 下拉列表中选择测试。
总执行结果显示在输出控制台中。它包含有关测试用例计数、成功、忽略、跳过、失败总数等信息。执行发生的用户名和机器名也会被捕获。
此外,还会显示执行持续时间以及 HTML 报告和日志文件路径的链接。
复制报告文件路径并在浏览器中打开它。我们将获得一份详细的 HTML 报告,其中包含项目名称、配置、执行开始时间、持续时间、线程数等。
它应描述结果、测试时间表摘要和完整的功能摘要。
该报告还包括错误摘要和场景摘要。它包含每个测试的成功率。要了解特定功能的详细信息,我们可以单击场景名称(以链接形式提供)。
接下来,捕获每个步骤的执行详细信息。每个步骤的详细信息均通过Trace和Result显示。
SpecFlow - 结合测试步骤
功能文件中的测试步骤
要访问功能文件中的步骤,请转至解决方案资源管理器中的 SpecFlow 项目。然后单击功能文件夹。应显示特征文件。
功能文件可用于以纯文本格式记录应用程序的预期特征,也可用于自动化。SpecFlow 中使用关键字Give、Then、When等来描述Gherkin语言中的场景。
测试步骤绑定
上述Feature文件已由SpecFlow项目默认添加。它还生成应运行功能文件中定义的场景的测试方法。右键单击Scenario关键字后面的任意行。然后单击“转到定义”选项。
Visual Studio 标识此步骤对应的步骤定义。在此示例中,它打开类CalculatorStepDefinitions并移至GiveTheFirstNumberIs方法。
SpecFlow - 创建第一个测试
我们现在将在类库中创建一个文件,用于执行两个数字的减法。
using System; namespace ClassLibrary2 { public class Class1 { public int Number1 { get; set; } public int Number2 { get; set; } public int Subtraction(){ return Number1 - Number2; } } }
特征文件实现
步骤定义文件实施
上述Feature文件对应的Step Definition文件,以及使用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); } } }
执行测试
构建上述解决方案,然后从Test → Test Explorer获取构建成功消息后执行测试。
选择SpecFlowProject1功能并单击“在视图中运行所有测试”。
结果显示为1 Passed以及执行持续时间。单击选项打开此结果的附加输出以获取结果详细信息。
显示每个测试步骤的执行结果。
功能文件中的所有步骤均与完成状态一起执行。此外,步骤定义文件中的相应方法也会显示执行持续时间。
SpecFlow - 配置 Selenium Webdriver
要在 Visual Studio 中配置 Selenium Webdriver,我们将借助NUnit 框架。该框架允许在 C# 中运行 Selenium 测试。
配置 NUnit 框架
我们首先创建一个 NUnit 项目。
Visual Studio 登录页面打开后,单击“创建新项目”。
在“创建新项目”弹出窗口中出现的搜索框中键入NUnit 。从搜索结果中选择NUnit测试项目(.NET Core) 。单击“下一步”。
输入项目名称和位置。然后单击“创建”继续。
由于项目是在NUnit(.Net Core)上建立的,因此应默认定义Setup和Test方法。此外,使用 NUnit.Framework 的语句应反映在顶部。这将证明NUnit框架已成功配置。
配置 Selenium WebDriver
设置 NUnit 框架后,导航到“工具”菜单,选择“ NuGet Package Manager”,然后单击“Package Manager Console”。
我们必须执行安装Selenium Webdriver和 NUnit 所需的包管理器命令。
对于 Selenium 安装,请在包管理器控制台中运行以下命令 -
Install-Package Selenium.WebDriver Install-Package Selenium.Firefox.WebDriver
对于 NUnit 安装,请在程序包管理器控制台中运行以下命令 -
Install-Package NUnit Install-Package UUnit3TestAdapter
要检查安装状态,请在包管理器控制台中运行命令 -
Get-Package
在 C# 中使用 Selenium WebDriver 实现
using NUnit.Framework; using OpenQA.Selenium; using OpenQA.Selenium.Firefox; using System; namespace NUnitTestProject1{ public class Tests{ String u = "https://www.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(); } } }
执行与输出
从Test->Test Explorer运行上述代码。测试资源管理器中的输出是 -
单击打开此结果的附加输出链接,我们应该获得测试结果和标准输出。
启动的 Url是通过代码中的Console.WriteLine方法实现的输出获取的。
SpecFlow - 小Cucumber
Gherkin是一组重要的关键字,用于构建有意义的规范架构。每个关键字都会转换为简单的口语,例如英语。
小Cucumber的规则
下面列出了 Gherkin 中的一些规则 -
Gherkin 中的文档以关键字开头。
可以在功能文件中新行的开头添加注释。它们以空格或不空格开头,后跟 # 符号和文本。但是,到目前为止,SpecFlow 中还无法添加块注释。
要缩进代码,可以使用空格或制表符。建议有两个空格用于缩进。
每个步骤的关键字后面的内容都有对应的代码块。这称为步骤定义。
小Cucumber示例
以下是小Cucumber的例子 -
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、When和Then被称为 Gherkin 关键字。
SpecFlow - 小Cucumber关键词
小Cucumber的主要关键字是 -
- 特征
- 设想
- 规则(直到小Cucumber 6)
- 示例或场景
- 背景
- 场景概要
- 例子
- | 对于数据表
- """ 表示文档字符串
- @代表标签
- # 评论
- 给定
- 什么时候
- 然后
- 但
- 和
Gherkin 使用多种语言的本地化,上述每个关键字在各自的语言中都有其等效术语。
让我们探讨一些重要的 Gherkin 关键字 -
特征
添加一个功能是为了对应用程序的功能进行总体描述并俱乐部连接的场景。这是 Gherkin 文档中最重要的关键字。
功能后跟一个冒号:符号,然后是对该功能的简短描述。我们可以添加多行以进行更多描述。SpecFlow 在执行时不会考虑这些,但会添加到 html 报告中。
一旦功能的描述完成,我们应该开始一个新行,其中包含关键字“背景”、“示例”等。我们可以在Feature之上添加标签来聚集相似的特征,而不管文件或目录的结构如何。
标签
标签是添加到场景或功能的标记。为功能添加标签就像将该标签标记到该功能文件中的每个场景一样。@ 符号后面提到了标签名称。
我们可以过滤和俱乐部要使用标签运行的测试。例如,我们可以使用@important标记紧急测试并经常运行它。SpecFlow 将@ignore标签视为重要标签,并从带有此标签的场景中生成一个被忽略的单元测试方法。
这里,功能文件包含两个带有@Calculator标签的场景。同样的情况也应反映在测试资源管理器中,以挑选要运行的测试。
设想
场景是描述业务逻辑的完整实例。它有多个步骤。它通常被认为是关键字Example的同义词。场景没有固定的步骤数。但建议每个场景有 3 到 5 个步骤。
如果步骤太多,可能会失去作为规范和文档的价值。场景就像开发生命周期中的测试。此外,它可以分为前提条件、测试步骤和验证。
给定
给出了用于描述系统预先存在的状况的步骤。它通常涉及过去发生的事件。当执行给定步骤时,它将设置对象、测试数据库中的数据并使系统处于适当的状态。
因此,给定步骤有助于在用户与系统交互之前在已知条件下定义系统。我们可以有多个给定步骤。两个或多个给定步骤可以与And关键字一起使用。简而言之,它用于定义前提条件。
什么时候
何时是用于描述操作或事件的步骤。这可能是人与系统的交互,也可能是另一个系统引起的事件。在场景中使用单个 When 步骤是一种很好的做法。
如果我们被迫有多个 When 步骤,理想情况下我们应该将场景分成更小的场景。
然后
然后是用于描述预期结果的步骤。Then 步骤的相应步骤定义应该有一个断言,用于根据预期结果验证实际结果。
因此,它基本上处理从测试中获得的输出(消息、报告等),而不是系统的内部特征,例如数据库记录。换句话说,它用于从最终用户的角度来看明显的结果。
但是,并且
如果我们重复了“Given”、“When”和“Then”步骤,那么我们可以通过用“And”、“But”步骤替换连续的“Given”、“When”、“Then”步骤来使场景更有条理。
上面的例子展示了And和But的用法。
* 符号
* 符号用于代替另一个步骤关键字。这可用于表示项目列表的步骤。它更像是一个要点。对于下面的示例,两个 And 步骤相继出现。
连续的 And 步骤应该这样表示 -
背景
有时,我们可能需要对功能文件中的所有场景重复相同的步骤。我们可以通过将这些步骤放在背景部分下将它们转移到背景中。
它有助于向场景添加上下文。它可以有多个给定步骤。因此,它应在每个场景的执行之前执行,但发布任何Before 挂钩。
背景保留在第一个示例或场景之前,处于类似的缩进级别。简而言之,Background 用于声明所有测试的通用步骤。
在上面的示例中,有两个场景,后台步骤应在执行每个场景之前运行一次。
场景概要
场景大纲用于使用不同的数据集复制相同的场景。使用不同的值编写相同的测试既麻烦又耗时。例如,
我们可以将上述两个场景与场景大纲结合起来。
因此,我们看到场景大纲应该附带关键字Examples。对于示例段下方出现的每一行,都会执行一次场景大纲。
此外,我们还看到给定步骤具有<>分隔符。它指向示例表的标题。在执行将步骤与步骤定义匹配的任务之前,SpecFlow 应将值放入此表中。
数据表
数据表用于将一组值以列表的形式发送到步骤定义文件。它对于处理大型数据集很有用。SpecFlow 在步骤定义文件中具有丰富的用于表操作的 API。
SpecFlow Assist Helpers包用于在表上工作。另外,我们必须将命名空间TechTalk.SpecFlow.Assist添加到我们的代码中。
SpecFlow - 特征文件
SpecFlow 测试从功能文件开始执行。这里所有的功能及其相应的场景都以纯文本解释。它具有作为自动化元件和文档的双重作用。特征文件由一个或多个以列表形式存在的场景组成。功能文件的扩展名应始终为.feature。
添加一个功能是为了对应用程序的功能进行总体描述并俱乐部连接的场景。这是 Gherkin 文档中最重要的关键字。
功能后跟一个冒号:符号,然后是对该功能的简短描述。我们可以添加多行以进行更多描述。SpecFlow 在执行时不会考虑这些,但会添加到 html 报告中。
一旦功能的描述完成,我们应该开始一个新行,其中包含关键字“背景”、“示例”等。我们可以在Feature之上添加标签来聚集相似的特征,而不管文件或目录的结构如何。
特征文件创建
创建 SpecFlow 项目后,转到解决方案资源管理器并展开它。
右键单击功能文件夹。单击“添加” ,然后选择“新建项目”选项。
添加新项目弹出窗口出现。在搜索框中输入SpecFlow 功能。从搜索结果中选择SpecFlow 特征文件选项。单击“添加”并继续。
默认情况下,SpecFlow 创建的特征文件只需几个步骤即可生成。
创建功能文件后的项目文件夹
以下是创建功能文件后的项目文件夹。
特征文件主要由 Gherkin 关键字组成,以采取具有一个或多个场景的特征的形式。
SpecFlow - 步骤定义文件
为了执行Feature文件,我们必须添加每个步骤的实现逻辑。为了在 SpecFlow 中添加步骤的定义,使用了 C# 语言。因此,步骤定义文件包含在类中用 C# 开发的方法。
这些方法具有注释以及将步骤定义连接到每个匹配步骤的模式。SpecFlow 将运行代码来执行 Gherkin 中的关键字。
步骤定义文件是应用程序接口和功能文件之间的链接。为了提供可读性特征,步骤定义文件可以具有参数。这意味着不需要为每个具有微小差异的步骤提供步骤定义。
例如,通过将管理和付款作为参数传递,可以通过一步定义来自动化“给定登录到管理应用程序”和“给定登录到支付应用程序”步骤。正则表达式 (.*) 用于声明方法的参数。
正则表达式的规则
正则表达式的规则如下:
即使我们没有使用标记^和$ ,它也与完整的步骤匹配。
正则表达式中的捕获组按顺序描述方法的参数。
步骤定义方法的规则
下面列出了步骤定义方法应遵循的规则 -
它应该具有[Binding]属性并驻留在公共类中。
它可以具有静态或非静态方法。如果它是非静态方法,则应该为其所在类的每个场景实例化一次对象。
它不应该有ref或out参数。
它不能有返回类型。
步骤定义文件创建
右键单击功能文件的任意步骤,然后单击“生成步骤定义”选项。
如何创建功能文件的详细信息将在“功能文件”一章中详细讨论。
在“生成步骤定义骨架”弹出窗口中,选中我们要为其生成实现的步骤。添加类名,然后单击“生成”按钮。
指定保存步骤定义文件的位置,然后单击“保存”。
打开步骤定义文件,其中包含特征文件中的所有匹配步骤。它还包含正则表达式属性。
创建步骤定义文件后的项目文件夹
以下是创建步骤定义文件后的项目文件夹 -
SpecFlow - 挂钩
挂钩是事件绑定,用于在某些步骤添加更多自动化逻辑。例如,对于需要在特定场景之前运行的任何步骤。介绍一下,我们必须在代码中添加[Binding]属性。
Hooks 具有全局访问权限。但可以通过声明作用域绑定将其提供给功能和场景。可以使用标签过滤作用域绑定。
SpecFlow+ 运行器限制
如果我们使用 SpecFlow+ Runner 从多个线程执行测试,则 After 和 Before 挂钩(例如 BeforeTestRun和AfterTestRun )只会为每个线程运行一次。
挂钩属性
下面列出了 Hook 属性 -
BeforeTestRun/AfterTestRun - 用于在完整测试执行之前/之后运行自动化逻辑。它适用的方法应该是静态的。
BeforeFeature/AfterFeature - 用于在单个功能执行之前/之后运行自动化逻辑。它适用的方法应该是静态的。
BeforeScenario 或 Before/AfterScenario 或 After - 用于在单个场景或场景大纲执行之前/之后运行自动化逻辑。
BeforeScenarioBlock/AfterScenarioBlock - 用于在单个场景块执行之前/之后运行自动化逻辑。(在 When 和 Give 步骤之间)。
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 - 背景插图
应用背景关键字来复制功能文件中所有场景之前的相同步骤。我们可以通过将这些步骤放在背景部分下将它们转移到背景中。
它有助于向场景添加上下文。它可以有多个给定步骤。因此,它应在每个场景的执行之前执行,但发布任何Before 挂钩。
背景保留在第一个示例或场景之前,处于类似的缩进级别。简而言之,它用于声明所有测试的通用步骤。
在上面的示例中,有两个场景,后台步骤应在执行每个场景之前运行一次。
背景规则
让我们描述应用背景时的一些规则 -
它应该用于定义简单的步骤,除非我们被迫将应用程序置于需要执行复杂步骤的状态。根据项目利益相关者的要求。
它应该简短而现实。
所有场景也应该简短扼要。
背景示例
让我们看一个示例,其中我们使用了在功能文件中的所有测试之前执行的后台步骤。例如,要为应用程序添加普通用户和管理员用户,我们需要在执行场景普通用户添加之前运行以下步骤 -
启动应用程序 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),然后单击Run All Tests in View。
选择“普通用户添加方案”,然后单击“为此结果打开附加输出”链接。
在上面的输出中,后台步骤 -启动给定的 URL,然后输入名称和密码在实际的普通用户场景之前执行。
选择管理员用户添加功能,然后单击打开此结果的附加输出链接。
在上面的输出中,后台步骤 -启动给定的 URL,然后输入名称和密码在实际的管理员用户场景之前执行。
SpecFlow - 数据驱动测试与示例
我们可以借助关键字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),然后单击“运行视图中的所有测试”。
选择“登录模块”、“tutorialspoint1 场景”,然后单击“为此结果打开附加输出”链接。
该场景使用用户名 -tutorialspoint1 和密码 -pwd执行,如示例(第一行)中指定。
选择“登录模块”、“tutorialspoint2 场景”,然后单击“为此结果打开其他输出”链接。
测试使用用户名 -tutorialspoint2 和密码 -pwd1执行,如示例(第二行)中指定。
SpecFlow - 没有示例的数据驱动测试
我们可以在没有关键字Examples的帮助下执行数据驱动测试。这可以通过将数据直接传递到 ('') 中包含的功能文件内的步骤来完成。然后它将作为步骤定义文件的输入提供。
让我们验证一个模块,需要执行以下步骤 -
- 用户启动 URL
- 网址应该打开
第 1 步:创建特征文件
如何创建功能文件的详细信息将在“功能文件”一章中详细讨论。
Feature: Launching application Scenario: Launch URL Given User hits URL 'https://www.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 步:执行和结果
选择“启动应用程序功能”,然后单击“在视图中运行所有测试”。
选择“启动 URL 方案”,然后单击“为此结果打开其他输出”链接。
在上面的输出中,获取的 url ( https://www.tutorialspoint.com/index.htm ) 是直接从给定步骤中的功能文件传递的。
SpecFlow - 表转换为数据表
表经常与场景大纲混淆。虽然场景大纲适用于完整的测试,但表格仅适用于定义它的单个步骤。
然而,需要构建一个编程逻辑来理解数据,然后才能将其合并到我们的测试中。示例关键字用于场景大纲,但数据表不需要关键字。
SpecFlow 中的 Table 有多种方法可用,让我们看看如何通过Table headers将 Table 转换为 Table 。
表用于将一组值以列表的形式发送到步骤定义文件。它对于处理大型数据集很有用。SpecFlow 在步骤定义文件中具有丰富的用于表操作的 API。
SpecFlow Assist Helpers包用于在表上工作。另外,我们必须将命名空间TechTalk.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 项目,然后单击添加。
选择“新建文件夹”选项。
将文件夹命名为Utils 。
右键单击创建的新文件夹,然后选择“添加”选项。单击班级。
在搜索框中键入C# Class并搜索。从搜索结果中选择选项“类别” ,然后单击“添加”继续。
项目文件夹结构
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)功能”,然后单击“运行视图中的所有测试”。
选择“登录模块方案”,然后单击“为此结果打开附加输出”链接。
在“何时”步骤中,使用从特征文件中的表(转换为数据表)传递的数据执行场景。
SpecFlow - 表转换为字典
表格可以保存特征文件中水平和垂直方向的数据。通过Dictionary对象,我们将了解如何以键值对的方式垂直访问特征文件中的数据。
第 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 项目,然后单击添加。
选择“新建文件夹”选项。
将文件夹命名为Utils 。
右键单击创建的新文件夹,然后选择“添加”选项。单击班级。
项目文件夹结构
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)功能”,然后单击“运行视图中的所有测试”。
选择“登录模块方案”,然后单击“为此结果打开附加输出”链接。
该场景是在“何时”步骤中使用从特征文件中的表(转换为字典)传递的数据执行的。
SpecFlow - 带有 CreateInstance 的表
CreateInstance<T>是 Table 方法的扩展。它将表中的数据转换为对象。在垂直对齐中对数据进行参数化是流行的技术之一。
SpecFlow Assist Helpers包用于处理表。另外,我们必须将命名空间TechTalk.SpecFlow.Assist添加到我们的代码中。
特征文件中的表头可以是任何名称,例如:KEY、VALUE。但是,第一列应指向属性的名称,第二列应指向其相应的值。
第 1 步:创建特征文件
如何创建功能文件的详细信息将在“功能文件”一章中详细讨论。