Web Testing with MbUnit and WatiN Part 2: Controlling Localhost and IIS Express

One important aspect of web testing which is not so often discussed in blogs or articles is how to run tests against a web project running in debug mode on the local host. Microsoft provides two options to let you debug web projects locally: the Visual Studio development server and IIS Express. In this second part of our series on writing web integration tests, we’re going to demonstrate how to use the WebTestServer<T> class to start either server from within a running test suite.

In this article, you will

  • Create a simple one page website project for testing
  • Create a web test project that tests it against the VS Development Server
  • Alter the website and test project to test the page using IIS Express.

If you have already read and followed part one of this tutorial, you will already have all you need to follow this part. If not, you will need the following installed.

  • Visual Studio 2010 or later and .NET 4.0 or higher. You can install the free Express edition of Visual Studio 2010 here.
  • Gallio \ MbUnit. The latest release is v3.3.442 and can be downloaded here as either MSI installer or zipped binary files. The Gallio wiki covers the installation process for both.
  • The MbUnit.Web helper project that comes as a part of the Web Testing with MbUnit and WatiN sample code project on GitHub.
  • WatiN. The latest release is v2.1.0.1196 and can be downloaded here.

It is also assumed that you know how to run tests with Gallio. If you don’t, this short tutorial in the Gallio wiki is a good place to start before carrying on.

The Problem To Solve

Before we start looking at WebTestServer<T>, let’s look at the problem we’re solving. Download the WebServerTestDemoStart.zip file from the top of this article, unpack it, and open it in Visual Studio. You’ll see it contains three projects.

The WebServerDemoSite project contains the single page we’re testing (figure 1). It runs on the Visual Studio Development Server.

The page to test

The WebServerDemoTests project contains one test to ensure that, once the button is clicked, any text in the TextBox is echoed back to the screen prefixed with “Hello”.

using MbUnit.Web;
using MbUnit.Framework;
using WatiN.Core;

namespace WebServerDemoTests
{
  [TestFixture]
  public class DefaultPageTest : AbstractBrowserTestFixture
  {
    [Test, RunBrowser]
    public void PostbackTest()
    {
      var page = GoToPage();
      page.TextBoxName.TypeText("McFly");
      page.ButtonOk.Click();
      Assert.AreEqual(page.SpanResult.Text, "Hello, McFly.");
    }

    [Url("http://localhost:2598/WebForm1.aspx")]
    public class Page : WatiN.Core.Page
    {
      [FindBy(Id = "txtName")]
      public TextField TextBoxName;

      [FindBy(Id = "btnOK")]
      public Button ButtonOk;

      [FindBy(Id = "lblResult")]
      public Span SpanResult;
    }
  }
}

The MbUnit.Web project contains several helper classes that WebServerDemoTests is already using to keep its tests clean and easy to read. (See part one for more on this).

Try to build the whole solution. You will likely need to re-reference the Gallio, MbUnit, WatiN.Core and ShDocVw.Interop assemblies in the MbUnit.Web and WebServerDemoTests projects for this to work. Once built, try and run the only test in the solution, PostbackTest. You’ll see that while the test spins up a browser to test the page, the test web server has not started to make the page available for testing. If you start debugging the page in Visual Studio and run the test again, you’ll see the test pass successfully, but you’ll also need to stop debugging the web page before you’ve returned your machine to its original state prior to the test being able to run.

Within an automated test harness, the need for to start the test server manually is unacceptable. We need our tests to control this, whether the web page is being tested on the Visual Studio Development Server or IIS Express. Fortunately, MbUnit.Web contains the classes to do just that.

Testing Against The Visual Studio Development Server

Let’s start by automating the Visual Studio Development Server in our tests.

Configuring the Server

When a developer presses F5 from within the Visual Studio IDE to run and debug her web application, Visual Studio runs an executable called WebDev.WebServer40.exe. This spins up the server ready to serve the page being debugged. It also derives and includes a number of parameters that the server needs to work properly,

  • /port : the port number on which you want to run the web site
  • /path : the physical location of your web application (i.e. the root directory of the ASP.NET project). This can be either an absolute or a relative path.
  • /virtual:”/Home/About” : the virtual path of the starting page.

For example, to spin up the server showing http://localhost:1234/Home/About, you might call

WebDev.WebServer40.exe /port:1234 /path:”C:\Temp\MyWebProject” /virtual:”/Home/About”

