Yarjuf – Yet Another RSpec JUnit Formatter (for Jenkins)

So, I’ve previously put together an JUnit formatter for RSpec so I can use RSpec with Jenkins/Hudson, but it was a bit of a hack. People seem to use and like it so I’ve redeveloped it and packaged it as a gem. I’ve also fixed a few problems with it, particularly how it groups tests together. It’s called… “Yet Another RSpec JUnit Formatter“, AKA: yarjuf. Inspired, I know.

Read about it here: https://github.com/natritmeyer/yarjuf

To install: gem install yarjuf

Firefox plugin: Test Automation Password Manager

I’ve recently come across a problem when doing UI testing with Firefox on a Mac against a web app that uses NTLM authentication. Every time I navigated to the web app I was presented with a dialog box asking me for my username and password.

I did some reading and came across Alister Scott’s Automatic Firefox authentication when using Selenium-WebDriver with AutoAuth post. In it he explains a way to get around the problem:

- Create a Firefox profile using the profile manager
- Add the required credentials to the profile
- Use the above Firefox profile when running tests
- Add the AutoAuth plugin to the profile at test execution time

The above would get around my problem, but it would lead to having to maintain a firefox profile which isn’t nice. So, I decided to attempt writing a firefox plugin that would allow me to add credentials to firefox’s password manager at runtime using Javascript. After all, according to the documentation it looked possible…

After a bit of hacking, the result is my first Firefox plugin: the Test Automation Password Manager plugin. It’s quite simple to use; you can find instructions here:

https://github.com/natritmeyer/test_automation_firefox_password_manager

…and the plugin page here:

https://addons.mozilla.org/en-US/firefox/addon/test-automation-password-ma/

I’ve not tested it extensively – “It Works On My Machine:)

Managing your page objects

The page object model works very well, but there are a few traps you can fall into. Alister Scott goes through a few of them and mentions one that particularly grates me: “Pages stored as instance variables”. Here’s a demonstration of the problem:

So why is that a problem? Well, there’s lots of noise – 3 lines are there just to create variables. This significantly reduces readability as you’ll end up with many, many lines of test code just creating instances of page objects. You also now have a whole load of instance variables to keep track of: @login_page, @account_page, @account_history_page. And when you’re using cucumber to run your tests, this will lead to *big* maintenance issues. I’ve had to rescue a few cucumber-based test projects and one of the most frequent causes for test-rot is that the testers lost track of their instance variables. Been in this situation before?

“Can I use @account_page here? Did I previously declare it? Hmmm… No, it’s nil when I try to use it. OK, I’ll instantiate it here. [runs the tests]. Cool, that works. Oh no! Doing that has broken some other tests that referenced @account_page but expected something else!?!? Should I fix up the other tests? Rename the @account_page variable to something else? If I do that will I break anything else?” Not fun. Big spaghetti problems.

But what to do about it? Alister suggests using blocks (provided by the page-object gem) that look something like the following:

On first glance, this looks great. No instance variables to keep track of. Just deal with the classes themselves and use only local variables inside the blocks. Nothing to keep track of. Great!

But…

The above proposal causes other maintenance hassles – the page object’s class name is now scattered throughout the code. Lots of “visit LoginPage” all over the place. What happens when the class name changes? You’ll have to make changes throughout the code. Not fun.

Solution: use an instance of an App class, this App class being a representation of the app you’re testing (the whole app, not individual pages). This App class contains one method per page class, each of these methods return an instance of the relevant page class.

“Whhhaaattt?”

OK, here’s an example:

In your tests, you would then have the following line:

When I visit the login page

…which would match the following step…

If you structure your tests such that they always begin by mentioning where the user starts (a good idea as it gives context), you can rely on the fact that @app has been instantiated so you can just use it. For example:

So how is this an improvement? Well, there’s no need to manage instance variables for different pages – just call methods on a known instantiation of the App class(@app) and they’ll return instances of the pages you want. There’s no need to mention class names; they are hidden behind methods. If the class name changes you only need to make one change (change the class referenced in the methods in the App class).

Subjective statement: I’d also argue that you also get great readability with this way of structuring things.

This is how I’ve normally organised things. And it’s worked great both on small projects of only 10′s of tests to large projects where the number of tests is 1000+. It’s the best solution I’ve come up with, it doesn’t suffer from having instance variables all over the place, neither are there class names all over the place.

I’ve written up in brief how this works if you’re using SitePrism to manage your page objects: http://rdoc.info/gems/site_prism/file/README.md#Epilogue

