TickSpec 2.0.3

dotnet add package TickSpec --version 2.0.3                
NuGet\Install-Package TickSpec -Version 2.0.3                
此命令旨在在 Visual Studio 的包管理器控制台内使用,因为它使用 NuGet 模块的 Install-Package 版本。
<PackageReference Include="TickSpec" Version="2.0.3" />                
对于支持 PackageReference 的项目,将此 XML 节点复制到项目文件中以引用包。
paket add TickSpec --version 2.0.3                
#r "nuget: TickSpec, 2.0.3"                
#r 指令可用于 F# Interactive 和 Polyglot Notebooks。将其复制到交互式工具或脚本源代码中以引用包。
// Install TickSpec as a Cake Addin
#addin nuget:?package=TickSpec&version=2.0.3

// Install TickSpec as a Cake Tool
#tool nuget:?package=TickSpec&version=2.0.3                

Build Status NuGet Status Join the chat at https://gitter.im/fsprojects/TickSpec

项目描述

一个轻量级的用于 .NET 的行为驱动开发 (BDD) 框架,可满足您的测试需求。

  1. 使用 Gherkin 商业语言(即 Given、When、Then)以纯文本形式描述行为。
  2. 轻松将行为与匹配的 F# 'ticked' 方法或属性标记的 C# 或 F# 方法执行。
  3. 通过您正常的测试运行器或插件(xUnit、NUnit 或独立)运行
  4. 在场景、步骤定义或您的代码中设置断点并执行(目前在 .NET Standard 版本中不支持在 Gherkin 中设置断点)

示例视频: http://www.youtube.com/watch?v=UuTL3nj9fIE

安装

通过 NuGet 或 Paket 引用 TickSpec,下载程序集或从源代码构建项目。

功能规范(纯文本)

Feature: Refunded or replaced items should be returned to stock

Scenario: Refunded items should be returned to stock
    Given a customer buys a black jumper
    And I have 3 black jumpers left in stock
    When he returns the jumper for a refund
    Then I should have 4 black jumpers in stock

