Automated Web Application Testing using Selenium and NUnit

September 30, 2008

A recent post on stackoverflow raised the question which tools to use for automated tests of web applications.

This question has been an interesting issue for me, as the largest web application I develop and maintain has over the years grown to some 300 aspx files.

Required software to implement tests using Selenium and NUnit:

Selenium Remote Control consists of an HTTP server component requiring Java (1.5 or higher) and a .Net client library. Method calls to the library issue commands to the Selenium server, which in turn sends these commands to the browser.

First, install Selenium IDE plugin for Firefox. You can use the IDE to record your actions in the browser, and replay these recorded actions. It also generates scripts of the recorded actions (called Test Cases) in HTML, C#, and other programming languages.

After installing Selenium Remote Control, the Selenium HTTP server can be started using the command line

c:\path\to\java.exe -jar c:\path\to\selenium-server.jar

Selenium server listens on port 4444 by default.

Install NUnit and create a Visual Studio project which references the nunit.framework.dll and Thoughtworks.Selenium.Core.dll libraries. Your project is now ready to compile the test cases generated by Selenium IDE.

(I recommend changing the browser string in the DefaultSelenium constructor to “*iexplore” for first experiments)

Run the NUnit GUI application and open the newly created assembly. The left-hand tree shows assemblies, namespaces, and test case names.

After starting the Selenium server, select a node and press Run. This will open a browser window which executes the commands defined in the test case. After completion, the browser will be closed again. (If you don’t see a browser window, use task manager to watch the list of processes)


Firefox 3 CPU Usage

September 22, 2008

After upgrading from Firefox 2 to Firefox 3, I noticed some strange behavior in terms of memory usage and, mainly, CPU usage.

My browsing habits cause open windows and tabs within windows to multiply in no time, so I expected some improvement by upgrading. Though memory consumption was slightly better, and hovering over the History menu item no longer freezes up the browser for several minutes, CPU hogging was worse than before the upgrade.

I found that two tips helped me reduce both CPU and memory consumption:

  • in the URL field, type about:config
  • locate the Urlclassifier.updatecachemax setting and set it to 104857600.
  • locate the browser.cache.memory.enable setting and click to set it to false.

My Firefox ran smoother after restarting the browser.


One Year devioblog – a Summary

September 21, 2008

I started this blog one year ago to write about topics that I deal with in my software projects, mostly about MS SQL Server and Asp.Net programming.

Since September 2007, this activity generated 71 posts (I did not realize I was publishing an article about every 5 days!) and 20.000 views (says my stats page).

In this time, I also released 3 freeware programs to the public: SchemaFind, graspx, and SMOscript (downloads here).

From the list of Top Posts, my personal favorites are those about automatically building Visual Studio solutions and automated project releases here, here, here, and here.

Sometimes I also documented software installation procedures if I thought I had run into unusual problems: TRAC, Bugzilla, or GForge.

And occasionally I was simply enjoying working with Visual Studio (2005), SQL Server (2005), and C#. :)

To be continued…


Creating a Mosaic Webpage with Javascript

September 9, 2008

If you are hosting a couple of websites, you want to make sure that adding or editing website configurations (e.g. Apache config files) does not interfere with other websites.

To display an overview of hosted sites, I decided to write a Javascript procedure which creates a table containing iframes to those websites:

<html>
    <head>
        <title>mosaic</title>
        <link rel="stylesheet" href="stylesheet.css" type="text/css">
    </head>
    <body>
        <table id="Table1" cellSpacing="1" cellPadding="1" width="100%" border="0">
        <script type="text/javascript">
var sites = [];
sites["site1"] = "http://my.first.site/";
sites["site2"] = "http://my.second.site/";
// more sites

var iMaxCol = 2;
var iCol = 0;

for(site in sites)
{
    if (iCol == 0) {
        document.writeln("<tr>");
    }

    document.writeln("<td align=\"center\">");
    document.writeln("<a href=\"" + sites[site] +
        "\" target=\"_blank\">" + site + "</a><br/>");
    document.writeln("<iframe src=\"" + sites[site] +
        "\" width=\"100%\" height=\"100px\"");
    document.writeln("</iframe>");
    document.writeln("</td>");

    iCol++;
    if (iCol == iMaxCol) {
        document.writeln("</tr>");
        iCol = 0;
    }
}

if (iCol == iMaxCol) {
    document.writeln("</tr>");
}
        </script>
        </table>
    </body>
</html>

Introducing SMOscript

September 5, 2008

SQL Server 2000 provides a tool called scptxfr which generates DROP and CREATE scripts for all objects in a database. Unfortunately it is not included in SQL Server 2005.

In the batch files I described in my posts about automating the build process, I also call it to generate a script for all database objects which is then used in version control.

Since it is not included in the latest SQL Server versions, I developed a replacement for scptxfr which uses the .Net SMO libraries for script generation called SMOscript:

smoscript 0.10.3169.17676 (c) by devio.at 2008

    list and script databases and database objects.

    usage: smoscript [options] [command]

    options: (leading '-' or '/')

    -s server       server name
    -d database     database name
    -u username     username (default: integrated authentication)
    -p password     password (if -u is missing, password for sa)

    -r              generate DROP statements
    -i              include IF NOT EXISTS statements

    -f filename     output to file
    -F directory    output to directory

    -A              current ANSI codepage
    -O              ASCII
    -T              Unicode
    -U              UTF8

    commands:

    l               list
    s               script object/s

    list databases on server (implied by -s)
    list objects in database (implied by -s -d)
    script object (implied by -s -d -o)
    script all objects (implied by -s -d -F/-f)

The SMOscript utility implements the following functions:

  • list all databases on a server
  • list all objects in a database
  • script CREATE or DROP statements for each object in database

Resulting script are either written to a single file, or to a separate file for each object.

Command line switches were selected to be compatible with scptxfr, but support both “-” and “/” as switch marker.

SMOscript is available for download here.


Accessing AssemblyInfo in C#

September 3, 2008

To retrieve a program’s Assembly information, you need to access the System.Reflection.Assembly class.

First, retrieve the object for the currently executing assembly:

System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();

Next, retrieve the desired attributes by calling GetCustomAttributes() with the respective attribute type:

object[] rgobjP = asm.GetCustomAttributes(
    typeof(System.Reflection.AssemblyProductAttribute), false);
object[] rgobjV = asm.GetCustomAttributes(
    typeof(System.Reflection.AssemblyFileVersionAttribute), false);

If the attribute exists in the assembly, the object[] array has a length greater zero.

However, the AssemblyVersion (of type AssemblyVersionAttribute) is not accessible in this way, as iterating through the array

object[] rgobj = asm.GetCustomAttributes(false);

shows. Rather, you have to access the assembly’s asm.GetName().Version object.

See also this entry on codeproject with available source code.