Feeds:
Posts
Comments

Archive for the ‘Testing’ Category

Overview

Every now and again I think I should maybe be integrating Javascript tests into my test suite. Then I take a look at the setup (Celerity, running in Java, plus Culerity, on top of my existing setup of RSpec + Cucumber + ROTS), and I think, “ick”.

Culerity & Co. probably makes sense for applications that are heavy on front-end modification using Javascript. But for my purposes, insofar as it is possible, I build my applications to work without Javascript, and then Ajaxify forms using jQuery. The JSON response includes the output of a rendered partial that replaces existing content already on the screen. Those partials are thoroughly tested via the standard, non-Ajaxian pathways.

The only part that has bitten me (and that not in a full-fledged production app) is when the underlying partial changes in some way that makes it incompatible with the way the partial is called when responding to JSON (for example, by making the partial require a new local variable).

Details

To ensure that all rendering pathways are tested, I added an RSpec example for every Ajax call. All it needs to test is whether the call is successful because all other aspects of the call are tested via the non-Ajaxian pathway. That gives the following:

  describe 'POST create via AJAX' do
    integrate_views
    it 'should be successful' do
      activate_authlogic
      UserSession.create(@contributor)
      post(:create,
           :node_id => @node.id,
           :score => 15,
           :format => 'json')
      response.should be_success
    end
  end

The “integrate_views” line is important. Usually, controller specs don’t render views, but in this case, the ability to render the view is the main thing we’re testing. It’s great that RSpec makes this option local to a describe block.

Read Full Post »

Overview

Providing the option of OpenID for account creation and sign-in helps keeps things easy on your users. It may even lower the barrier to people signing up for (and continuing to use) your service.

Authlogic implements user authentication beautifully, and it is readily extensible. By way of illustrating how to extend Authlogic, its author, Ben Johnson, released Authlogic OpenID. That makes supporting OpenID authentication as clean, easy, and flexible as Authlogic makes user authentication.

The difficulty, up to this point, has been testing OpenID. Some time ago, I was looking for ways to test OpenID, and I happened upon the Ruby OpenID Test Server (ROTS), by Román González. Googling various combination of ROTS and OpenID or Rails, one would think the experiment had failed, because of the lack of mention and its author’s only two blog posts on the topic [1] [2]. But I contacted Román via Git, and he offered very helpful assistance and pointed me to the rots_consumer, which is an example Rails (and Merb) application that uses ROTS to test OpenID. Today, I followed Román’s instructions and now have operational OpenID scenarios in my Cucumber suite (I was inspired to do so today because I wanted to add another OpenID related feature, and felt dirty not being able to do BDD).

This post covers how to get OpenID working in Cucumber (I’m running Cucumber 0.6.1, Cucumber-Rails 0.2.3, and Rails 2.3.5).

Details

To quote its ReadMe, “ROTS is a minimal implementation of an OpenID server.” When running OpenID tests against ROTS, the ROTS server must be running locally. It seems pretty lightweight, so isn’t a big deal, but if you don’t want to run against it all the time, tag your Cucumber scenarios that involve OpenID (or an entire file) with @openid and include “–tags ~@openid” as one of the std_opts in config/cucumber.yml. Then, when you want to test OpenID, run
$ cucumber --tags @openid features

Setting up your application to work with ROTS is pretty easy. First get ROTS. Román’s version is here. I ran into a problem in his current version with an application that requests dob from the OpenID server, so I wrote a patch. If you request dob as part of your OpenID request, check to see whether Román’s repository has fixed that issue, or use my fork. Either way, clone ROTS to your local system.

Once you have ROTS locally, build, install, and run the gem:
$ cd rots
$ gem build rots.gemspec
$ sudo gem install rots-0.2.2.gem
$ rots

I changed my default Screen settings to include a rots window and automatically launch rots. That way, I always have rots running when I open my work environment:
screen -t rots /bin/bash -c 'rots'

As an aside, I’m running Ubuntu 9.10, which comes with an elegant version of Screen called Byobu. Byobu makes it easy to set all the Screen preferences, such as changing ctrl-a to ctrl-j (not only is this better for Emacs, but J is the rest position for the right index finger, so is very fast).

Now for your Rails app.

Create features/support/openid.rb with the following contents:

require "rots"

World(Rots::TestHelper)

And features/step_definitions/openid_steps.rb with the following:

Then /^I (?:should )?receive a response from the OpenID Server$/ do
  server_request_uri = response.headers['Location']
  hash = openid_request(server_request_uri)
  visit(hash[:url], :get, hash[:query_params])
end

At this point, you can write your Cucumber scenarios. The important step to remember is, after any successful call to the OpenID server, you must have the line

    And I receive a response from the OpenID Server

or

    Then I should receive a response from the OpenID Server

Here are the OpenID steps I implemented for one application:
http://gist.github.com/334789

Read Full Post »