I'm a big fan of the xUnit.NET framework; I find it light, simple, clean, and extensible.
Now let's say that I have a class like so:
public class AdditionSpecification
{
static int result;
public void Because()
{
result = 2 + 2;
}
public void Result_is_non_zero()
{
Assert.True(result <> 0);
}
public void Result_is_correct()
{
Assert.Equal(4, result);
}
}
With the test class above I want xUnit.NET to see 2 test cases and to run the Because() method before each of them.
Leaving aside any issues you may have with my class or method names, the structure of this test/specification, the xUnit.NET framework, or BDD, here's my question:
How can I tell xUnit.NET that I want to customize how it identifies and executes test methods out of this class without using a custom [Fact]-like attribute on each target test method?
I know that I can derive from BeforeAfterAttribute to decorate each test method with custom before and after execution. How can i do this at the class level? Do i have to write a custom runner?
xUnit.net's IUseFixture allows you to do per fixture setup. You could therefore define your own fixture class:
public class AdditionFixture : IDisposable
{
public int Because()
{
return 2 + 2;
}
public void Dispose()
{
//test tear down code
}
}
Your test class can then implement this (with setFixture requiring implementing) :
public class AdditionSpecification : IUseFixture<AdditionFixture>
{
int result;
public void SetFixture(AdditionFixture Fixture)
{
result = Fixture.Because();
}
[Fact]
public void Result_is_non_zero()
{
Assert.True(result <> 0);
}
[Fact]
public void Result_is_correct()
{
Assert.Equal(4, result);
}
}
The xUnit runner will create a single instance of your fixture, and pass it into SetFixture before running each test. After running all of your tests, the runner will then dispose of the fixture if it implements IDisposable. I hope that helps!
The xUnit wiki on codeplex has more information, including a nice example of how to implement IUseFixture to manage a database connection for you test fixtures.
So it turns out that I was looking for the ITestClassCommand.EnumerateTestMethods() method.
In the case of my example above, I would need something like:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class RunWithMyTestClassCommandAttribute : RunWithAttribute
{
public RunWithMyTestClassCommandAttribute()
: base(typeof(MyTestClassCommand)) {}
}
Then I could decorate my above example with:
[RunWithMyTestClassCommand]
public class AdditionSpecification
{
static int result;
public void Because()
{
result = 2 + 2;
}
public void Result_is_non_zero()
{
Assert.True(result <> 0);
}
public void Result_is_correct()
{
Assert.Equal(4, result);
}
}
Finally, in MyTestClassCommand, I get to opportunity between EnumerateTestMethods() and EnumerateTestCommands(IMethodInfo testMethod) to use whatever logic I want to locate and construct ITestCommand instances that get executed as individual tests.
BTW, in the process of researching this issue, I ran into a small bug in the xUnit.NET framework where a custom IMethodInfo generated by EnumerateTestMethods() never showed up in EnumerateTestCommands(..) because it was being unwrapped and rewrapped by the test runner or one of it's factories.
I submitted this issue to the xUnit project on codeplex and it was corrected on May 30th, 2009 for xUnit.NET 1.5 CTP 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With