xUnit.net在各测试方法/类中共享上下文

首先明确一点:xUnit框架会为每个test类中的test方法创建一个实例,也就是说有多少个[Fact][Theory]特性标注的方法,该类就会被实例化多少个,所以可以把共用的初始化代码放到测试类的构造函数里,构造函数里的代码同样会执行多次。
如果想要一次初始化后提供给各个测试使用,xUnit提供了对应两种依赖注入生命周期Scope和Singleton的方式:IClassFixtureICollectionFixture

新建Fixture类,实现IDisposable接口并将需要共享的内容暴露出来:

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; }
}

然后在Test类实现IClassFixture接口并带有泛型的类型:

public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
    DatabaseFixture fixture;

    public MyDatabaseTests(DatabaseFixture fixture)
    {
        this.fixture = fixture;
    }

    // ... write tests, using fixture.Db to get access to the SQL Server ...
}

如此一来,在Test类第一次运行前,xUnit会创建Fixture类的实例,并在每次Test类实例化时将其传递进构造函数。显然这是Scope的生命周期。若要实现整个测试项目Singleton的生命周期,xUnit有ICollectionFixture:
新建一个类实现ICollectionFixture泛型接口并添加特性:

[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.
}

上一个方法中说到的Fixture类不需要更改。Test类添加[Collection("Database collection")]特性,去掉IClassFixture实现:

[Collection("Database collection")]
public class DatabaseTestClass1
{
    DatabaseFixture fixture;

    public DatabaseTestClass1(DatabaseFixture fixture)
    {
        this.fixture = fixture;
    }
}

这样Collection同名的Test类就会共享定义中指定的Fixture类实例。

另外要注意的是:Fixture类会在测试类构造函数注入的时候实例化,因此Fixture中的构造函数的代码如果发生异常的话,会导致注入失败,测试类就根本没有实例化出来。此过程会发生异常,错误提示为
The following constructor parameters did not have matching fixture data
但不会在调试的时候提示,而是直接判定测试不通过,在测试管理器上显示结果。

xUnit.net官方文档:https://xunit.net/docs/shared-context.html

posted @ 2020-05-23 09:08  pikqu  阅读(575)  评论(0)    收藏  举报