Once in place, the the MbUnit.Web.DevelopmentServer class will make this call silently for you, but you’ll need to specify the parameters in a configuration file.

  • Right click the WebServerDemoTests project in solution explorer and select Add > Add New Item
  • Select Application Configuration File and click Add.
  • Replace its contents with the following.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="webTestServer" type="MbUnit.Web.ConfigurationSectionHandler, MbUnit.Web" />
  </configSections>

  <webTestServer>
    <server>Development Server</server>
    <virtualPath>/</virtualPath>
    <portNumber>2598</portNumber>
    <sitePath>D:\Code\WebServerTestDemo\WebServerDemoSite</sitePath>
  </webTestServer>

</configuration>

Of the four elements given here, only sitePath is mandatory. The sitePath, portNumber and virtualPath elements correspond to the /path, /port and /virtual parameters for WebDev.WebServer.exe described earlier. The server element sets which test web server is being used within the tests. It has two possible values

  • Development Server (default) : Visual Studio development server
  • iisexpress

Note that the DevelopmentServer class is hardcoded with the path to the .NET 4.0 version of WebDev.WebServer.exe. You’ll find it in Settings.cs in the MbUnit.Web project. If you’re using an earlier version of .Net you’ll need to change this to one of the following paths and then recompile MbUnit.Web.

  • VS2008 : %CommonFiles%\Microsoft Shared\DevServer\9.0\WebDev.WebServer.exe
  • VS2005 : \WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.exe

Automating the Server From The Tests

Once the configuration is complete, there’s very little additional code to write to have the tests start up the server as required. The key is to create a new class deriving from AbstractBrowserTestFixture<T>. If you recall from part 1, this is a very simple class whose primary purpose is to manage the life cycle of the browser.

Add a new class file named BrowserTestFixture.cs to the WebServerDemoTests project and add the following code to it.

using MbUnit.Web;
namespace WebServerDemoTests
{
  public abstract class BrowserTestFixture : AbstractBrowserTestFixture
  where TPage : WatiN.Core.Page, new()
  {
    protected BrowserTestFixture()
      : base(() => WebTestServer.Instance.LocalHostUrl)
    {}
  }

  class ScopeMarker
  {}
}

This new class will be the base class for all your web test fixtures that target localhost. Note how the base constructor is passed the address of the local web application, by getting (and possibly creating) the singleton instance of the development server. The generic type parameter TScope is used to specify in which assembly the parameters for the development server are located. We’ve chosen here to pass a simple empty class called ScopeMarker. Our development server controller will use that type to locate the configuration data file and load the parameters we have defined previously.

With the base class ready, we only need to make two simple changes to for our test to start the test server automatically. First, the web test fixture class must derive from the new base class and not AbstractBrowserTestFixture<T> directly.

[TestFixture]
public class DefaultPageTest : BrowserTestFixture
{
  …

Second, the Url parameter decorating the WatiN Page class should contain a path relative to the start Url of the site, such as “/Default.aspx”.

[Url("/WebForm1.aspx")]
public class Page : WatiN.Core.Page
{
  …

If you run your test now, you’ll see the test server starts as required.

Testing Against IIS Express

Running web tests against IIS Express instead of the Visual Studio Development Server is easy. In fact, the exact same method shown above can be followed with a slight tweak to the configuration file. We can start IIS Express by starting a new process with the appropriate command line arguments. For example

iisexpress.exe /port:1234 /path:"C:\Temp\MyWebProject"

All that’s required then is to update your test project to iisexpress (lower case, all one word), by adding a server element to app.config set to IIS Express (or altering that element if it already exists).

<server>iisexpress</server>

To demonstrate, right click the WebServerDemoSite project in Solution Explorer and select Use IIS Express. Make the change to the server element in app.config as described above and run the test. You’ll see IIS Express now starts up and the test runs successfully.

Summary

In this article, we’ve seen how to automate the starting of both the Visual Studio development server and IIS Express so we can run web tests against localhost without any manual assistance.

In the final part of this tutorial, we’ll see how to test asynchronous requests.

You might also like...

Comments

About the author

Yann Trevin

Yann Trevin Luxembourg

Yann is a software engineer working at the research center of a large tire manufacturing company. He's mostly involved in web, desktop and mobile enterprise projects built on the .NET stack. He ...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Engineers are all basically high-functioning autistics who have no idea how normal people do stuff.” - Cory Doctorow