Survival tips for living with MSTest

MSTest has for a long time had a reputation for being inferior to NUnit, MBUnit and XUnit.

Here are a couple of other posts that explain why:

Why I’m Migrating From MS Test to XUnit
Why MSTest is the IE6 of unit test frameworks

To be fair, the Framework has improved over the last couple of versions, but there are still areas where it comes up short. However if your company has a standard for using MSTest that you can’t reverse, there’s a few tools that can make your life easier.

For Assert.Throws you can use
https://github.com/bbraithwaite/MSTestExtensions

Or you can use XUnit for your Asserts in MSTest:
http://www.richard-banks.org/2010/04/how-to-add-assertthrows-to-mstest.html

 

If you decide to use asserts from XUnit (or another framework) instead of MSTest but you already have a lot of MSTest asserts that you don’t want to port, you can do this on a class by class basis:


using Assert=Xunit.Assert;

Porting your asserts doesn’t take much time however. Your Assert.AreEqualbecome Assert.Equal in XUnit or remain as Assert.AreEqual in NUnit. NUnit also using Assert.IsTrue as per MSTest whereas XUnit is just Assert.True

Also, although Autofixture is usually associated with XUnit, you can use it with MSTest or any other unit test framework as well. If you haven’t used Autofixture before here is a basic (and admittedly contrived) introductory example. We are testing some method called Upper that exists in a class AutoFixTest. You don’t need to see the production code, only know that it does some work and returns the upper case value of any string that you give it.

Now an easy way to test it is by doing something like this:


using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class UpperTest
{
[TestMethod]
public void Upper_helloworld_HELLOWORLD()
{
//Arrange
AutoFixTest.autotest sut = new AutoFixTest.autotest();
//Act
string actual = sut.Upper(“hello world”);
//Assert
Assert.AreEqual(“HELLO WORLD”, actual);
}
}

The problem with this it gives the reader the impression that the code has some particular relation to “hello world”. It was only intended as an example, but the reader doesn’t know this.
This doesn’t test every scenario, either. You want to know that it handles numbers as well:


[TestMethod]
public void Upper_7_7()
{
//Arrange
AutoFixTest.autotest sut = new AutoFixTest.autotest();
//Act
string actual = sut.Upper("7");
//Assert
Assert.AreEqual("7", actual);
}

Again, why 7? why not 1, or 2, or 5? The value of the number doesn’t matter, only that it is the string representation of a number.

With Autofixture your inputs are anonymous. This let’s you express the intent of your production code better:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ploeh.AutoFixture;
[TestClass]
public class UpperTest
{
[TestMethod]
public void Upper_fixture_FIXTURE()
{
//Arrange
Fixture fixture = new Fixture();
AutoFixTest.autotest sut = new AutoFixTest.autotest();
string input = fixture.Create();
//Act
string actual = sut.Upper(input);
//Assert
Assert.AreEqual(input.ToUpper, actual);
}
}

After the test runs, you can see that Autofixture has generated a long string with numbers and digits in it. Therefore this is a better test than the hello world and the 7 test combined.

The real value of autofixture is not for primitive types but for arranging more complex types. It can take your own types and populate all of the public fields and properties for you, saving you a lot of lines of code. You can customise how it generates the anonymous data for you, it will make use of any data annotations in your code, and there is an extension for auto mocking.

For further information on Auto Fixture this is a useful course:
http://www.pluralsight.com/courses/autofixture-dotnet-unit-test-get-started

Advertisements

2 thoughts on “Survival tips for living with MSTest

  1. Pingback: Zombie Code Kill

  2. Pingback: Learning Unit Testing and Test Driven Development | Zombie Code Kill

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s