Automating classic ASP unit tests with NUnit and C#

In this fourth part of a series on classic ASP unit testing we will explore how we can automate our unit tests using the 2.0 .Net framework, C# and NUnit so that we need not call our test ASP pages directly.

Parts one, two and three walked us through the reasons for our framework and introduced the core UnitTester VBScript class that emits HTML for our assertions when we call a test ASP page that uses the class and asserts.
Rather than manually call this test ASP page (and any further ones that we develop) it would help us greatly if we could automate this using a common test framework and runner.

We start this automation with a C# class that will serve as a base NUnit test fixture - we will call it AspFixture and store it in the root of our test project (see illustration).
Note that we have a "lib" folder with the nunit.framework.dll file and this is referenced by the project.

The initial code for the AspFixture class is as follows:

namespace ASPTesting.Tests
{
    public abstract class AspFixture
    {
        private const string BASE_URI = "http://localhost:990/UnitTests/ASPTesting.Tests/";

        public void RunAspTest(string uri)
        {
            var request = WebRequest.Create(BASE_URI + uri);

            ICredentials requestCredentials = CredentialCache.DefaultCredentials;
            request.Credentials = requestCredentials;

            using (var response = request.GetResponse())
            {
                using (var stream = new StreamReader(response.GetResponseStream()))
                {
                    string html = stream.ReadToEnd();

                    Assert.IsFalse(html.Contains("Failed"));
                }
            }
        }
    }
}

This class serves as an abstract base class for any fixtures that we write and encapsulates the automation of our ASP test run. First it creates a WebRequest instance from the uri provided and supplies default credentials. Then a WebResponse instance is obtained via request.GetResponse().

We then obtain a StreamReader instance and read the HTML into a string. Finally we make a simple assertion that this HTML does not contain the word "Failed". Through using statements we ensure Dispose() is called to free all resources.

This forms the beginnings of a base class and is pretty primitive (hard coded constant uri path for instance) -  later in the series we will improve upon this but for now it enables us to automatically check whether any assertions we are calling emit "Failed" in the HTML.

To see this in action we now create a new C# class called "TestFixture.cs" within our UnitTest folder (alongside its Test.asp counterpart):

namespace ASPTesting.Tests.UnitTests
{
    [TestFixture]
    public class TestFixture : AspFixture
    {
        [Test]
        public void Test()
        {
            RunAspTest("UnitTests/Test.asp");
        }
    }
}

This class is decorated with the NUnit TestFixtureAttribute indicating it is a unit test and inhertis from the base abstract class we just set up - it makes just one call to the RunAspTest() method with the location of our "Test.asp" file.

We can now run this TestFixture and it will call out to our ASP page, parse the HTML and assert whether any have failed - in our previous example (part three) we have an assertion that fails, so we expect our first test run to fail.

Using Resharper as our test runner in this example (obviously any NUnit test runner will suffice), we right click on the file in the solution and choose "Run Unit Tests":

We receive an NUnit AssertionException because the HTML does indeed contain the word "Failed" and our test run fails.
We now have automated classic ASP unit tests!

We finish up this part of the series by fixing our assertion problem and illustrating automation in action.
Let us go back to the Test.asp file and amend our assertion:

<!--#include virtual="Tests/UnitTester.asp"-->
<%
Dim tester
Set tester = new UnitTester
tester.Init("Testing our unit tester class")
tester.Given("that we are testing our new framework")
tester.AssertAreEqual 1, 1
tester.AssertAreEqual "this", "this"
tester.AssertAreEqual "yes", "yes"
%>

Now when we run our unit tests we get a green bar indicating our assertions all pass:

In the next part of this series we will start to implement our user stories showing the unit test framework in action and illustrating how we can use test-first development with classic ASP.



3 comments:

  1. Mike Henry January 26, 2009 at 8:00 PM

    Thanks for sharing this. I've been meaning to setup some sort of automation to run some ASPUnit tests via NUnit but haven't yet gotten around to it. So your example is helpful.

     
  2. Justin Davies January 27, 2009 at 11:53 PM

    Hi Mike,
    Thanks for the feedback. I've been considering putting this small project up onto codeplex or similar repository with all the VBScript assertion code and automation available - if you think that would be useful let me know and I'll see if I can sort it out.

     
  3. Mike Henry May 19, 2009 at 5:21 AM

    Hi Justin,
    FYI I just published my test runner to run ASPUnit tests via NUnit. It's called ASPUnitRunner. Your example was helpful.