Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
774 views
in Technique[技术] by (71.8m points)

c# - xUnit.net: Global setup + teardown?

This question is about the unit testing framework xUnit.net.

I need to run some code before any test is executed, and also some code after all tests are done. I thought there should be some kind of attribute or marker interface to indicate the global initialization and termination code, but couldn't find them.

Alternatively, if I invoke xUnit programmatically, I can also achieve what I want with the following code:

static void Main()
{
    try
    {
        MyGlobalSetup();
        RunAllTests();  // What goes into this method?
    }
    finally
    {
        MyGlobalTeardown();
    }
}

Can anyone provide me a hint about how to declaratively or programmatically run some global setup/teardown code?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As far as I know, xUnit does not have a global initialization/teardown extension point. However, it is easy to create one. Just create a base test class that implements IDisposable and do your initialization in the constructor and your teardown in the IDisposable.Dispose method. This would look like this:

public abstract class TestsBase : IDisposable
{
    protected TestsBase()
    {
        // Do "global" initialization here; Called before every test method.
    }

    public void Dispose()
    {
        // Do "global" teardown here; Called after every test method.
    }
}

public class DummyTests : TestsBase
{
    // Add test methods
}

However, the base class setup and teardown code will be executed for each call. This might not be what you want, as it is not very efficient. A more optimized version would use the IClassFixture<T> interface to ensure that the global initialization/teardown functionality is only called once. For this version, you don't extends a base class from your test class but implement the IClassFixture<T> interface where T refers to your fixture class:

using Xunit;

public class TestsFixture : IDisposable
{
    public TestsFixture ()
    {
        // Do "global" initialization here; Only called once.
    }

    public void Dispose()
    {
        // Do "global" teardown here; Only called once.
    }
}

public class DummyTests : IClassFixture<TestsFixture>
{
    public DummyTests(TestsFixture data)
    {
    }
}

This will result in the constructor of TestsFixture only being run once for every class under test. It thus depends on what you want exactly to choose between the two methods.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...