Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run code once before and after ALL tests in xUnit.net

TL;DR - I'm looking for xUnit's equivalent of MSTest's AssemblyInitialize (aka the ONE feature it has that I like).

Specifically I'm looking for it because I have some Selenium smoke tests which I would like to be able to run with no other dependencies. I have a Fixture that will launch IisExpress for me and kill it on disposal. But doing this before every test hugely bloats runtime.

I would like to trigger this code once at the start of testing, and dispose of it (shutting down the process) at the end. How could I go about doing that?

Even if I can get programmatic access to something like "how many tests are currently being run" I can figure something out.

like image 749
George Mauer Avatar asked Dec 11 '12 22:12

George Mauer


People also ask

Does xUnit create a new instance for each test?

xUnit.net creates a new instance of the test class for every test that is run, so any code which is placed into the constructor of the test class will be run for every single test.

Do xUnit tests run in order?

Ordering classes and casesTests are executed in ascending order. If no Order attribute is specified default 0 is assigned. Multiple Order attributes can have same value.

Does xUnit run tests in parallel?

Running unit tests in parallel is a new feature in xUnit.net version 2. There are two essential motivations that drove us to not only enable parallelization, but also for it to be a feature that's enabled by default: As unit testing has become more prevalent, so too have the number of unit tests.


2 Answers

As of Nov 2015 xUnit 2 is out, so there is a canonical way to share features between tests. It is documented here.

Basically you'll need to create a class doing the fixture:

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

A dummy class bearing the CollectionDefinition attribute. This class allows Xunit to create a test collection, and will use the given fixture for all test classes of the collection.

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

Then you need to add the collection name over all your test classes. The test classes can receive the fixture through the constructor.

    [Collection("Database collection")]     public class DatabaseTestClass1     {         DatabaseFixture fixture;          public DatabaseTestClass1(DatabaseFixture fixture)         {             this.fixture = fixture;         }     } 

It's a bit more verbose than MsTests AssemblyInitialize since you have to declare on each test class which test collection it belongs, but it's also more modulable (and with MsTests you still need to put a TestClass on your classes)

Note: the samples have been taken from the documentation.

like image 143
gwenzek Avatar answered Sep 21 '22 11:09

gwenzek


To execute code on assembly initialize, then one can do this (Tested with 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       }        public new void Dispose()       {         // Place tear down code here         base.Dispose();       }    } } 

See also https://github.com/xunit/samples.xunit/tree/master/AssemblyFixtureExample

like image 41
Rolf Kristensen Avatar answered Sep 18 '22 11:09

Rolf Kristensen