Selenium rocks. My most recent task has been to create an end-to-end system
test for our QA environment. There are a lot of moving parts in QA.
A lot of things can and do go wrong. The end-to-end test will play the role
of a canary in a coal mine. I'm certain that it will go belly-up frequently,
but at least we will now have something that detects that something has died and
it will also give us some indication of what has died.
My goal was to create this test with a minumum of cheating. A test can accomplish
anything at all by poking the database, but a good test only interacts
with the target system via the interface mechanisms provided by the target system.
When a tested behavior can only be stimulated via web applications, this has always
posed a difficult obstacle for me. Of course, I can create WebRequest objects
to accomplish such tasks, but doing so creates an awful lot of brittle test code.
And then, there is the issue of javascript. Have you ever tried to interpret
javascript so that you can perform exactly the behavior a user
would cause interacting with the application? Not fun.
Enter the perfect solution: Selenium.
Now, it's simple to mix browser actions in with the body of a standard NUnit test.
A Selenium script takes care of the text-entry, button-poking, mouse-jumping actions
that normally require a user's touch. It's child's play to create such scripts
with the Selenium IDE extension to firefox (why would anyone use any other browser?).
Then launching the script inside an automated test just requires a Process.Start
on IExplore.exe with
the right URL. Selenium lays out the actions and the
browser does the heavy lifting of parsing the html and javascript. [Note: I haven't
been able to convince IExplore.exe to exit from javascript window.close(), but my
test can get away with a tap of the Process.Kill hammer, heh, heh. 2nd note:
My mouse only touches firefox, but it is useful to run IExplore.exe inside the test
so that my sessions aren't affected by the running test.]
The one missing ingredient was the ability to pass arguments in to the Selenium test scripts.
I had to learn enough server-side javascript to pull it off, but essentially, I changed the Selenium test suite files and individual test files to asp instead of html. This gave me the ability to use <%= Request.QueryString("argname") %>
. I didn't need to change any of the Selenium core code at all!
So, now my end-to-end test runs every night. The test creates a flurry of
file drops, web service calls, and Selenium-controlled web application interactions
to verify that the stuff that was working yesterday will still be working tomorrow.
Selenium's mascot ought to be Mighty Mouse, -- "Here I am to save the day!"