Geeks With Blogs

News



Microsoft Store

Support This Site


AddThis Social Bookmark Button

Locations of visitors to this page

Subscribers to this feed

TwitterCounter for @sdorman

Creative Commons License


Scott Dorman Microsoft MVP, Software Architect, Developer, Author

I have been writing a lot of unit tests over the past month using the Microsoft Test (MSTest) unit testing framework that is now part of Visual Studio 2008 Professional Edition (and higher SKUs). Currently I have about 223 unit tests covering 39 classes (about 18K lines of code, 325 methods and 176 properties) with a code coverage percent of 97%.

The classes that I’m testing previously had NUnit tests (although not as many as I currently have) and used NCover and NCover Explorer for my code coverage analysis. I had looked at MSTest when it first came out and decided against using it because it was only available in the Visual Studio Team System SKUs, which meant it wasn’t generally available to the development community at large, and required Visual Studio to be installed in order to use it.

Since then, Microsoft has addressed both of those issues and I decided it was time to give MSTest another look. In doing so, I decided to see if it would be possible to leverage the existing NUnit tests rather than starting completely from scratch. One word of caution…if you use the newer constraint model in NUnit, your unit tests will not easily migrate to MSTest and you are probably better off starting fresh using MSTest.

It turned out to be a relatively painless process that can be broken down to the following steps:

  1. Replace the reference to the Nunit.Framework assembly with a reference to the Microsoft.VisualStudio.QualityTools.UnitTestFramework assembly.
  2. Replace the “using Nunit.Framework” line with “using Microsoft.VisualStudio.TestTools.UnitTesting”
  3. For each file containing unit tests, replace the following attributes (you can use global search and replace for this):
  4. NUnit Attribute MSTest Attribute
    TestFixture TestClass
    Test TestMethod
    SetUp TestInitialize
    TearDown TestCleanup
    TestFixtureSetup ClassInitialize
    TestFixtureTearDown ClassCleanup
       
  5. Replace the following method calls:
  6. NUnit Method Code MSTest Method Call
    Assert.Ignore Assert.Inconclusive

At this point, the easy stuff is done, but Visual Studio will not recognize your project as an MSTest unit test project. (This only applies if you don’t create a new Unit Test project in Visual Studio to hold your converted tests.) If that’s the case, you need to edit the project file using a text editor and add the following tag to the first <PropertyGroup> in the XML:

   1: <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

