Home
Courses/Training
Articles
Clients
Approach
Technology
Associates
Contact Us
Links

Writing Automated Browser Tests With NUnit and IE

This article is written by Dave Chaplin, an IT Consultant with 10 years experience. He leads and mentors teams of developers on agile .NET projects and has extensive experience in agile development techniques, particularly Test-Driven Development. Dave can be emailed at davechaplin@byte-vision.com.

Date: Thursday, October 24, 2002

Author: Dave Chaplin
Dated: 24th October 2002

Abstract

The benefits of automated testing are well known. In Extreme Programming (XP) automated unit tests are central to the whole process. However, we would still like to conduct ‘above the bonnet’ automated testing for browser based sites. This article explains how you can automate browser based testing and link the tests into NUnit.

Background Reading

This article assumes you are familiar with the NUnit framework and already know how to write automated tests. For my article that shows you how to do this see Developing Automated Test With NUnit and VB.NET

Automating IE With The IE Driver

Referencing The IE Libraries

Before we attempt to write the NUnit tests we need to write a tool, which I’ll call the IEDriver, that will enable us to create an instance of Internet Explorer, set values, read value, and click links and buttons. To do this we need the following COM libraries:

  • shdocvw.dll (Microsoft Internet Controls)
  • mshtml.tlb (Microsoft HTML Object Library)

To get these into .NET I find the easiest way is to put a form into the IEDriver and then customise the toolbox by right clicking on the tool bar. Like this:

From the dialog that pops up choose the Microsoft Web Browser control:

Now, from the toolbox drag and drop the Web Browser control onto a form. It will create all the references you require in the references section of your project:

Creating The IEDriver Class And Hooking Into IE:

Create a class called IEDriver that will wrap the Internet Explorer functionality. Create a private read only property to manage the creation and connection to IE:

Imports SHDocVw

Public Class IEDriver

#Region "IE hookup"
    Private WithEvents mIE As InternetExplorer
    Private loaded As Boolean = False

    Private ReadOnly Property IE() As InternetExplorer
        Get
            Dim wins As New ShellWindows()

            If wins.Count > 0 Then
                mIE = CType(wins.Item(0), InternetExplorer)
            Else
                mIE = New InternetExplorer()
            End If

            If Not mIE.Visible Then
                mIE.Visible = True
            End If

            Return mIE

        End Get
    End Property

Making It Synchronous

In order for your tests to work, control cannot be sent back to the test suite whilst the browser is still in the middle of processing. Thus, we need to make it synchronous. To do this we use two functions shown below:

Private Sub ieDocumentComplete(ByVal pDisp As Object,

ByRef URL As Object) Handles mIE.DocumentComplete

loaded = True

End Sub

Private Sub WaitUntilDocComplete()
      loaded = False
      Do While Not loaded
      Loop
      loaded = False
End Sub

 

The WaitUntilDocComplete() function is called after an asynchronous event is fired. For example, the IEDriver.ClickButton(elementID) method:

Public Sub ClickButton(ByVal buttonID As String, _

ByVal WaitForCompleteEvent As Boolean)

'Preconditions

If buttonID = "" Then
          
Throw New ArgumentException("empty buttonID")
      End If

      Method Body
      Dim button As mshtml.HTMLInputElement

button = CType(Document.getElementById(buttonID), _

mshtml.HTMLInputElement)

      button.click()

      If WaitForCompleteEvent Then
          WaitUntilDocComplete()
      End If

End Sub

 

The parameter WaitForCompleteEvent() is there because sometimes the button will have client side javascript validation and you do not wish to wait for the page to be loaded.

Getting And Setting Values

Here’s how to set a value:

Public Sub SetValue(ByVal elementID As String, _
                    ByVal value As String)

      'Preconditions

      If Not ElementExists(elementID) Then
             Throw New ArgumentException("Element ID " & elementID & ~
                                                "
does not exist.")
      End If

      'Method Body
      Dim txt As mshtml.HTMLInputElement

      txt = CType(Document.getElementById(elementID.ToString),

mshtml.HTMLInputElement)

      txt.value = value

End Sub

Getting values works using very much the same principles.

Writing NUnit Tests

Here’s a text fixture written in NUnit that makes use of the IEDriver:

Imports NUnit.Framework
Imports NUnitIEDriver
Imports System.Configuration

<TestFixture()> _
Public Class LogonTests

    Private mIEDriver As IEDriver
    Private URL As String = “http://MyLogonPageURL”

    <SetUp()> _
    Public Sub SetUp()
        mIEDriver = New IEDriver()
    End Sub

    <TearDown()> _
    Public Sub TearDown()

    End Sub

    <Test()> _
    Public Sub WrongLogonID()
        mIEDriver.Navigate(URL)
        mIEDriver.SetValue("txtUserName", "BadUser")
        mIEDriver.SetValue("txtPassword", "password")
        mIEDriver.ClickButton("Checkpassword", True)

        Dim ErrorLabel As String
        ErrorLabel = mIEDriver.GetValue("Errors")
        Assertion.Assert(ErrorLabel = "Login Failed")
    End Sub

    <Test()> _
    Public Sub SuccessfulLogon()
        mIEDriver.Navigate(URL)
         mIEDriver.SetValue("txtUserName", "CorrectUser")
        mIEDriver.SetValue("txtPassword", "CorrectPassword")
        mIEDriver.ClickButton("Checkpassword", True)

        Dim WelcomeLabel As String
        WelcomeLabel = mIEDriver.GetValue("lblWelcome")
        Dim welcome As String = "Welcome to SystemXYZ, "        
        Assertion.Assert(WelcomeLabel = welcome)
    End Sub

Summary

This is a very basic, but inexpensive (free) way to automate browser based testing. Note though, that the tests take quite a while to run compared to unit tests. Because of the length of time taken to run the tests I would advise keeping your pages as thin as possible and fully test below the bonnet first. These browser based tests can form your functional regression test suite and could be part of your daily build and smoke tests. Also, note that the tests are only for Internet Explorer.

Feel free to email me should you have any questions. Any enjoy!

Dave Chaplin

Other Articles

Test Driven Development (Dec 2003)
The Losers Olympics (Sep 2003)
Making Projects Succeed: Part 1 - Measurable Business Goals (Sep 2003)
Pitfalls In Software Development (June 2003)
Extreme Web Architectures - Testing Web Applications In Seconds (June 2003)
Pair Programming and Quad Programming - From Experience (June 2003)
Making Extreme Programming A Success (April 2003)
Contractual Test Driven Development (TDD with DBC) (April 2003)
Moving To XP (Feb 2003)
Maximising Development Productivity (Dec 2002)
Writing Automated Browser Tests Using NUnit and IE (Oct 2002)
Mitigating Requirements Risk With Agile Practices (Oct 2002)
10 Tips for Successful Team Leading (Oct 2002)
Developing Automated Using Tests Using NUnit 2.0 With VB.NET (Sep 2002)
Quality By Design - Part 1.doc (May 2001)
Quality By Design - Part 2.doc (May 2001)
Quality By Design - Part 3.doc (May 2001)

Other Resources

NUnit
http://www.nunit.org/
http://sourceforge.net/projects/nunit/

Extreme Programming
http://www.extremeprogramming.org/rules/testfirst.html
http://www.extremeprogramming.org/index.html

Refactoring
http://www.refactoring.com

Agile Modelling
http://www.agilemodeling.com/

All content © Byte-Vision Limited 1997 - 2004