RSpec JUnit Formatter for Jenkins

While RSpec is great, it is missing a built in JUnit formatter so you don’t get the pretty analysis stuff from Jenkins that you otherwise would. There have been a few attempts at writing an RSpec JUnit formatter, but I’ve never seen something work consistently across versions of RSpec. In my experience, the ci_reporter gem works well, but only with some versions of RSpec. Since it doesn’t work with the current version (2.10), I decided to write my own simple JUnit formatter that will allow me to run my tests in Jenkins. To use it, save the code that follows to a file called junit.rb and then call rspec with the following options:

rspec my_spec.rb -r ./junit.rb -f JUnit -o results.xml

That will cause RSpec to require the file containing the formatter, invoke the formatter and save the JUnit-formatted results to a file called results.xml. A better option would be to require the junit.rb file from your spec_helper.rb file (which in turn is being required by your .rspec file, right?). If you do that then you’ll only need to call the following:

rspec my_spec.rb -f JUnit -o results.xml

Anyway, here’s the code. Hope it helps!

How to bring a browser to the front (on a mac)

One of the sad realities of browser testing is that for some functions to work the browser just has to be on top. If it’s not on top, tests will fail. There has to be a way to bring browsers to the front…

Well, if you’re running your tests on a Mac, you can easily bring any application to the front using AppleScript. If you’ve never heard of AppleScript, there’s a reason: it’s awful and no one uses it. But in this instance it does the job.

The following code shows you (in ruby) how to bring Chrome to the front and then resize the window:

Here’s the same thing for Firefox:

It took me a while to hunt around for a solution and then a little while more to figure out the AppleScript required to do the job. Hope it helps!

SitePrism: Capybara Page Objects

Capybara is a great browser interaction library for automated testing, but until now it hasn’t been much fun to follow the Page Object pattern with it. So, I wrote SitePrism that lets you do just that: SitePrism is a Page Object Model DSL for Capybara.

We’ve been using it at my current client since December 2011 and it’s proven a great success. Until now I’ve kept it quiet to allow some time to develop it to the point that it does everything we need, but a few days ago SitePrism went to version 1.0 – early adopters tell me that SitePrism’s intuitive API lets them create expressive and maintainable Page Objects with ease, so take a look! The SitePrism ReadMe will give you an idea of what it’s like to put together a Page Object model of the site you’re testing using SitePrism with capybara…

Here’s the code: https://github.com/natritmeyer/site_prism
And here’s the documentation: http://rdoc.info/gems/site_prism/frames

Go take a look, it might save you a lot of frustration!

A Solution to AJAX errors with Capybara against a jQuery site

Ajax has long been a pain for browser-based test automation; it is often the main culprit when looking for the reasons behind some flakey tests. The normal scenario is this:

  1. Your test clicks a button which fires off an ajax transaction
  2. While the browser is talking to the server, the next line in your test executes
  3. Result? A failing test and a nice big irrelevant stack trace
  4. Frustration
  5. Reduction in self-esteem
  6. Spend a while trying to pin down and make allowances in the code for the problem

Well, if you’re using capybara to test a site that’s using jQuery, the following may help – it’s a method called wait_for_ajax that blocks until there are no active connections between the browser and the server. Basically, it *should* sort out any ajax-related problems. No guarantees though. But it does work for me…

To use it, call wait_for_ajax just after the line of code that kicks off the ajax transaction.

The method is in a module called AjaxWaiter that gets included into ‘World‘ (this example uses cucumber, ‘World‘ is not relevant if you’re not using cucumber). Anything added to World can be used in any of your steps. To use the above it in its current form, stick it in your cucumber project’s env.rb file. Here’s an example of wait_for_ajax‘s use in cucumber:

Well, I hope that helps. I know it’s improved my life…

Command Line Spotlight

Spotlight is probably my favourite thing about Mac OS X. I recently found out that it’s possible to use spotlight on the command line using the mdfind command. But, the arguments I have to pass to it to get what I want mean that it’s a bit ‘wordy’ and not nearly as convenient to use as the Real Thing. So, I’ve written a tiny function that does exactly what I want:

function sl() {
  /usr/bin/mdfind -onlyin \. $@
}

If you put that in your .bash_profile you’ll have the…

sl

…command available to you (‘sl’ as in ‘SpotLight’). It allows you to type…

sl find this phrase

…which will search for files that contain ‘find this phrase’; but instead of searching system-wide, sl will search the current directory and all child directories.