Testing your Rails views with Hpricot

Update: This extension is now available as a Rails plugin. See below for more details.

_why released his great little Hpricot HTML parser the other day and the first thing that struck me would be that it would be a great tool for testing the output of Rails views. Rails comes with the built-in assert_tag method but I've always found it clunky and a pain in the arse to use.

By combining the Hpricot library and a few useful helper functions, you can now test the output of your Rails views in Test::Unit::TestCase easily using Hpricot's support for CSS selector searches.

First of all, install Hpricot if you don't have it already:

[code] $ gem install hpricot --source code.whytheluckystiff.net

Next, download the Hpricot Test Extensions file and copy it to the lib folder of your Rails app.

Finally, require the file at the top of your test_helper.rb file:


# test_helper.rb
require 'hpricot_test_extension'

Alternatively, you can also install as a Rails plugin. The plugin is located in the Agile Evolved Open Source repository.

And thats it. You'll now have access to four new methods - tag, tags, element and elements. All four methods take a CSS selector as an argument. The pluralised methods return an array of search results for the CSS query, the singular methods just return the first (handy if you know you'll only have one of a particular element, say, "title"). The tag methods return the inner contents of the returned elements, whereas the element methods return the raw Hpricot::Elem objects for you to work with. Here's a few examples:


assert_equal "My Funky Website", tag('title')
assert_equal 20, tags('div.boxout').size
assert_equal 'visible', element('div#site_container').attributes['class']

Finally, there is a small extension to the Hpricot::Elem object itself which lets you assert the presence of text within an element using an alternative syntax:


assert element('body').should_contain('My Funky Website')

I plan to integrate these helpers into rSpec as well using a more rSpec-style syntax. Any comments and suggestions are welcome.

Return to home page | Check out my tumblelog

14 Comments on this article

1. Comment by Ladislav Martinčík on 07 Jul 2006 at 15:07

Huh. Interesting. Keep doing this. I like that. :)

2. Comment by Andrew Turner on 07 Jul 2006 at 18:07

Great idea – I’ll d/l this as soon as I get to my dev machine

3. Comment by topfunky on 07 Jul 2006 at 19:07

That looks very useful! How about a Rails plugin to make it even easier?

See http://topfunky.net/svn/plugins/topfunkypowertools for an example of a test-related plugin.

4. Comment by Luke on 07 Jul 2006 at 19:07

topfunky – I thought about making it as a plugin but I thought I’d wait and see if anybody asked first ;)

However, your wish is my command etc.

http://opensource.agileevolved.com/svn/root/rails_plugins/hpricot_test_helper/trunk

5. Comment by Peter Cooper on 07 Jul 2006 at 20:07

Hmm, I think I was going to try and catch up with you at POR last night, but I guess it didn’t happen. Oh well, next time maybe! :) I saw Jonathan though.

Anyway, nice piece of work here, I’ll probably be putting it on RubyInside shortly :)

6. Comment by Aslak Hellesoy on 07 Jul 2006 at 22:07

Luke, this looks great!

This is something we’ll definitely consider adding to RSpec! (I saw your mail to the RSpec list).

7. Comment by Damien Tanner on 08 Jul 2006 at 22:07

Great job, gonna get using this right away :D

8. Comment by Rodney on 10 Jul 2006 at 14:07

Nice, Applied Hpricot, very cool, tnx

9. Comment by Rob Sanheim on 20 Jul 2006 at 06:07

Hiya,

I think there is a problem with the plugin – it expects HpricotExtensionSomething from within process_output, but the actual module is called HpricotTestHelper. So I just changed the line to:

@output = HpricotTestHelper::DocumentOutput.new(@response.body) if @output.nil?

and it fixed things…

10. Comment by Rob Sanheim on 20 Jul 2006 at 06:07

that should be one line, btw…

thanks for the plugin.

11. Comment by Luke Redpath on 20 Jul 2006 at 17:07

Hi Rob, thanks for the notice. Could you file a bug on the agile evolved trac – cheers.

12. Comment by Jay Levitt on 24 Jul 2006 at 23:07

This is great stuff! I’m using a modified version of the test_helper to test new behaviors with Radiant.

Looking forward to the rspec integration as well – rspec has changed the way I develop.

13. Comment by choonkeat on 26 Jul 2006 at 10:07

Hi, in your plugin lib/hpricottesthelper.rb(59) did you mean: HpricotTestHelper::DocumentOutput.new(@response.body) instead of, HpricotTestExtension::DocumentOutput.new(@response.body)

14. Comment by Luke on 26 Jul 2006 at 11:07

@rob, choonkeat:

Yeah, a small bug there left over from the conversion to a plugin. I’ve fixed this now so run an svn update (revision 113).

Return to home page | Check out my tumblelog

Commenting on this article is now closed