Click here to Skip to main content
15,077,137 members
Articles / Web Development / ASP.NET
Posted 8 Jan 2007


111 bookmarked

WatiN - Web Application Testing In .NET

Rate me:
Please Sign up or sign in to vote.
4.68/5 (32 votes)
8 Jan 2007CPOL6 min read
This article exposes how to use WatiN and how to create UI tests for Web applications.

WatiN Test Screenshoot


Nowadays, testing code is not so difficult. We have lots of tools that help us to achieve this goal. But in Web application development, we use to forget to test one of the most important layers, the UI. In this article, I'm going to briefly cover how to do UI and functional testing using WatiN (Web Application Testing In .NET). I'll try to show you what impressed me of this framework from a developer point of view.

What is WatiN?

WatiN stands for Web Application Testing In .NET, and it's a framework that enables web application testing through Internet Explorer. WatiN is inspired on WatiR, a web application testing framework for Ruby. The way that WatiN works is very "easy", knowing that there's a lot of work behind a framework like this. WatiN lets you open Internet Explorer instances, and through interop, interact with the elements in a form. With WatiN, you can get and set values from the elements in a form, and you can fire events of any of the elements in the document too.

Getting started

The API of WatiN is very user-friendly, and watching some code examples and digging a bit, you can get the benefit of this framework quickly. The first thing that we need to build a test method using WatiN is to add a reference to WatiN.Core.dll. WatiN gives us four namespaces; the one that we use to interact with IE instances is WatiN.Core. The different namespaces available are:

  • WatiN.Core.DialogHandlers: The namespace that provides the needed objects to manage the dialogs that the browser can show to the user. Some of the handlers you can find in this namespace are, for example: AlertDialogHandler, ConfirmDialogHandler, FileUploadDialogHandler, PrintDialogHandler, and LogonDialogHandler.
  • WatiN.Core.Exceptions: The namespace that hosts specific exceptions that would help us to control any unwanted behavior. Some examples of these exceptions are: ElementNotFoundException, IENotFoundException, TimeoutException, and a generic WatiNException.
  • WatiN.Core.Interfaces: The namespace that provides us some interfaces to extend the WatiN framework as, for example, the ILogWriter interface that lets us implement our own LogWriter class.
  • WatiN.Core.Logging: The namespace that hosts classes that will help us to log the actions that our code is doing. We can use the DebugLogWriter class to write log messages to the debug window, or we can use the Logger class to save our logs in other ways.

Because the scope of this article is introductory, I will only show you the usage of the most important objects of the framework. In order to learn more about the rest of the namespaces and/or objects, you can check the "References & Resources" section at the bottom of this article.

Now that we have a brief idea of what WatiN is and what we can do with it, let's write some code to see the API's usage.

using WatiN.Core;

static void Main(string[] args)
    // create a new Internet Explorer Instance

    IE ie = new IE();

    // point it to


    // fill the search box


    // performs click event

    ie.Button(Find.ByValue("Google Search")).Click();

The above code example opens an Internet Explorer instance and points it to, then, when the page is loaded, it searches a textbox with name "q" and fills it with the text "WatiN". Then, we do the same we did for the textbox but, this time, looking for a button whose value is "Google Search". In this case, we perform the "Click()" event of the button. If we run this console application, we will see an Internet Explorer opening and doing the things we coded. Isn't that cool?

Solving initial workarounds

Back into the previous piece of code, I have to mention a couple of things. In order to automate tasks with Internet Explorer, we need to run our test under a thread that has a single-threaded apartment (STA) as the apartment state. Notice that over the Main() method, we have the [STAThread] attribute that sets the apartment state to STA. A big question that I made myself when I came across this framework was, "And what about running this tests with NUnit?". NUnit doesn't run tests in a thread using the STA apartment state; it uses multithreaded apartment (MTA), but this isn't a big problem, so we can attach a config file to the NUnit test project and specify the apartment state mode that we want. Let's see how to do it:

<?xml version="1.0" encoding="utf-8" ?>
        <sectionGroup name="NUnit">
            <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
            <!--<span class="code-comment"> Valid values are STA,MTA. Others ignored. --></span>
            <add key="ApartmentState" value="STA" />

