Automated Testing w/ Selenium!

We here at CodeSmith recently started using Selenium to test our webapps.
If
you haven’t heard of Selenium, or you have been thinking about trying
to create tests for any of your websites or web apps but didn’t know
where to start, go check it out!
(Some links can be found at the bottom of the post.)

While
Selenium is a great tool, and the guys at ThoughtWorks did a great job,
Selenium definitely lacking in the same department as most all of it’s
open source brethren: documentation.
Thus, this is my attempt to try and help out!

Our Automation Goals

Once we got our unit tests working, we wanted a quick and easy way to
automate them; the goal was to be able to open N-Unit, run tests, and
not have to worry about configuration and server connections.
Also, this worked out well for running our unit tests with our build for continuous integration!

Disclaimer:
For large scale or enterprise testing, there are better ways of
accomplishing this (such as leaving the server running on a dedicated
testing box), but we were just looking for a quick and easy way to run
our tests!

Our Automation Implementation

We are just
running the Selenium Server out of the Test Fixture Setup; we launch it
as a process, run our tests, then close it in the Test Fixture Tear
Down.

First, we created a class to pull my settings from the App.Config…

public static class SeleniumAppSettings
{
public static string ServerHost
{
get { return ConfigurationManager.AppSettings["SeleniumServerHost"] ?? "localhost"; }
}

…etc, etc, I only mention this so you know where I’m getting the values later!

Second, we create an abstract class for our Tests to inherit from…

public abstract class SeleniumTestBase
{
private Process _process;
protected ISelenium selenium;

[TestFixtureSetUp]
public void TestFixtureSetUp()
{
string arguments = String.Format("-jar "{0}" -firefoxProfileTemplate "{1}"",
SeleniumAppSettings.ServerJar,
SeleniumAppSettings.FirefoxProfile);
_process = Process.Start("java", arguments);

selenium = new DefaultSelenium(
SeleniumAppSettings.ServerHost,
SeleniumAppSettings.ServerPort,
SeleniumAppSettings.Browser,
SeleniumAppSettings.URL);
selenium.Start();
}
[TestFixtureTearDown]
public void TestFixtureTearDown()
{
if (selenium != null)
{
try
{
// Close Browser
selenium.Stop();
// Close Server
selenium.ShutDownSeleniumServer();
}
catch { }
}

// Confirm server is closed.
try
{
if (!_process.HasExited)
_process.CloseMainWindow();
if (!_process.HasExited)
_process.Kill();
_process.Close();
}
catch { }
}
}

Third, we just created a class for whatever we wanted to test…

[TestFixture]
public class WebsiteTest : SeleniumTestBase
{
[Test]
public void MainPageTest()
{
selenium.Open("/");
selenium.WaitForPageToLoad(SeleniumAppSettings.TimeOut);
Assert.IsTrue(selenium.GetTitle().Equals("My Website"));
Assert.IsTrue(selenium.IsTextPresent("Hello world!"));
}
}

As long as it inherits the base it will take care of managing the server!

Firefox 3.0

A
great feature with Selenium is that you can run your tests against
multiple browers just by customing your start up parameters.
(…yes, my example is hard coded to use Firefox, see my next section for why!)
So, many are disapointed that Selenium does not natively support Firefox 3.0…

However! There is a very simple, and very reliable work around!
Here’s what you need to do…

  1. Open selenium-server.jar (You can do this by using Winrar.)
  2. Recursively traverse the customProfileDirCUSTFFCHROME and customProfileDirCUSTFF directorys…
  3. … and edit all the install.rdf files…
  4. …update the <em:maxVersion> values from 2.0.0.* to 4.0.0.*

…this will allow Selenium to run the latest Firefox!

(My thanks to Mikhail Koryak for blogging about this fix!)

Persisting Custom SSH Certificates

When testing one
of our websites we kept running into a problem: our test domains did
not have legetimate SSH certificates, so we were unable to test our
https pages!

Why/how was this a problem?
When Selenium launches it creates a
clean browser profile, this way no cookies plugins or other thing will
interfear with the tests.
However, this also means that no temporary certificates were being persisted from test to test!

The Solution
Create a custom Firefox profile, and tell Selenium to use that when it launches.

Close
your Firefox browser and Run "firefox.exe -profileManager". This will
allow you to create another Firefox profile (I named mine "Selenium").
Then launch that profile, go to the website you want to test, and store a perminant SSH certificate for it.

Above
you may have noticed that I used the "-firefoxProfileTemplate" argument
when launching the Selenium server, this tells the server to load the
specified profile rather than creating a new one.

Note: The changes made to your profile while Selenium is running will not be saved!
This
is good because no cookies or other such things will be left behind to
intefear with future tests. However, it has the slight draw back (for
us at least) of cause Selenium to reinstall its Firefox plugins every
time it runs.
…meh!

(Thanks to Chris Pitts for blogging about something very similar to this!)

Helpfull Links

Selenium Homepage
Selenium IDE Homepage
Selenium Video Example/Tutorial
Selenium on Wikipedia