Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to run all your NUnit tests in a solution in Visual Studio

0.00/5 (No votes)
22 Sep 2009 1  
An article on always running all your NUnit tests after a build.

Sample Image

Introduction

NUnit is an excellent piece of software that has greatly improved the quality of .NET code throughout the world.

However, I feel it has a small usability problem in that when you want to run all your tests in a solution from Visual Studio, you have to manually set up a NUnit project file to do so. This can be a pain, particularly if you add or remove projects from your solution.

When doing Test Driven Development, the steps we take typically are like this:

  1. Write some code.
  2. Compile.
  3. Run all tests.

Ideally, we would want the third step to happen automatically after the second, like so:

  1. Write some code.
  2. Compile and automatically run all tests.

I have written this add-in to achieve this. When a project is built, it checks to see if the project has a reference to "nunit.framework". If it does, then we make the assumption that this is a test project containing unit tests, and the built DLL path is remembered. After the full build is completed, a NUnit project file is created containing these paths. Any existing NUnit GUI process is killed, and a new NUnit GUI process is started with the created project file. The new process then runs the tests.

This approach has the following advantages:

  1. You can just press Ctrl+Shift+B to compile your projects and run any unit test.
  2. The tests are run using the GUI test runner designed to work with nunit.framework. This means you have the full source, unit tests for the code, and a large community backing it.
  3. No need to mess around with the NUnit project files yourself.
  4. No need to pay for a commercial add-in with the same functionality (but might have bugs in!), for which you don't have the source code.

One limitation is that your project folders must be under the same root directory, i.e., you can have solutions with folders on the "c:\" drive or "d:\" drive separately, but not mixed on both the "c:\" and "d:\" drives in the same solution. This is a general limitation of NUnit projects.

Background

For more information on NUnit, you can read the NUnit documentation.

For more information on Visual Studio extensibility, you can look at the LineCounter project, or my own "Improving Code Auto Completion in C#" article on this site.

Installation

Unzip the demo files to a folder somewhere. Move the "Jonno Nunit Helper.AddIn" file to the "your path\My Documents\Visual Studio 2008\Addins" folder. Open the file up and change the following line to point to the location of the Jonno.AddIns.NunitHelper.dll file:

<Assembly>C:\JonnoTest\Jonno.AddIns.NunitHelper.dll</Assembly>

If you are running the source, then the "Jonno Nunit helper.AddIn" file will probably be missing. Add it to the add-in project, making sure you link it to the version in your add-ins folder, rather than adding it.

If you wish to run the Unit Tests, you will need Nunit 2.5 and Rhino Mocks 3.6. I have only tested this on Visual Studio 2008. I have done 99% of my testing on C# projects, but have run against VB.NET projects as well. I see no reason why the add-in should not work equally well for both languages.

Using the Code

The Connect class handles the Visual Studio events we need. We need to hook into the build events that we need, which are OnBuildBegin, OnBuildDone, and OnBuildProjConfigDone, in the OnConnection method, like so:

var events = this.ApplicationObject.Events as Events2;

if (events == null)
{
    return;
}

this.BuildEvents = events.BuildEvents;

this.BuildEvents.OnBuildBegin += this.OnBuildBegin;
this.BuildEvents.OnBuildDone += this.OnBuildDone;
this.BuildEvents.OnBuildProjConfigDone += this.OnBuildProjConfigDone;

Of course, we need to unhook these events in the OnDisconnection method:

if (this.BuildEvents != null)
{
    this.BuildEvents.OnBuildBegin -= this.OnBuildBegin;
    this.BuildEvents.OnBuildDone -= this.OnBuildDone;
    this.BuildEvents.OnBuildProjConfigDone -= this.OnBuildProjConfigDone;
}

The OnBuildBegin method then simply initializes a new list of the project paths that we are interested in:

this.NunitProjectNames = new List<string>();

The OnBuildProjConfigDone method runs after each project is built. If it was not a success, we cancel the whole build. If it was, we find the project that was just built using the name:

var projects = this.ApplicationObject.Solution.Projects;

foreach (Project project in projects)
{
    if (builtName == project.Name)
    {
        return (VSProject2)project.Object;
    }
}

We then check the references to see if one to "nunit.framework" is set. If it is, we construct the path of the built DLL using the project's output path (using a good default value of "bin\Debug"), and store it in the list:

foreach (Reference reference in envProject.References)
{
    if (reference.Name != "nunit.framework") 
    {
        continue;
    }
     
    var fullName = envProject.Project.FullName;
    var outPutPath = "bin"
                     + System.IO.Path.DirectorySeparatorChar
                     + projectConfig
                     + System.IO.Path.DirectorySeparatorChar;

    foreach (Configuration s in envProject.Project.ConfigurationManager)
    {
        if (s.ConfigurationName != projectConfig) 
        {
            continue;
        }
         
        outPutPath = s.Properties.Item("OutputPath").Value.ToString();
        break;
    }

    this.NunitProjectNames.Add(this.Logic.GetBuiltAssemblysPath(fullName, outPutPath));
    break;
}

The OnBuildDone method runs after a build has successfully completed. It calls the logic to create the NUnit project file, and kills/starts the NUnit process.

Most of this logic has been put inside the Logic class, which also handles any string manipulations.

The ConcreteProcess class handles the actual killing or starting of the NUnit process by calls to the framework System.Diagnostics class.

Points of Interest

The code outlined above has a problem in that if we start a test project to debug a test, you will get two instances of the NUnit GUI appear! To counteract this, I also had to add handlers for the Debug.Start command which removes the handlers for the build events, and thus turns the code off. Then, when you come out of debug mode, the build events are plugged back in.

History

  • 22nd September, 2009: Initial version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here