Victor Quinn

Software Engineer, Legal Scholar, Problem Solver.

Using Capybara and RSpec to Test Drupal

tl;dr

I created a git repo with a framework for testing Drupal sites using Capybara webkit and RSpec so any Drupal developers can just clone it and go.

View project on Github

Rationale

The first question I’m likely to get here is “Why?” Drupal has its own testing framework SimpleTest which can be used for both Unit and Functional tests, so why try to use RSpec/Ruby? Also, SimpleTest has access to all of the Drupal-y goodness, why write functional tests in Ruby where those functions would not be available?

That’s a great question. In my case I’m trying to run tests on a Drupal instance that is on a different machine. In my case I’m trying to run the tests from by desktop and hit my production web server which is on an offsite clustered server. Here SimpleTest wouldn’t fit the bill. These tests allow me to take into account network latency and such.

Note, of course since these tests are not in Drupal, tests written and performed like this will not do the setup/teardown like SimpleTest. So I would strongly suggest only touching data on test websites.

Setup

First, test that ruby exists and is the right version.

1
ruby -v

I used ruby 1.9.3-p194 managed by rvm but I believe any 1.9+ version of ruby should work here with Capybara.

Next, clone my repo which is basically a skeleton setup ready to test Drupal using Capybara. In the repo I’ve included a file called default.config.yaml. You will want to copy that file to config.yaml. The Gemfile should be set up to install all necessary dependencies.

1
2
3
git clone git://github.com/victorquinn/drupal-capybara.git
cp default.config.yaml config.yaml
bundle install

Now edit config.yaml and change the values to match the Drupal site you are testing.

1
2
3
site: "http://mycoolwebsite.com"
user: myusername
password: abcd1234

Is it working?

I’ve included two sample tests, one which will just check to ensure the site can be hit and the second which should try logging in to your Drupal site using the values in config.yaml. I’ve tested this both on Drupal 6 and Drupal 7 and works out of the box on both.

Try to run the tests and ensure things work. Go to the root of that directory (drupal-capybara by default) and try to run it! (do not try to run this from inside the spec directory, you’ll get errors.)

1
rspec spec

You should see something like the following:

1
2
3
4
5
6
2012-10-12 11:45:18.027 webkit_server[73469:707] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead.

..

Finished in 4.23 seconds
2 examples, 0 failures

The warnings can be safely ignored. I am not sure exactly why they’re there, something to do with the way the Capybara webkit code is with Mountain Lion. But it’s just a warning and doesn’t have anything to do with our web tests.

Note: The login test I included will only work if your system has not altered the login page. If something has changed the Log In button to say “Login” or “Go” or “Submit” or anything else, the test will fail. This is one of the downsides of trying to write tests for Drupal in a system that is not associated with Drupal – it cannot dynamically know about anything which has changed internal to Drupal.

** Capybara webkit can be a bit of a tricky beast to get installed on your system with dependencies and such. Jump to the bottom to see more details on some possible solutions.

Now test that tests fail correctly by changing your password in config.yaml to a bad value and run it again.

1
2
3
site: "http://mycoolwebsite.com"
user: myusername
password: notmypassword

You should see something like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2012-10-12 11:42:51.760 webkit_server[72603:707] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead.

Failures:

  1) DrupalTest login works
     Failure/Error: verify_login_worked
       expected #has_content?("Sorry, unrecognized username or password.") to return false, got true
     # ./spec/drupal_test_helper.rb:10:in `verify_login_worked'
     # ./spec/drupal_capybara_spec.rb:27:in `block (2 levels) in <top (required)>'

Finished in 3.46 seconds
2 examples, 1 failure

Failed examples:

rspec ./spec/drupal_capybara_spec.rb:25 # DrupalTest login works

Here failure is a good thing! Shouldn’t be able to log in if the password is wrong. Don’t forget to change your password back in config.yaml before moving on.

This isn’t a full rspec tutorial as such, but with my example tests that should be a good start. I’ve included a third sample test of filling out a Drupal form in my code (specifically in spec/drupal_capybara_spec.rb, but it’s commented out by default because that’s kind of specific to the particulars of the site and I didn’t want to send this out with tests likely to fail on most systems.

I should note, you can also run RSpec to get a nice HTML output. Just run the following:

1
2
3
rspec spec --format html --out results.html
# And if you're on a Mac, to open the results in a browser, just run:
open results.html

You should be all set and ready to write some tests!

Troubleshooting Capybara Webkit

Not to sugar coat things, I found Capybara Webkit pretty painful to get installed.

I’ll help with the issues I overcame, but generally it will likely involve some googling and such as it’s very dependent on the particulars of the system on which this is being run. For reference, I am on Mountain Lion (10.8.2) using ruby 1.9.3-p194. I also use HomeBrew to manage packages.

If you get the following error:

1
2
3
4
5
6
7
8
9
10
Installing capybara-webkit (0.12.1) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /Users/<username>/.rvm/rubies/ruby-1.9.3-p194/bin/ruby extconf.rb


Gem files will remain installed in /Users/<username>/.rvm/gems/ruby-1.9.3-p194/gems/capybara-webkit-0.12.1 for inspection.
Results logged to /Users/<username>/.rvm/gems/ruby-1.9.3-p194/gems/capybara-webkit-0.12.1/./gem_make.out
An error occured while installing capybara-webkit (0.12.1), and Bundler cannot continue.
Make sure that `gem install capybara-webkit -v '0.12.1'` succeeds before bundling.

Then it’s likely qt is not installed on your system. I resolved this by running:

1
brew install qt libpng

Mentioned above, but if you’re on Mountain Lion you will likely see a warning such as:

1
2012-10-11 18:16:42.457 webkit_server[64967:707] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead.

but it can safely be ignored.

If all else fails and you cannot get Webkit working on your system, Selenium can be used instead of Capybara Webkit so all this magic still works, just using Selenium instead of Webkit.

Alternative setup with Selenium

To use Selenium instead of headless Webkit, simply edit the drupal_capybara_spec.rb file as follows:

1
2
3
4
5
# Before
Capybara.default_driver = :webkit
Capybara.javascript_driver = :webkit
# After
Capybara.default_driver = :selenium