using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; using Xunit.Extensions; using Xunit.Sdk; using xUnitStudy.Model; namespace xUnitStudy.WebApi.Test { /// /// Collection级别的Fixture /// 测试程序集中所有测试类可以共享 /// [Collection("Demo Collection")] public class UseICollectionFixtureTest { /* ICollectionFixture使用步骤: * * 01:创建自定义的Fixture类,添加构造函数;如需做清理,则实现IDisposable接口 * 02:创建Collection类, 添加[CollectionDefinition]特性, 并设置一个唯一名称来识别测试集合. * 03:Collection类,实现ICollectionFixture接口,T 即是“自定义的Fixture类”. * 04:创建具体的测试类,添加[Collection]特性,指定要使用的[CollectionDefinition]的唯一名称 * 05:如果需要在测试类中使用共享对象,只需要把它作为一个构造函数参数。xUnit.Net 会自动发现和运用。 * * * 执行流程: * * 运行整个测试集 * * xUnit 发现程序集中所有相关的共享ICollectionFixture,创建共享实例并保存,与测试集关联 * * 发现测试类x * * xUnit 发现测试类相关共享Fixture,创建共享实例并保存,与测试类关联 * * 用例b:创建测试类实例 --> 获取共享ICollectionFixture --> 获取共享ClassFixture --> 构造函数 --> 用例1 --> Dispose()方法 --> 结束测试类实例 --> 完成 * * 用例a:创建测试类实例 --> 获取共享ICollectionFixture --> 获取共享ClassFixture --> 构造函数 --> 用例2 --> Dispose()方法 --> 结束测试类实例 --> 完成 * * 用例x:创建测试类实例 --> 获取共享ICollectionFixture --> 获取共享ClassFixture --> 构造函数 --> 用例2 --> Dispose()方法 --> 结束测试类实例 --> 完成 * * 用例m:创建测试类实例 --> 获取共享ICollectionFixture --> 获取共享ClassFixture --> 构造函数 --> 用例2 --> Dispose()方法 --> 结束测试类实例 --> 完成 * ........ * 本测试类中所有用例完成 * 清理共享实例 * * 其它测试类y m n a ...... * * .......... * * 所有测试类完成 * * ICollectionFixture共享实例,清理 * * 完成 * * 特别注意: * 由于测试用例执行顺序不固定,还可能并行运行 * 所以对共享对象(ICollectionFixture和ClassFixture)的使用,应避免出现竞态条件。 * 否则,很容易因共享类的竞态条件,导致单元测试失败。 * 因此:共享资源,只适合读,不适合写,使用须谨慎。 */ CollectionFixtureDemo fixtureDemo; public UseICollectionFixtureTest(CollectionFixtureDemo fixture) { fixtureDemo = fixture; } [Fact] public void Test() { var persons = fixtureDemo.GetPersonById(1); Assert.True(persons.Id == 1, "使用全局共享对象"); } } }