Sunday, April 22, 2007

Taming assert_select with css_select and Regexp.escape

I had a lot of trouble writing a test to check whether all elements of an array were showing up in a table properly; I needed more fine-grained testing than assert_select was allowing me. I needed to guarantee that every element in an array could be found as a child of a particular table.

Fortunately, I noticed that Rails also has a css_select method which returns an array of selected elements without running tests on them. This lets you run your own tests using the results of the selection.

This isn't the prettiest code in the world (I'm also testing a formatting helper, hence the literals '$200.00' and so on), so I'll probably refactor it later. There might also be a way to do this more elegantly with assert_select. But I think this does show the utility of css_select.
elements = css_select('table#investors tr td')

[[investors(:investor_8),'$200.00'],
[investors(:investor_9),'$343.40']].each do |i,amount|

assert_not_nil elements.detect \
{ |e| e.to_s =~ /#{i.name}/ }

assert_not_nil elements.detect \
{ |e| e.to_s =~ /#{Regexp.escape(amount)}/ }

end

Things to watch out for:
  • You need to force the conversion of the element to a String for the regular expression comparison (with to_s)
  • In this particular example, since I am using string literals with special characters, I had to use Regexp.escape to make $ and . match properly

2 comments:

Paul Barry said...

I haven't tried it, but you could create this helper method, and then (assuming that works), your tests methods would look like this.

Anonymous said...

shoe carnival
nike sneakers
Nike Basketball shoes
MBT shoes
supra shoes She gave some to Toto, and taking a pail from the
shelf she carried it down to the little brook and filled it with
clear, sparkling water.