我一直在寻找相同的答案,此时 xUnit 文档对于如何实现类夹具和集合夹具非常有帮助,它们为开发人员提供了类或类组级别的广泛设置/拆卸功能。这与 Geir Sagberg 的回答一致,并提供了良好的框架实现来说明它应该是什么样子。
https://xunit.net/docs/shared-context
Collection Fixtures 何时使用:当你想创建一个单独的测试上下文并在多个测试类中的测试之间共享它,并在测试类中的所有测试完成后清理它。
有时您会希望在多个测试类之间共享一个夹具对象。用于类夹具的数据库示例是一个很好的示例:您可能希望使用一组测试数据初始化数据库,然后将该测试数据保留在适当的位置以供多个测试类使用。您可以使用 xUnit.net 的集合夹具功能在多个测试类中的测试之间共享单个对象实例。
要使用集合夹具,您需要执行以下步骤:
创建夹具类,并将启动代码放入夹具类构造函数中。如果fixture类需要进行清理,在fixture类上实现IDisposable,将清理代码放在Dispose()方法中。创建集合定义类,用 [CollectionDefinition] 属性装饰它,给它一个唯一的名称来标识测试集合。将 ICollectionFixture<> 添加到集合定义类。使用您提供给测试集合定义类的 [CollectionDefinition] 属性的唯一名称,将 [Collection] 属性添加到将成为集合一部分的所有测试类。如果测试类需要访问夹具实例,请将其添加为构造函数参数,它将自动提供。这是一个简单的例子:
public class DatabaseFixture : IDisposable
{
public DatabaseFixture()
{
Db = new SqlConnection("MyConnectionString");
// ... initialize data in the test database ...
}
public void Dispose()
{
// ... clean up test data from the database ...
}
public SqlConnection Db { get; private set; }
}
[CollectionDefinition("Database collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
[Collection("Database collection")]
public class DatabaseTestClass1
{
DatabaseFixture fixture;
public DatabaseTestClass1(DatabaseFixture fixture)
{
this.fixture = fixture;
}
}
[Collection("Database collection")]
public class DatabaseTestClass2
{
// ...
}
xUnit.net 对待集合夹具的方式与类夹具非常相似,只是集合夹具对象的生命周期更长:它是在集合中的任何测试类中运行任何测试之前创建的,并且不会被清理直到集合中的所有测试类都完成运行。
测试集合也可以用 IClassFixture<> 装饰。xUnit.net 将其视为测试集合中的每个单独的测试类都用类固定装置装饰。
测试集合也会影响 xUnit.net 在并行运行测试时的运行方式。有关更多信息,请参阅并行运行测试。
重要提示:fixtures 必须与使用它们的测试在同一个程序集中。