Friday, October 16, 2009

Running Selenium tests in Visual Studio

Troublesome testing

I found the amount of time I spent manually testing forms as part of my development process painful and thought there must be a better way of doing this task. The forms are tightly coupled to the database so any refactoring becomes a risky process due to the lack of unit tests. One answer I found that helped me is the http://seleniumhq.org/ web testing framework from ThoughtWorks.

You can download the example code for this post here: http://keithbloom.s3.amazonaws.com/Selenium.Example.zip The only requirement is that you have Java or greater on your PC.

The framework is built around a language called Selenese which executes actions in a web browser. There is a client library available for .Net, so the tests can be run in NUnit or any similar tool. For the NUnit integration to work you have to be running the Selenium RC web server to host the test and a web server for the ASP.Net page being tested.

This could be a lot of work upfront just to run some tests. So I have written some helpers to configure the environment automatically.

Web server

The development web server which ships with Visual Studio (once called Cassini) is a perfect tool for hosting the ASP.Net page under test. An instance is started for the test suite with a hard coded port of 8085 and the URL is set to localhost. As all the projects live at the same level in my project tree I am able to hard code the path as well.

Selenium RC

The process that hosts the tests is a Java based application called Selenium RC. When a test is run in NUnit, the Selenium client library sends Selenese commands to this process over HTTP. When the test suite first runs, I start a Java process and point it to the Selenium RC jar file, this will only get closed when all the tests are finished.

Selenium Runner

The helpers are combined by an abstract class which starts the Web Server and Selenium RC process so any test class that derives from this will automatically have the testing environment configured. The only data required by implementors is the name of the project under test:

Speedy

I have been using this for a week now. At first just as a means to run through the forms quickly. However, I have found other uses for it. I have started adding asserts for common scenarios. One Selenium command that is proving useful to me is selenium.GetHtmlSource() which returns a string of the full source code. This is enabling me to run a test and see the source appear in the Output window and then to check for the presence of certain items. I have used this method the check that certain Omniture tags are being generated:

I am happy with the addition of UI testing to my development process. Here it helps to deal with legacy code which requires some work. It is now possible for me to start refactoring which is something that can only be done with this kind of test coverage.