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.
I use AssemblyFixture (NuGet).
What it does is it provides an
IAssemblyFixture<T>
interface that is replacing anyIClassFixture<T>
where you want the object's lifetime to be as the testing assembly.Example:
Does your build tool provide such a feature?
In the Java world, when using Maven as a build tool, we use the appropriate phases of the build lifecycle. E.g. in your case (acceptance tests with Selenium-like tools), one can make good use of the
pre-integration-test
andpost-integration-test
phases to start/stop a webapp before/after one'sintegration-test
s.I'm pretty sure the same mechanism can be set up in your environment.
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:
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.Then you need to add the collection name over all your test classes. The test classes can receive the fixture through the constructor.
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.
It's not possible to do in the framework today. This is a feature planned for 2.0.
In order to make this work before 2.0, it would require you to perform significant re-architecture on the framework, or write your own runners that recognized your own special attributes.
Create a static field and implement a finalizer.
You can use the fact that xUnit creates an AppDomain to run your test assembly and unloads it when it's finished. Unloading the app domain will cause the finalizer to run.
I am using this method to start and stop IISExpress.
Edit: Access the fixture using
ExampleFixture.Current
in your tests.To execute code on assembly initialize, then one can do this (Tested with xUnit 2.3.1)
See also https://github.com/xunit/samples.xunit/tree/master/AssemblyFixtureExample