(These Guids are for a C# project. For a VB project, replace the second Guid with {F184B08F-C81C-45F6-A57F-5ABD9991F28F}.)

Depending on the complexity of your original NUnit tests, you may be done at this point. However, if you relied on NUnit TestFixtureSetup or TestFixtureTearDown methods you will need to make a few other changes.

In NUnit, these attributes would be applied to a non-static void method that takes no parameters. For MSTest, the methods must be static and the ClassInitialize method must take a TestContext parameter. This also means that you should add a public TestContext property as well. What you end up with is code that looks like this:

   1: private TestContext testContextInstance;
   2:  
   3: /// <summary>
   4: ///Gets or sets the test context which provides
   5: ///information about and functionality for the current test run.
   6: ///</summary>
   7: public TestContext TestContext
   8: {
   9:     get
  10:     {
  11:         return testContextInstance;
  12:     }
  13:     set
  14:     {
  15:         testContextInstance = value;
  16:     }
  17: }
  18:  
  19: [ClassInitialize()]
  20: public static void ClassInit(TestContext context)
  21: {
  22:     MessageBox.Show("ClassInit " + context.TestName);
  23: }
  24:  
  25: [ClassCleanup()]
  26: public static void ClassCleanup()
  27: {
  28:     MessageBox.Show("ClassCleanup");
  29: }

If you had code in your NUnit TestFixtureSetup or TestFixtureTearDown methods that manipulated non-static data you will need to rework your tests or move that code to a constructor/finalizer combination to achieve the same results.

Unfortunately, the Assert (and related classes) used by MSTest are not as complete as the ones offered by NUnit so you may also end up changing some of your tests. The following Asserts are not available in MSTest:

  • Assert.IsNaN
  • Assert.IsEmpty
  • Assert.IsNotEmpty
  • Assert.Greater
  • Assert.GreaterOrEqual
  • Assert.Less
  • Assert.LessOrEqual
  • Assert.IsAssignableFrom
  • Assert.IsNotAssignableFrom
  • CollectionAssert.IsEmpty
  • CollectionAssert.IsNotEmpty
  • StringAssert.AreEqualIgnoringCase
  • StringAssert.IsMatch
  • FileAssert.AreEqual
  • FileAssert.AreNotEqual

You may be tempted to replace StringAssert.IsMatch with StringAssert.Matches from MSTest but they really aren’t equivalent methods. StringAssert.Matches matches the actual result against a regular expression pattern.

The other thing to watch out for is any place you use the ExpectedException attribute. The syntax is identical between NUnit and MSTest, however the meaning is not. In NUnit, the message parameter is used to verify the message of the exception (by comparing the Message property of the exception with this text). MSTest uses this text as the message to display if the exception is not thrown. There are better ways to test for exceptions that don’t use the ExpectedException attribute at all.

All in all, I’ve been very happy with the relative ease of migrating my NUnit tests to MSTest and using the MSTest framework in general. Yes, there are things that the older unit testing frameworks provide that MSTest does not, but I believe that is just a matter of age. In time, MSTest will offer the same functionality. The nice thing about MSTest is that it is built in to Visual Studio and the code coverage and unit testing capabilities are integrated with the IDE without requiring additional tools, add-ins, macros, or other hoops in order to run your tests and evaluate the results. Everything you need to write effective unit tests, analyze the results and ensure good code coverage is already available to you.

Technorati Tags: , ,
DotNetKicks Image
Posted on Saturday, January 31, 2009 12:39 PM .NET (General) , .NET (C#) | Back to top


Comments on this post: Migrating from NUnit to MSTest

# re: Migrating from NUnit to MSTest
Requesting Gravatar...
What's missing from this post is a real reason to migrate from NUnit to MSTest in the first place, other than IDE support. Having unit testing and code coverage baked into the IDE is convenient during development, but makes it much more difficult to integrate into a continuous integration process.
Left by Nat eKohari on Jan 31, 2009 12:44 PM

# re: Migrating from NUnit to MSTest
Requesting Gravatar...
Scott,

But you still have to install Visual Studio on the build server. Redistribution of the MSTest executable and DLLs without it is prohibited, at least according to this post:

http://social.msdn.microsoft.com/Forums/en-US/vststest/thread/2897fb68-ef48-4941-a49e-fe8cb1b5aced/

That's the fundamental issue I have with it. I know it can be integrated, but to do that, I have to install crap on my build server that defeats the purpose of it being a clean machine.

Unless you've found a workaround?

Cory
Left by Cory Foy on Feb 02, 2009 10:30 AM

# re: Migrating from NUnit to MSTest
Requesting Gravatar...
Cory

Why do you not want to install Visual Studio on the build server? I just don't see the issue. There is no licencing requirement and there are lots of reasons other than Testing that require VS.


Nat

You would want to use MS Test as it is tightly integrated into the IDE as well as automatically porting data on code coverage and test result back into TFS which is then shipped to a Data Warehouse and Cube ready to be reported on .

Try getting any third party framework to support that is difficult and being able to report on test results and coverage is crucial to being able to identify problems early based on trended data.
Left by Martin Hinshelwood on Mar 13, 2011 6:07 PM

# re: Migrating from NUnit to MSTest
Requesting Gravatar...
Thanks for the post, it solved my problem of my project not being recognized as a test project.
Left by Eric Flynn on Sep 22, 2011 7:59 PM

# re: Migrating from NUnit to MSTest
Requesting Gravatar...
Great post, helped me a lot.

In VS2010, I had to use "using Microsoft.VisualStudio.TestTools.UnitTesting;" instead of what is in your post. Same reference to "Microsoft.VisualStudio.QualityTools.UnitTestFramework" though.

cheers :-)
Left by Stretch on Oct 26, 2011 10:19 PM

# re: Migrating from NUnit to MSTest
Requesting Gravatar...
oops ignore that last comment. I'm a dullard!
Left by stretch on Oct 26, 2011 10:20 PM

# re: Migrating from NUnit to MSTest
Requesting Gravatar...
Here is a neat trick:

using NUnit.Framework;

#if !NUnit
using TestFixtureAttribute = Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute;
using SetUpAttribute = Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute;
using TestAttribute = Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute;
#endif

You can actually use NUnit's assertion classes with MSTest. This will give you the best of both worlds. Declare NUnit on your CI server and use MSTest to run the tests in VS. This will allow you to use NUnit's nice API even with VS 2012 Express.
Left by Jarrod on Dec 04, 2012 4:19 PM

# re: Migrating from NUnit to MSTest
Requesting Gravatar...
In the article above you said that Nunit, and used NCover and NCoverExplorer for coverage. I also have many unit tests in NUnit and use NCover and NCoverExplorer for coverage. You didn't say in the article how to do coverage if you convert to Microsoft MSTest.

How would you recommend to get coverage info now that NCover no longer exists and works in 64 bit environments?

Thanks,
Rick
Left by Rick Wirch on Jun 16, 2014 11:47 AM

Your comment:
 (will show your gravatar)


Copyright © Scott Dorman | Powered by: GeeksWithBlogs.net | Join free