Introduction
In the project that I'm currently working I need to do an intensive UI and Functional testing to ensure that the application UI is working fine. Due to that I've been looking for a good way to do, both, UI and functional tests. Past week I came across a framework called WatiN and I decided to research about it. This post exposes what I found and I'll try to show you what impressed me of this framework from a developer point of view.
What's WatiN?
WatiN stands for Web Application Testing In .Net and enables web applications testing trhought 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 let's you to open Internet Explorer instances and throught interop interact with the elements in the form. With WatiN you can get and set values from the elements in the form and you can fire events of any of the elements in the document too.
Getting started
The API of WatiN is very nice, at least for me, and watching some code examples and digging a bit you can get benefit of this framework quickly. The first thing that we need to build a test method using WatiN is to add a reference to the WatiN.Core.dll. WatiN gives us four namespaces, furthermore of the one that we use to interact with the IE instances, WatiN.Core. These namespaces are:
- WatiN.Core.DialogHandlers: Provides the needed objects to manage 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 or LogonDialogHandler.
- WatiN.Core.Exceptions: Provides some specialized exceptions to allow us to control unwanted behaviors. This namespace exceptions examples are: ElementNotFoundException, IENotFoundException, TimeoutException or a generic WatiN exception, WatiNException.
- WatiN.Core.Interfaces: Provides us some interfaces to extend the WatiN framework, as for example the ILogWriter interface that gives us the availability of implement our own LogWriter class.
- WatiN.Core.Logging: This namespace exposes some class that will help us in order to log the actions that our test 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 that the scope of this post is only introductory I'll 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 post.
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 how is the API's usage.
1 using WatiN.Core;
2
3 [STAThread]
4 static void Main(string[] args)
5 {
6 // create a new Internet Explorer Instance
7 IE ie = new IE();
8
9 // point it to http://www.google.com
10 ie.GoTo("http://www.google.com");
11
12 // fill the search box
13 ie.TextField(Find.ByName("q")).TypeText("WatiN");
14
15 // performs click event
16 ie.Button(Find.ByValue("Google Search")).Click();
17 }
The previous code example opens an Internet Explorer instance and points it to
www.google.com, then, when the page is loaded, it searchs a textbox with name "q" and fills it value with the text "WatiN". Then I do the same I did for the textbox but, this time, looking for a button wich value is "Google Search" and then I perform the "Click()" event. If we run this console application we will see an Internet Explorer opening and doing the things we code. Isn't cool?
Solving initial workaroundsNow just some comments about the above piece of code. 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 apartment state. Notice that over the Main method we have an attribute that makes the thread use 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 the tests in a thread using STA apartment state, it uses multithreaded apartment (MTA), but this isn't a big problem so we can attach a config file to NUnit test project and specify the apartment state mode that we want. Let's see how to do it:
1 <?xml version="1.0" encoding="utf-8" ?>
2 <configuration>
3 <configSections>
4 <sectionGroup name="NUnit">
5 <section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
6 </sectionGroup>
7 </configSections>
8 <NUnit>
9 <TestRunner>
10 <!-- Valid values are STA,MTA. Others ignored. -->
11 <add key="ApartmentState" value="STA" />
12 </TestRunner>
13 </NUnit>
14 </configuration>
One thing that will occur after executing the above code is that the Internet Explorer window stills open. If you run more than one test, supposing you use NUnit, you can do two things. First, you can create the instance of the IE object using the "using" keyword and using the constructor that lets us specify the url. If you do that it gets closed and disposed after test execution. Second, you can call the Close() method of the IE instace to programmatically close the window. Both are valid, but I prefer the first one becuase I think that the resulting code is more elegant that if we use the second one.
Creating our first UI testIf 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 happend. Suppose that we have an aspx page like this:
1 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml">
4 <head runat="server">
5 <title>WatiN Test Page</title>
6 </head>
7 <body>
8 <form id="form1" runat="server">
9 <h2>Check if a nickname is already used</h2>
10 <table>
11 <tr>
12 <td>Nickname:</td>
13 <td><asp:TextBox runat="server" ID="txtNickName" /></td>
14 </tr>
15 <tr>
16 <td colspan="2" align="right">
17 <asp:Button runat="server" ID="btnCheck" Text="Check !!" OnClick="btnCheck_Click" />
18 </td>
19 </tr>
20 <tr>
21 <td colspan="2">
22 <asp:Label runat="server" ID="lblResult" />
23 </td>
24 </tr>
25 </table>
26 </form>
27 </body>
28 </html>
And now suppose that we have this code on the btnCheck.OnClick event:
1 protected void btnCheck_Click(object sender, EventArgs e)
2 {
3 // do some logic to check if the nickname is already used.
4 // i'll return true for all nicknames but "gsus"
5 if (txtNickName.Text != "gsus")
6 lblResult.Text = "The nickname is already in use";
7 else
8 lblResult.Text = "The nickname is not used";
9 }
I'm writing this post examples in Visual Studio 2005 and 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 programmatically the Web Server in order to run the test. I'm not a "tests" guru, so I don't really know if my test is the best test of the world, the only thing I'm trying to transmit you is the concept of how it will be done, of course if I'm wrong, your comments are welcome. Now let's see how my test looks finally:
1 using System.Diagnostics;
2 using WatiN.Core;
3 using NUnit.Framework;
4 using System;
5
6 namespace WebAppUITesting
7 {
8 [TestFixture]
9 public class UITesting
10 {
11 //process object
12 private Process p;
13
14 [TestFixtureSetUpAttribute]
15 public void SetUp()
16 {
17 // create a new process to start the ASP.Net Development Server
18 p = new Process();
19
20 // set the initial properties
21 string path = Environment.CurrentDirectory.Replace(@"WebAppUITesting\bin", string.Empty);
22 p.StartInfo.FileName = "WebDev.WebServer.EXE";
23 p.StartInfo.Arguments = String.Format("/port:8080 /path:\"{0}WebApp\"", path);
24 p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
25
26 // start the process
27 p.Start();
28 }
29
30 [Test]
31 public void CheckIfNicknameIsNotUsed()
32 {
33 // create a new Internet Explorer instance pointing to the ASP.NET Development Server
34 using (IE ie = new IE("http://localhost:8080/Default.aspx"))
35 {
36 // Maximize the IE window in order to view test
37 ie.ShowWindow(NativeMethods.WindowShowStyle.Maximize);
38
39 // search for txtNickName and type "gsus" in it
40 ie.TextField(Find.ById("txtNickName")).TypeText("gsus");
41
42 // fire the click event of the button
43 ie.Button(Find.ById("btnCheck")).Click();
44
45 // parse the response in order to fail the test or not
46 Assert.AreEqual(true, ie.ContainsText("The nickname is not used"));
47 }
48 }
49
50 [TestFixtureTearDownAttribute]
51 public void TearDown()
52 {
53 // kill the ASP.NET Development Server process
54 p.Kill();
55 }
56 }
57 }
As you can see I use the method ContainsText in line 46. This method searchs the specified text in the document content and returns a bool indicating if there are occurrences in the search. We can replace the line 46 with the next code example, where I directly get the "lblResult" span content to see if the nickname is already used:
1 // parse the response in order to fail the test or not
2 bool result = (ie.Span(Find.ById("lblResult")).Text == "The nickname is not used");
3 Assert.AreEqual(true, result);
ConclusionAt this point, you should know how to basically use WatiN framework to test your web applications. I hope you find this framework and this post useful as I did. Personally I haven't used any other web application testing framework but I get really surprised with how we can test our UI using WatiN. I think that we can do an intesive UI and functional testing with it.
References & Resources
References:
Resources:
posted on Sunday, January 07, 2007 5:36 AM
Feedback
1/22/2007 5:10 AM |
If you want to develop web automation with C# or VB.NET you can also try www.InCisif.net.
# re: WatiN: Web Application Testing in .Net
1/22/2007 8:37 AM |
Thanks for the comment Frederic, I didn't know about InCisif, I'll give it a try.
Jesus
# re: WatiN: Web Application Testing in .Net
3/16/2007 7:43 PM |
You can also check SWExplorerAutomation SWEA from
http://webiussoft.com. SWEA records, replays test scripts and generates c# or VB.NET script code.
# re: WatiN: Web Application Testing in .Net
3/18/2007 12:11 AM |
Thanks Alex, I'll check it too. :)
# re: WatiN: Web Application Testing in .Net
11/18/2007 10:46 PM |
thxx
# re: WatiN: Web Application Testing in .Net
12/8/2007 6:57 PM |
We offer the largest collection of polyphonic ringtones, monophonic ringtones, mobile videos, color wallpapers, color screensavers, real sounds.
# re: WatiN: Web Application Testing in .Net
12/19/2007 10:27 PM |
If you are looking for the replica watch and information about it, you came to the right place.
# re: WatiN: Web Application Testing in .Net
2/13/2008 10:05 PM |
tskler
# re: WatiN: Web Application Testing in .Net
7/16/2008 6:46 PM |
harikada nasil olmus bu olay aciklarmisiniz.
# re: WatiN: Web Application Testing in .Net
7/25/2008 8:22 PM |
very very nice
# re: WatiN: Web Application Testing in .Net
7/25/2008 9:18 PM |
very very nice
# re: WatiN: Web Application Testing in .Net
9/14/2008 12:23 PM |
Thanks so much.
# re: WatiN: Web Application Testing in .Net
10/26/2008 11:32 AM |
Thanks so much.
# re: WatiN: Web Application Testing in .Net
12/1/2008 8:15 AM |
Thanks for this much texts
# re: WatiN: Web Application Testing in .Net
2/4/2009 2:51 AM |
thanks
# re: WatiN: Web Application Testing in .Net
2/4/2009 2:52 AM |
thanks
# re: WatiN: Web Application Testing in .Net
2/4/2009 2:52 AM |
thanks
# re: WatiN: Web Application Testing in .Net
2/4/2009 2:53 AM |
thanks
# re: WatiN: Web Application Testing in .Net
2/4/2009 2:53 AM |
thanks you
# re: WatiN: Web Application Testing in .Net
2/4/2009 2:54 AM |
thanks
# re: WatiN: Web Application Testing in .Net
2/4/2009 2:55 AM |
thanks
# re: WatiN: Web Application Testing in .Net
2/15/2009 11:44 AM |
thanks forthe txt
# re: WatiN: Web Application Testing in .Net
3/17/2009 9:31 PM |
thanks
# re: WatiN: Web Application Testing in .Net
3/25/2009 6:01 PM |
thanks
# re: WatiN: Web Application Testing in .Net
6/5/2009 8:59 AM |
thank you
# re: WatiN: Web Application Testing in .Net
6/5/2009 8:59 AM |
Thank you admin
# re: WatiN: Web Application Testing in .Net
6/5/2009 8:59 AM |
thank you post
# re: WatiN: Web Application Testing in .Net
6/5/2009 9:00 AM |
thank you
# re: WatiN: Web Application Testing in .Net
6/5/2009 9:00 AM |
thank you
# re: WatiN: Web Application Testing in .Net
11/6/2009 8:55 AM |
hii
# re: WatiN: Web Application Testing in .Net
11/9/2009 3:12 PM |
Thanks for article. Everytime like to read you.
11/14/2009 1:41 PM |
Thanks Admin wery good :)