codeflood logo

Automated Testing and Sitecore - Part 2

In the first post of this series I mention I make use of a custom NUnit test runner which runs in the Sitecore context. In this post I'll take you through creating such a test runner.

The test runner is just a web form deployed to the webroot of your Sitecore site. Because it runs inside your Sitecore application it runs within a Sitecore context.

The test runner allows running a selection of test categories from your test suite, so you don't have to run all of your tests on each test run.

The first thing we need to do is create a test project to contain your NUnit tests and the test runner itself. Prior to Sitecore 6.0, Sitecore used to contain NUnit assemblies (and a test runner too) and I used to reference these. Unfortunately as of Sitecore 6.0 NUnit has been removed, so you'll first have to go and download NUnit , then make references in your project to nunit.core, nunit.core.interfaces and nunit.framework.

Next, create a new web form which will be the test runner. In the code behind of this form implement the NUnit.Core.EventListener interface. The primary method I'm interested here is TestFinished, but you can use the others if you want to do some more advanced stuff with your test runner. TestFinished is called each time a test is, well, finished and it allows you to log statistics about the test and the tests outcome. Refer to the full code (link at the bottom of this post) to see how I collect this information.

Now we can load the test suite in the Page_Load method of the page. Add a using statement for NUnit.Core and System.Reflection in the code behind and declare a member variable to store the TestSuite in.

private TestSuite m_testSuite = null;

Then place the following code in the Page_Load method.

CoreExtensions.Host.InitializeService();
TestPackage pkg = new TestPackage(Assembly.GetExecutingAssembly().Location);
m_testSuite = new TestSuiteBuilder().Build(pkg);

The above assumes your tests will be located in the same assembly as the test runner. If they are not then you'll have to pass the location of the test suite assembly to the TestPackage constructor. We can run the test suite by calling the Run method on the test suite.

TestResult result = m_testSuite.Run(this);

We can then inspect the result to see if we passed or not. That's a simple test runner, but it won't let us filter the tests to run, so the above code will be an all or nothing affair. To filter the tests which will be run there is an overload to the Run method which accepts an ITestFilter. The default filters can be found in the NUnit.Core.Filters namespace. I'll use a category filter. This filter accepts the category names as a string to it's constructor. But we don't want to hard code any catgeory values, so we'll need to read them out of the test suite assembly.

This sounds like it should be easier than it actually is. This is to to with the stucture of the test suite assembly and the objects NUnit exposes to us (or maybe I didn;t dig deep enough :) ). TestSuite contains an IList property called "Categories" which will list the categories for the current level. The thing is that the NUnit tests are heirarchical, so we'll have to traverse each nested ITest from the TestSuite's Tests property to generate a full list of all categories in the current test suite assembly. The following method will do this for you.

private void GetCategories(TestSuite suite, StringCollection cats)
{
    if (suite.Categories != null)
    {
    for (int i = 0; i < suite.Categories.Count; i++)
        if (!cats.Contains((string)suite.Categories[i]))
        cats.Add((string)suite.Categories[i]);
    }

    for (int i = 0; i < suite.Tests.Count; i++)
    if(((ITest)suite.Tests[i]).IsSuite)
        GetCategories((TestSuite)suite.Tests[i], cats);
}

To invoke it just pass it the current test suite and a string collection to populate. Once you have the list of categories you can list them on the web form in a check box list or similar, then construct a category filter from the selected categories before calling run.

You can use the above code examples to construct your own custom NUnit test runner or download the full source for my custom test runner from my website: /testrunner

Comments

[...] Automated Testing and Sitecore part 2 &#8211; Custom test runner [...]

Leave a comment

All fields are required.