Running NUnit in the Windows Azure Emulator

Download Test Project Here

If there is an easier way to do what I am about to describe, someone please me. I am guessing there is some clever way to use cspack and csrun to allow me to run NUnit in the Azure emulator, but for the life of me I can’t get it to work. Therefore, I am using this admittedly goofy approach.

Disclaimer: The approach is tailored to a web role. The sample code is really a proof of concept.

"I think I have NUnit running"

Basic Approach

My basic approach is to copy the output from my test project into a subdirectory beneath the bin folder of my main web role (bin/test). Instead of using a test runner – in my case TestDriven .NET – I run my web role. There is a page on my site that will run NUnit and output the test results to the browser. If I need to, I can put break points in my tests and the debugger will let me step into the code.

Initial Setup

1. In the bin directory of your web role, create a sub-directory called test. In my case this is /TestSiteWebRole/bin/test.

2. Add a post-build event to your test project (replacing TestSiteWebRole with your project):

copy “$(TargetDir)*.*” “$(SolutionDir)TestSiteWebRole\bin\test”

3. In your web role add references to nunit.core.dll and nunit.core.interfaces.dll.

Adding a Test Runner Page (or Running NUnit from Code)

4. Add a page to your web role. In the example code, this is NUnit.aspx. There are several horrors to behold here. One, my example code is using WebForms. Two, there are a bunch of hardcoded references in it. I’m leaving it up to you to take this code beyond a POC.

public partial class NUnit : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        RunTests();

    }

    private void RunTests()
    {
        CoreExtensions.Host.InitializeService();

        string testPath = Server.MapPath("bin/test");
        string testAssemblyPath = Path.Combine(testPath, "TestSite.Tests.dll");
        var package = new TestPackage(testAssemblyPath);
        var builder = new TestSuiteBuilder();
        var suite = builder.Build(package);
        var result = suite.Run(new MyListener(Response), TestFilter.Empty);
    }

5. The NUnit page uses another class called MyListener. This is just a class that implements NUnit.Core.EventListener (which is an interface). My implementation is about as simple as you can get. I am sure you can do much better.

public class MyListener : EventListener
{
    private readonly HttpResponse _response;

    public MyListener(HttpResponse response)
    {
        _response = response;
    }

    public void RunStarted(string name, int testCount)
    {
        _response.Write(name);
    }

    public void RunFinished(TestResult result)
    {
    }

    public void RunFinished(Exception exception)
    {
    }

    public void TestStarted(TestName testName)
    {
        Print("<p/>");
        Print("{0}", testName.Name);
    }

    public void TestFinished(TestResult result)
    {
        if (result.ResultState == ResultState.Failure)
        {
            Print("FAILED");
            Print(result.StackTrace);
        }
        else if (result.ResultState == ResultState.Success)
        {
            Print("SUCCESS");
        }
        else
        {
            // do something phenomenal here
        }
        Print(result.Message);
    }

    public void SuiteStarted(TestName testName)
    {
    }

    public void SuiteFinished(TestResult result)
    {
    }

    public void UnhandledException(Exception exception)
    {
    }

    public void TestOutput(TestOutput testOutput)
    {
    }

    private void Print(string msg)
    {
        _response.Write(msg);
        _response.Write("<br />");
    }

    private void Print(string msg, params string[] args)
    {
        _response.Write(string.Format(msg, args));
        _response.Write("<br />");
    }
}

The test project contains one test:

[Test]
public void role_environment_is_available()
{
    Assert.IsTrue(RoleEnvironment.IsAvailable);
}

If everything is set up correctly. You should get the following output when you run the NUnit page:

role_environment_is_available
SUCCESS

Leave a Reply