If we run the "Getting started" code sample, Internet Explorer will remain open after the actions we coded are performed. This will not affect us if we only want to run one test; we only need to close one Internet Explorer window. But if we want to run more than one test, we can do two things to avoid having to manually close the Internet Explorer windows. First, we can create the instance of the IE object using the using keyword and using the constructor that lets us specify the URL where the new instance will be pointed. If we do that, it gets closed and disposed after the test execution. Second, we can call the Close() method of the IE instance to programmatically close the window. Both are valid, but I prefer the first one because I think that the resulting code is more elegant than if we used the second one.

Creating our first UI test

If our test result is based on the response that the server sends back to the browser, we can parse the response in order to know if our test has failed or not. The way that we do that is exactly the same that we use to make the test, but searching other items in the page that help us to identify what happened. Suppose that we have an aspx page like this:

<%@ Page Language="C#" AutoEventWireup="true" 
         CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" >
<html xmlns="">
<head runat="server">
    <title>WatiN Test Page</title>
    <form id="form1" runat="server">
        <h2>Check if a nickname is already used</h2>
                <td><asp:TextBox runat="server" ID="txtNickName" /></td>
                <td colspan="2" align="right">
                    <asp:Button runat="server" ID="btnCheck" 
                                Text="Check !!" OnClick="btnCheck_Click" />
                <td colspan="2">
                    <asp:Label runat="server" ID="lblResult" />

And now, suppose that we have this code on the btnCheck.OnClick event:

protected void btnCheck_Click(object sender, EventArgs e)
    // do some logic to check if the nickname is already used.

    // i'll return true for all nicknames but "gsus"

    if (txtNickName.Text != "gsus")
        lblResult.Text = "The nickname is already in use";
        lblResult.Text = "The nickname is not used";

For writing these article code samples, I'm using Visual Studio 2005 running under Windows Vista, so I don't have Internet Information Services installed. For web development, I'm using the ASP.NET Development Server that came with .NET Framework 2.0, so in the next code sample, you will see that I start the Web Server programmatically in order to run the test. I think that this is a good way to decouple our UI tests from IIS. Now, let's see how the test looks finally:

using System.Diagnostics;
using WatiN.Core;
using NUnit.Framework;
using System;

namespace WebAppUITesting
    public class UITesting
        //process object 

        private Process p;

        public void SetUp()
            // create a new process to start
            // the ASP.Net Development Server

            p = new Process();

            // set the initial properties 

            string path = 
            p.StartInfo.FileName = "WebDev.WebServer.EXE";
            p.StartInfo.Arguments = 
                   String.Format("/port:8080 /path:\"{0}WebApp\"", path);
            p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;

            // start the process


        public void CheckIfNicknameIsNotUsed()
            // create a new Internet Explorer instance
            // pointing to the ASP.NET Development Server

            using (IE ie = new IE("http://localhost:8080/Default.aspx"))
                // Maximize the IE window in order to view test


                // search for txtNickName and type "gsus" in it


                // fire the click event of the button


                // parse the response in order to fail the test or not 

                Assert.AreEqual(true, ie.ContainsText("The nickname is not used"));

        public void TearDown()
            // kill the ASP.NET Development Server process


As you can see, I use the method ContainsText in line 46. This method searches the specified text in the document content and returns a bool indicating if there are occurrences in the search. We can replace line 46 with the next code example, where we directly get the "lblResult" Span content to see if the nickname is already used:

// parse the response in order to fail the test or not 

bool result = (ie.Span(Find.ById("lblResult")).Text == "The nickname is not used");
Assert.AreEqual(true, result);


At this stage, we should know how to basically use WatiN framework to test web applications. I hope you find this framework and this article useful, as I did. Personally, I haven't used any other web application testing framework, but I got really surprised with how we can test our UI using WatiN. I think that we can do intensive UI and functional testing with it.

References & Resources




This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Jesus Jimenez
Web Developer
Spain Spain
Jesus Jimenez is a software development consultant in Madrid. He has focused in .Net technologies in the last years and he mainly works in ASP.NET environments. He is MCAD.NET since 2002 and is starting to be a bit paranoid about usability and user interfaces.

