Rails Testing First Look: Blue Ridge

So, I tried Blue Ridge for the first time yesterday and I thought I'd write down some quick impressions. Hence, Rails Testing First Look.

Disclaimer: We came into this tool so cold our toes froze. We fumbled, we made mistakes, we probably missed really great ways of doing things. I look forward to being enlightened.

Let's do this question-and-answer style: What is Blue Ridge? Glad you asked. It's an framework for testing JavaScript from inside a Rails application. For the most part, it's a cohesive bundle of existing JavaScript test tools, such as Screw.Unit. The value-add of Blue Ridge is an easy installation and nice integration with Rails testing tasks.

Why did we start using it? We had some simple JavaScript stuff to do, and thought it would be a good time to start out with what looks like a solid way to test.

Is it easy to install? Very. Install as a plugin ./script/plugin install git://github.com/relevance/blue-ridge.git, then generate the Blue Ridge files with script/generate blue_ridge.

Blue Ridge will install a test/javascript directory. In that directory will be a sample test file application_spec.js, a helper file, and a fixture directory. Each javascript test file is assumed to have a matching HTML file in the fixture directory which is loaded to provide a sample DOM for test purposes.

Does it make any other assumptions? BlueRidge assumes you are using jQuery as your library. It's theoretically possible to use Prototype, but we ran into continual difficulties (possibly because we were doing it wrong), and actually wound up switching to jQuery for the project, easy enough to do since we just started.

How do you write tests? Tests are written using Screw.Unit syntax, and if you are familiar with RSpec, the syntax will look pretty similar. Here's the final draft of the first couple of tests we wrote, for a search box with default text that goes away when focused. The TextMate Screw.Unit bundle was very helpful, but other than that, the tests are pretty straightforward.

Screw.Unit(function() {
  describe("With my search box and default", function() {
    it("should switch the default", function() {
      search_focus($('#unified_search'));
      expect($('#unified_search').attr('value')).to(equal, '');
    });

    it("should switch a non-default", function() {
      $('#unified_search').addClass('search_entry');
      search_blur($('#unified_search'));
      expect($('#unified_search').attr('value')).to(equal, default_text);
    });

    it("should not switch if there is a value", function() {
      $('#unified_search').attr('value', 'Fred');
      search_blur($('#unified_search'));
      expect($('#unified_search').attr('value')).to(equal, 'Fred');
    });

  });
});

How do you run tests? Two ways. Blue Ridge provides a test:javascripts Rake task that will run all your Javascript tests in the terminal, this is also suitable for including in your continuous integration build, for example. A very nice feature from Screw.Unit is the ability to run tests in browser by simply opening the fixture HTML file in the browser of your choice. As long as your choice isn't Safari, which isn't supported at the moment. The ability to run the tests in console and in browser is very useful.

Any gotchas? Oy. We had what appeared to be some minor differences between the Rhino implementation that powers the console tests and the browser tests, leading to tests passing in the browser and failing in the console. We weren't quite able to do what amounted to integration tests -- we tried to trigger the JavaScript events so that the jQuery functions tested above were triggered, but couldn't get that to work. You have to be careful that the fixture HTML file actually has all the DOM elements you need, and remember that fixing the actual view doesn't change the fixture. Screw.Unit's error messages on failure aren't as helpful as they might be, there also seemed to be a thing where the fixture DOM wasn't actually being reset between tests, but I'm not 100% sure about that, we wound up working around it.

And in the end? That said, I did feel better about my JavaScript after having tested it. Fixing the JavaScript code, it was nice to see that other functions hadn't broken. There's a lot to like here, and I'm hoping to get past my initial problems to a tool that will improve the JavaScript parts of my code.

Related Services: Ruby on Rails Development, Custom Software Development