步骤定义(F#)

type StockItem = { Count : int }

let mutable stockItem = { Count = 0 }

let [<Given>] ``a customer buys a black jumper`` () = ()

let [<Given>] ``I have (.*) black jumpers left in stock`` (n:int) =
    stockItem <- { stockItem with Count = n }

let [<When>] ``he returns the jumper for a refund`` () =
    stockItem <- { stockItem with Count = stockItem.Count + 1 }

let [<Then>] ``I should have (.*) black jumpers in stock`` (n:int) =
    let passed = (stockItem.Count = n)
    Debug.Assert(passed)

步骤定义(F#无变元字段)

type StockItem = { Count : int }

let [<Given>] ``a customer buys a black jumper`` () = ()
      
let [<Given>] ``I have (.*) black jumpers left in stock`` (n:int) =
    { Count = n }
      
let [<When>] ``he returns the jumper for a refund`` (stockItem:StockItem) =
    { stockItem with Count = stockItem.Count + 1 }
      
let [<Then>] ``I should have (.*) black jumpers in stock`` (n:int) (stockItem:StockItem) =
    let passed = (stockItem.Count = n)
    Debug.Assert(passed)

步骤定义(C#)

public class StockStepDefinitions
{
   private StockItem _stockItem;

   [Given(@"a customer buys a black jumper")]
   public void GivenACustomerBuysABlackJumper()
   {
   }

   [Given(@"I have (.*) black jumpers left in stock")]
   public void GivenIHaveNBlackJumpersLeftInStock(int n)
   {
      _stockItem = new StockItem() { Count = n };
   }

   [When(@"he returns the jumper for a refund")]
   public void WhenHeReturnsTheJumperForARefund()
   {
      _stockItem.Count += 1;
   }

   [Then(@"I should have (.*) black jumpers in stock")]
   public void ThenIShouldHaveNBlackJumpersInStock(int n)
   {
      Debug.Assert(_stockItem.Count == n);
   }
}

类型转换

当可能时,步骤方法参数的声明类型将从 string 转换为。以下转换受支持

  • Enum 类型
  • 无参数的 Union 类型
  • Nullable<T> 类型,其中内部 T 类型可从 string 转换
  • 每个元素都可以从 string 转换的 Tuple 类型
  • 数组类型 T [],其中 T 可从 string 转换,并且原始 string 是以逗号分隔的
  • System.Convert.ChangeType 支持的类型

表格

一个表格可以作为步骤方法的参数传递

When a market place has outright orders:
   | Contract | Bid Qty | Bid Price | Offer Price | Offer Qty |
   | V1       | 1       | 9505      |             |           |
   | V2       |         |           | 9503        | 1         |

参数可以被声明为类型 Table

let [<When>] ``a market place has outright orders:`` (table:Table) =
    outrightOrders <- toOrders table

或者,参数可以被转换为记录数组或其他支持构造参数的类型,这些参数由 类型转换 支持

type OrderRow = { Contract: string; BidQty: string; BidPrice: string; OfferPrice: string; OfferQty: string }

let [<When>] ``a market place has outright orders:`` (orderRows: OrderRow[]) =
    outrightOrders <- toOrders orderRows

Table 参数必须出现在任何正则表达式捕获参数之后,出现在任何 Functional Injection 参数之前

let [<Given>] ``A market place``() =
    createMarketPlace()

let [<When>] ``a market place has outright (.*) orders:``
    (orderType: string)       # captured
    (table: Table)            # table
    (maketPlace: MarketPlace) # injected
    =
  ...

列表

类似地,一个项目符号列表可以作为 表格 传递给步骤方法

Scenario: Who is the one?
Given the following actors:
    * Keanu Reeves
    * Bruce Willis
    * Johnny Depp
When the following are not available:
    * Johnny Depp
    * Bruce Willis
Then Keanu Reeves is the obvious choice

参数类型必须是受 类型转换 支持的数组类型

let [<Given>] ``the following actors:`` (actors : string[]) =
    availableActors <- Set.ofArray actors

高级功能

解析引用类型(beta)

步骤定义(F#无变元字段) 中所示,TickSpec 还允许您请求与步骤名称中的正则表达式洞中捕获的内容一起附加的额外参数,就像典型的基于 Gherkin 的框架一样。这些附加参数可以通过以下机制来实现

  • 从步骤方法返回的实例: 这涉及到在场景中之前的一个步骤中生成和存储一个 实例。通常这是通过从步骤方法返回实例来实现的。每当一个步骤有一个返回值时,该值就会被保存在其类型下(步骤方法的返回类型控制类型是什么)。步骤方法可以通过返回一个元组返回多个值。在每个场景运行中,每个类型只能存储一个已存储的值。在解析参数时,TickSpec 首先尝试从这个类型到实例的缓存字典中解析。

  • 解析依赖项: 如果基于先前步骤存储的值在类型到实例缓存中找不到实例,则 TickSpec 将尝试使用所需类型的具有最多参数的‘最宽’构造函数(即具有最多参数的构造函数)来实例化它。构造函数的所有输入参数都递归地使用相同的机制来解析。任何构建的实例也存储在类型到实例缓存中,因此下一次将返回相同的实例。

  • 访问场景元数据:您可以访问在某种步骤定义执行的场景内的上下文信息(例如,标签)。为此,在步骤定义参数列表(或依赖数据的构造函数参数列表)中添加类型为 ScenarioMetadata 的参数(例如,标签),然后您可以在方法的参数(或依赖的构造函数)中引用 ScenarioMetadata,您将得到一个描述已调用场景的实例。

实例的生命周期是按场景划分的:- 每个场景运行时启动一个空的类型到实例缓存,并在场景结束时清除此缓存。此外,如果任何实例是 IDisposable,则在场景结束时将调用 Dispose

请参阅示例项目 DependencyInjectionFunctionalInjection,以获取使用此机制典型的和高级示例。

自定义类型解析器(测试版)

虽然典型的推荐使用方法是使步骤定义简单并尽可能简单地从外部驱动系统,但在某些高级情况下,提供自定义类型解析器可能会有所帮助。可以通过设置 StepDefinitions.ServiceProviderFactory 属性来实现。此工厂方法在每个场景运行期间仅使用一次,用于为每个场景运行建立一个独立的解析上下文。该 IServiceProvider 实例用于代替内置的实例构建机制(参见上一节中的 解析依赖:[连接](#resolving-referenced-types-beta))。如果工厂提供的 IServiceProvider 实现实现了 IDisposable,则将在场景运行结束时调用 Dispose

请参阅 CustomContainer 示例项目中的使用示例 - 示例演示了将 Autofac 连接起来,包括按场景使用生存期范围和使用 xUnit 2+ 共享固定装置,以正确管理容器中运行的 xUnit 测试类的共享/生存期,该容器是在大型测试套件中并行运行的一部分。

贡献

欢迎贡献,特别是示例和文档。如果您想讨论 TickSpec,请使用 gitter 通道

对于问题或建议,请提出一个问题。如果您想扩展或更改核心实现,最好留下一个简短的笔记和/或一个占位符 PR,以便在投入大量时间之前确保人们对变更范围/所讨论特征的特性的广泛同意;我们希望保持 TickSpec 强大但最小

产品 兼容和额外的计算目标框架版本。
.NET net5.0 已计算。 net5.0-windows 已计算。 net6.0 已计算。 net6.0-android 已计算。 net6.0-ios 已计算。 net6.0-maccatalyst 已计算。 net6.0-macos 已计算。 net6.0-tvos 已计算。 net6.0-windows 已计算。 net7.0 已计算。 net7.0-android 已计算。 net7.0-ios 已计算。 net7.0-maccatalyst 已计算。 net7.0-macos 已计算。 net7.0-tvos 已计算。 net7.0-windows 已计算。 net8.0 已计算。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。
.NET Core netcoreapp2.0 已计算。 netcoreapp2.1 已计算。 netcoreapp2.2 已计算。 netcoreapp3.0 已计算。 netcoreapp3.1 已计算。
.NET Standard netstandard2.0 兼容。 netstandard2.1 已计算。
.NET Framework net452兼容。 net46已计算。 net461已计算。 net462已计算。 net463已计算。 net47已计算。 net471已计算。 net472已计算。 net48已计算。 net481已计算。
MonoAndroid monoandroid已计算。
MonoMac monomac已计算。
MonoTouch monotouch已计算。
Tizen tizen40已计算。 tizen60已计算。
Xamarin.iOS xamarinios已计算。
Xamarin.Mac xamarinmac已计算。
Xamarin.TVOS xamarintvos已计算。
Xamarin.WatchOS xamarinwatchos已计算。
兼容的目标框架
包含的目标框架(在包内)
了解更多关于目标框架.NET Standard的信息。

NuGet包 (2)

显示依赖TickSpec的前2个NuGet包

下载
TickSpec.Xunit

TickSpec与Xunit的集成。TickSpec是一个轻量级的针对.NET的行为驱动开发(BDD)框架。使用Gherkin业务语言(即Given、When、Then)用纯文本描述行为。轻松地针对匹配的F# 'ticked'方法(let ``tick method`` () = true)或带有属性的C#或F#方法执行行为。

TickSpec.NUnit

使用Gherkin业务语言(即given、when、then)在纯文本中描述行为。轻松地针对匹配的F# tick方法(let ``tick method`` () = true)或带有属性的C#或F#方法执行行为。

GitHub仓库

此包未被任何流行的GitHub仓库使用。

版本 下载 最后更新
2.0.3 7,109 1/26/2024
2.0.2 46,677 6/19/2021
2.0.1 13,155 5/30/2021
2.0.0 8,452 4/24/2020
2.0.0-rc1 6,989 12/21/2018
1.1.0 9,206 3/14/2018
1.0.1.1 12,355 12/7/2014
1.0.0.1 3,797 11/28/2012
1.0.0 4,731 2/20/2011

[特性] 通过参数解析使`ScenarioInformation`可用于步骤实现(问题#49)
[修复] 当使用的程序集包含许多方法时,提高性能(问题#45)
[特性] 在事件中添加对功能注入的支持(问题#56)
[修复] 在文档字符串中保留空行(问题#60)
[修复] 允许多个步骤类型在单个方法上(问题#55)
【修复】单元测试序列化,便于从IDE中轻松运行