xUnit.net - 前所有测试后运行一次代码(xUnit.net - run code onc

2019-07-04 23:47发布

TL; DR -我在寻找的xUnit等效MSTest的年代AssemblyInitialize (又名一个特点它有我喜欢)。

具体来说,我正在寻找它,因为我有一些硒烟雾测试,我希望能够与任何其他依赖运行。 我有一个灯具将推出IisExpress我把它杀了处置。 但每次测试之前做这个巨大的腌运行。

我想在测试开始后触发此代码,并对其进行处理末(关闭进程)。 我怎么会去这样做呢?

即使我能得到类似的编程访问“多少测试,目前正在运行的”我可以计算出来的东西。

Answer 1:

随着2015年11月的的xUnit 2已经出来了,所以要测试之间共享功能规范的方法。 据记载这里 。

基本上,你需要创建一个类做夹具:

    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属性。 这个类允许的xUnit创建测试集合,并使用给定的固定的集合中的所有测试类。

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

它比MsTests更详细一点AssemblyInitialize因为你必须在申报其所属的测试集每个测试类,但它也更可调制(与MsTests你仍然需要投入的TestClass你的班级)

注:样品已经从拍摄文档 。



Answer 2:

创建一个静态字段和实施一个终结。

您可以使用的xUnit创建一个AppDomain中运行测试组装和卸载它,当它完成的事实。 卸载应用程序域会导致终结运行。

我使用这种方法来启动和停止IISExpress。

public sealed class ExampleFixture
{
    public static ExampleFixture Current = new ExampleFixture();

    private ExampleFixture()
    {
        // Run at start
    }

    ~ExampleFixture()
    {
        Dispose();
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);

        // Run at end
    }        
}

编辑:允许使用夹具ExampleFixture.Current在你的测试。



Answer 3:

这是不可能在今天的框架做。 这是计划2.0功能。

为了2.0之前,使这项工作,它需要你对框架进行显著重新架构,或写自己的选手,承认自己的特殊属性。



Answer 4:

要在组件执行代码初始化,那么可以做到这一点(与的xUnit 2.3.1测试)

using Xunit.Abstractions;
using Xunit.Sdk;

[assembly: Xunit.TestFramework("MyNamespace.MyClassName", "MyAssemblyName")]

namespace MyNamespace
{   
   public class MyClassName : XunitTestFramework
   {
      public MyClassName(IMessageSink messageSink)
        :base(messageSink)
      {
        // Place initialization code here
      }
   }
}

又见https://github.com/xunit/samples.xunit/tree/master/AssemblyFixtureExample



Answer 5:

我用AssemblyFixture ( 的NuGet )。

它的作用是它提供了一个IAssemblyFixture<T>被更换任何接口IClassFixture<T>要在其中对象的生存期是作为测试组件。

例:

public class Singleton { }

public class TestClass1 : IAssemblyFixture<Singleton>
{
  readonly Singletone _Singletone;
  public TestClass1(Singleton singleton)
  {
    _Singleton = singleton;
  }

  [Fact]
  public void Test1()
  {
     //use singleton  
  }
}

public class TestClass2 : IAssemblyFixture<Singleton>
{
  readonly Singletone _Singletone;
  public TestClass2(Singleton singleton)
  {
    //same singleton instance of TestClass1
    _Singleton = singleton;
  }

  [Fact]
  public void Test2()
  {
     //use singleton  
  }
}


Answer 6:

请问您的构建工具提供这样的功能?

在Java世界中,使用时的Maven作为构建工具,我们使用适当的构建生命周期的阶段 。 例如,在你的情况(硒类工具验收测试),可以很好地利用的pre-integration-testpost-integration-test阶段启动/停止之前,web应用程序/人的后integration-test秒。

我敢肯定,同样的机制可以在你的环境中进行设置。



Answer 7:

您可以使用IUseFixture接口来实现这一目标。 此外所有的测试必须继承TestBase类。 您也可以直接从你的测试中使用OneTimeFixture。

public class TestBase : IUseFixture<OneTimeFixture<ApplicationFixture>>
{
    protected ApplicationFixture Application;

    public void SetFixture(OneTimeFixture<ApplicationFixture> data)
    {
        this.Application = data.Fixture;
    }
}

public class ApplicationFixture : IDisposable
{
    public ApplicationFixture()
    {
        // This code run only one time
    }

    public void Dispose()
    {
        // Here is run only one time too
    }
}

public class OneTimeFixture<TFixture> where TFixture : new()
{
    // This value does not share between each generic type
    private static readonly TFixture sharedFixture;

    static OneTimeFixture()
    {
        // Constructor will call one time for each generic type
        sharedFixture = new TFixture();
        var disposable = sharedFixture as IDisposable;
        if (disposable != null)
        {
            AppDomain.CurrentDomain.DomainUnload += (sender, args) => disposable.Dispose();
        }
    }

    public OneTimeFixture()
    {
        this.Fixture = sharedFixture;
    }

    public TFixture Fixture { get; private set; }
}

编辑:修正了新的夹具为每个测试类的问题。



文章来源: xUnit.net - run code once before and after ALL tests