Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / XUnit

Migrate MsTest Test Suites to xUnit

5.00/5 (1 vote)
24 Nov 2023CPOL2 min read 6.7K  
From MsTest to xUnit

Introduction

If you use MS Test for unit testing only, probably you may just ignore this article, since there's no value to migrate the codes of unit testing that have been working well.

However if you have been using MS Test as test harness to construct some integration test suites, and you might want to run the test suites independent of Visual Studio, then you may want to use xUnit. In this article, I would presume you have experience in unit testing and integration testing through MS Test and xUnit.

This article introduces a few tips for efficiently transforming MS Test codes to xUnit codes.

Background

Over years before 2012, I have been using MsTest, NUnit and xUnit. Though xUnit is a bit harder to learn comparing with the other two, I have exclusively been using xUnit for green field projects in since 2012 due to its speed and extensibility for integration testing. From time to time, I migrated some legacy test suites from MsTest to xUnit, and this article is largely based on my blog Fully migrated to xUnit from MsTest published in 2014 for .NET Framework, however, with some updates after so many years:

  1. xUnit repository had moved from CodePlex to GitHub, and the authors had published a migration guide: Migrating from MSTest to xUnit.net
  2. Microsoft had released an open source console app XUnitConverter in 2015 for converting projects from using MSTest to XUnit..
  3. xUnit.NET is on .NET Core these days, and is working well with your libraries on .NET Framework.

Using the Code

The mapping of the assert statements from MsTest to xUnit is straightforward. Simple text replacement could be good enough for 95% of the scenarios. So I had written the following PowerShell scripts:

PowerShell
Param(
  [string]$ProjectDir
)
get-childitem $ProjectDir -recurse -include *.cs |
 select -expand fullname |
  foreach {
            (Get-Content $_) -replace '\[TestMethod\]','[Fact]' `
            -replace 'Assert.AreEqual' , 'Assert.Equal' `
            -replace 'Assert.AreNotEqual' , 'Assert.NotEqual' `
            -replace 'Assert.IsTrue' , 'Assert.True' `
            -replace 'Assert.IsFalse' , 'Assert.False' `
            -replace 'Assert.IsNotNull' , 'Assert.NotNull' `
            -replace 'Assert.IsNull' , 'Assert.Null' `
            -replace '\[TestClass\]' , ' ' `
            -replace 'Assert.AreNotSame' , 'Assert.NotSame' `
            -replace 'Assert.AreSame' , 'Assert.NotSame' `
            -replace 'Assert.IsInstanceOfType' , 'Assert.IsType' `
            -replace 'Assert.IsNotInstanceOfType' , 'Assert.IsNotType' `
            -replace 'using Microsoft.VisualStudio.TestTools.UnitTesting' , 'using Xunit' `
            | Set-Content -Encoding utf8 $_
            }

Then run something like:

.\mstest2xunit.ps1 c:\MyProjects\MySolution\MyTestsProjectFolder

Steps

  1. Create a new xUnit test project on .NET Core and import the same dependencies except those for .NET Framework and MS Test.
  2. Add those CS files of the legacy MsTest project to the xUnit project.
  3. Run mstest2xunit.ps1.

Some Trivial Steps

  1. Replace ExpectedExceptionAttribute with Assert.Throws.
  2. Replace MsTest attributes like DeploymentItemAttribute with xUnit fixtures.

Some Fixtures to Replace MsTest Attributes

Points of Interest

The migration guide from xUnit.NET and the XUnitConverter of Microsoft are through in-project migration, that is, altering the current MsTest project. I had used such in-project migration approach but manually long time ago as well, however, if you have some very legacy MsTest projects on older .NET Framework, from time to time, you may find some mysterious obstacles, probably caused by some old csproj format. Having a clean start with a new xUnit project (.NET Core) could be overall having less hassle caused by legacy issues.

History

  • 24th November, 2023: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)