TickSpec 2.0.3
dotnet add package TickSpec --version 2.0.3
NuGet\Install-Package TickSpec -Version 2.0.3
<PackageReference Include="TickSpec" Version="2.0.3" />
paket add TickSpec --version 2.0.3
#r "nuget: TickSpec, 2.0.3"
// 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
项目描述
一个轻量级的用于 .NET 的行为驱动开发 (BDD) 框架,可满足您的测试需求。
- 使用 Gherkin 商业语言(即 Given、When、Then)以纯文本形式描述行为。
- 轻松将行为与匹配的 F# 'ticked' 方法或属性标记的 C# 或 F# 方法执行。
- 通过您正常的测试运行器或插件(xUnit、NUnit 或独立)运行
- 在场景、步骤定义或您的代码中设置断点并执行(目前在 .NET Standard 版本中不支持在 Gherkin 中设置断点)
示例视频: http://www.youtube.com/watch?v=UuTL3nj9fIE
安装
通过 NuGet 或 Paket 引用 TickSpec,下载程序集或从源代码构建项目。
- 二进制文件应在任何 .NET Standard 2.0、.NET 4.5 或更高版本环境中干净地运行。
- TickSpec 解决方案文件与 Visual Studio 2017 兼容。
- 历史上支持了Silverlight;但这种支持和相关的示例在2017年已被移除(但对古生物学爱好者来说仍然保存在提交历史中)
- 示例文件夹中有有用的示例,位于 https://github.com/fsprojects/TickSpec/tree/master/Examples/,根据您的选择,这一个是良好的起点:https://github.com/fsprojects/TickSpec/tree/master/Examples/ByFramework
功能规范(纯文本)
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
。
请参阅示例项目 DependencyInjection
和 FunctionalInjection
,以获取使用此机制典型的和高级示例。
自定义类型解析器(测试版)
虽然典型的推荐使用方法是使步骤定义简单并尽可能简单地从外部驱动系统,但在某些高级情况下,提供自定义类型解析器可能会有所帮助。可以通过设置 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已计算。 |
-
.NETFramework 4.5.2
- FSharp.Core (>= 4.2.3)
-
.NETStandard 2.0
- FSharp.Core (>= 4.3.4)
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仓库使用。
[特性] 通过参数解析使`ScenarioInformation`可用于步骤实现(问题#49)
[修复] 当使用的程序集包含许多方法时,提高性能(问题#45)
[特性] 在事件中添加对功能注入的支持(问题#56)
[修复] 在文档字符串中保留空行(问题#60)
[修复] 允许多个步骤类型在单个方法上(问题#55)
【修复】单元测试序列化,便于从IDE中轻松运行