Extreme ASP.NET Makeover: Testing - Using WatiN

Download

Right click “Save as…”

  • Mid Quality WMV (Lo-band, Mobile)
  • MP3 (Audio only)
  • MP4 (iPhone, Android)

Using WatiN to Test a Local Web site

Now that we have successfully run a simple WatiN test against a remote Web site, we turn our attention to using WatiN to test ScrewTurn Wiki. We won't want to deploy ScrewTurn Wiki to a server every time we want to run our acceptance test suite using WatiN. Instead, we will use the ASP.NET Development Server (WebDev.WebServer.exe), which is better known by its code name "Cassini." It is installed with .NET Framework 2.0 and above in C:\Windows\Microsoft.NET\Framework\v2.0.50727\. Another option would be to use a local IIS instance, but the ASP.NET Development Server has the nice feature that it can be started and/or stopped by a normal user.

We want to start ASP.NET Development Server before any WatiN tests are run and stop it once testing is complete. Most test frameworks have a method for specifying code to run before and after any tests. In NUnit 2.4.8, we use the SetUpFixture attribute on a class to mark it as containing setup/teardown code for all tests in the same namespace, as shown below.

using System.Configuration;
using NUnit.Framework;

namespace ScrewTurn.Wiki.Tests {
    [SetUpFixture]
    public class WebServerRunner {
        private WebServer webServer;

        [SetUp]
        public void StartWebServer() {
            var absolutePathToWebsite = ConfigurationManager.AppSettings["absolutePathToWebsite"];
            webServer = new WebServer(absolutePathToWebsite, 9999);
            webServer.Start();
        }

        [TearDown]
        public void StopWebServer() {
            webServer.Stop();
            webServer = null;
        }
    }
}

 

The WebServer class is a helper class that encapsulates the ASP.NET Development Server. It needs the physical path to the compiled Web site and a fixed port. We need a fixed port, such as 9999, so that we can direct WatiN to browse to http://localhost:9999 in our tests.

ASP.NET Development Server on Windows Vista and Later

The ASP.NET Development Server only listens for requests on IPv4, not IPv6. If you are running Windows Vista or Windows Server 2008, requests for "localhost" will resolve to the IPv6 address of ::1 by default rather than the IPv4 address of 127.0.0.1 and the WatiN tests will fail. To resolve this issue, comment out the IPv6 localhost address in your C:\Windows\System32\drivers\etc\hosts file. This is the line with "::1 localhost".

The Start method for WebServer formats the command line arguments for WebDev.WebServer.exe and launches it using a System.Diagnostics.Process object:

public void Start() {
    webServerProcess = new Process();
    const string webDevServerPath = @"c:\Windows\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.exe"";
    string arguments = string.Format("/port:{0} /path:\"{1}\" /vpath:{2}", port, physicalPath, virtualDirectory);
    webServerProcess.StartInfo = new ProcessStartInfo(webDevServerPath, arguments);
    webServerProcess.Start();
}

At the end of the test run, the Stop method terminates the Cassini process:

public void Stop() {
    if(webServerProcess == null) {
        throw new InvalidOperationException("Start() must be called before Stop()");
    }
    webServerProcess.Kill();
}

 

NOTE: You might receive a strange error message from the ASP.NET Development Server stating that "The directory '<PATH> /vpath:' does not exist", as we see below. This is a bug in the ASP.NET Development Server which causes it to fail if your physical path has a trailing \. To bypass this bug, simply remove the trailing slash in your configuration file or code defensively using physicalPath.TrimEnd(\\) on any physical path intended for the ASP.NET Development Server as I did in the constructor for ScrewTurn.Wiki.Tests.WebServer.

testing_3

Smoke Tests

Our goal in writing acceptance tests is to ensure that end user functionality continues to work as expected, as we add features or refactor existing code for better maintainability. Before getting into complex workflows, we will write some simple smoke tests using WatiN to ensure that ScrewTurn Wiki's basic functionality is working. (A smoke test is a preliminary test designed to show simple and obvious failures, such as an error in the web.config file resulting in the site being inaccessible.) Our smoke tests include the actions of:

· Browsing to the main page

· Logging into the site

· Browsing the admin pages redirects to the login page

· Accessing a nonexistent page redirects to a page not found information page

Note that you don't have to think of everything immediately, but can gradually add tests as you build your test suite.

We'll start out with testing whether a user can log into the site as an administrator. (By default, ScrewTurn Wiki's administrative account is admin/password.) The WatiN script should be fairly self-explanatory. You are finding page elements, such as the Login link, and then performing actions, such as clicking the Login link via its Click method, as shown here.

[Test]
public void CanLogIntoSite() {
    using(var browser = new IE()) {
        browser.GoTo("http://localhost:9999");
        browser.Link(Find.ByTitle("Login")).Click();
        browser.TextField(Find.ByTitle("Type here your Username")).TypeText("admin");
        browser.TextField(Find.ByTitle("Type here your Password")).TypeText("password");
        browser.Button(Find.ByValue("Login")).Click();
        var username = browser.Link(Find.ByTitle("Go to your Profile")).Text;
        Assert.That(username == "admin");
    }
}

The only slightly confusing part might be how to find the page elements. (e.g., How did I know to find the username textbox by looking for its title, "Type here your Username"?) You need your browser of choice and a tool or two, such as Internet Explorer and the Internet Explorer Developer Toolbar or Firefox and Firebug/Web Developer Toolbar.

Finding by selecting an element's title isn't recommended because it is more likely to change. For example, the text really should say "Type your username here." If we correct the grammar, however, we break the test. I wanted to create the smoke tests before modifying the site, which is why I left the text as it is. A better option for identifying page elements is by ID. (You can find elements by ID using Find.ById("id") instead of Find.ByTitle("title"). The Find class contains a wide variety of static methods for simplifying the location of page elements.) So while WatiN can automate any site, you can make your tests more robust in the face of change (and language translations) by providing IDs for elements of interest.


Other videos from this article

· Of Tightropes and Tests

· Using WatiN

· Eliminating Repetition from Tests

· Acceptance Tests

Read the full article at http://msdn.microsoft.com/en-us/magazine/dd744751.aspx

Tags:

Follow the Discussion

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.