You can read his blog at:

Comments and Discussions

QuestionWatiN- Failed:System.threading.ThreadStateException Pin
jdjdahsjads28-Dec-16 0:57
Memberjdjdahsjads28-Dec-16 0:57 
QuestionWebAppUITesting Pin
Member 105538015-Feb-14 12:10
MemberMember 105538015-Feb-14 12:10 
AnswerRe: WebAppUITesting Pin
jdjdahsjads29-Dec-16 1:03
Memberjdjdahsjads29-Dec-16 1:03 
Questionie.Button(Find.ByValue("Google Search")).Click(); Pin
Lewis Ardern30-Oct-12 3:21
MemberLewis Ardern30-Oct-12 3:21 
AnswerRe: ie.Button(Find.ByValue("Google Search")).Click(); Pin
jdjdahsjads28-Dec-16 0:58
Memberjdjdahsjads28-Dec-16 0:58 
GeneralWaitUntilExists function does not catch alertdialog when a link is clicked. Pin
rajeevkg23-Jan-11 22:59
Memberrajeevkg23-Jan-11 22:59 
GeneralOpen a new window Pin
Sheikh.Usman.Shakeel16-Sep-10 6:32
MemberSheikh.Usman.Shakeel16-Sep-10 6:32 
Generallogindialog Pin
joe loyzaga22-Jun-10 12:44
Memberjoe loyzaga22-Jun-10 12:44 
QuestionHow to capture screenshot of embedded WebBrowser control? Pin
alexandr_nv19-May-10 3:23
Memberalexandr_nv19-May-10 3:23 
GeneralAccess textfields in popup window Pin
Donnerknall23-Feb-10 22:04
MemberDonnerknall23-Feb-10 22:04 
GeneralRe: Access textfields in popup window Pin
Donnerknall23-Feb-10 22:24
MemberDonnerknall23-Feb-10 22:24 
AnswerRe: Access textfields in popup window Pin
jawed.ace9-Apr-10 2:23
Memberjawed.ace9-Apr-10 2:23 
QuestionRe: Access textfields in popup window Pin
Avanthi Devireddy24-Oct-10 18:56
MemberAvanthi Devireddy24-Oct-10 18:56 
AnswerRe: Access textfields in popup window Pin
jtg129-Oct-10 8:30
Memberjtg129-Oct-10 8:30 
QuestionCan I do a multi select using WatiN Pin
Alpha_Male25-Nov-09 23:53
MemberAlpha_Male25-Nov-09 23:53 
GeneralUse WatiN to fill form fields in a running IE instance Pin
FilipVW8-Aug-09 5:14
MemberFilipVW8-Aug-09 5:14 
AnswerRe: Use WatiN to fill form fields in a running IE instance Pin
jawed.ace10-Aug-09 23:18
Memberjawed.ace10-Aug-09 23:18 
GeneralRe: Use WatiN to fill form fields in a running IE instance Pin
FilipVW11-Aug-09 3:05
MemberFilipVW11-Aug-09 3:05 
GeneralRe: Use WatiN to fill form fields in a running IE instance Pin
jawed.ace11-Aug-09 23:27
Memberjawed.ace11-Aug-09 23:27 
GeneralRe: Use WatiN to fill form fields in a running IE instance Pin
FilipVW15-Aug-09 1:28
MemberFilipVW15-Aug-09 1:28 
GeneralRe: Use WatiN to fill form fields in a running IE instance Pin
jawed.ace15-Aug-09 9:49
Memberjawed.ace15-Aug-09 9:49 
GeneralRe: Use WatiN to fill form fields in a running IE instance Pin
Member 116639328-Jun-10 4:15
MemberMember 116639328-Jun-10 4:15 
GeneralWaitN -&gt; FireFox -- help [modified] Pin
skinflint6-Aug-09 22:59
Memberskinflint6-Aug-09 22:59 
AnswerRe: WaitN -&gt; FireFox -- help Pin
jawed.ace11-Aug-09 0:13
Memberjawed.ace11-Aug-09 0:13 
GeneralWatiN : Popup window and Radio button Pin
smita godbole27-Jul-09 9:19
Membersmita godbole27-Jul-09 9:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.