Validating feeds in functional tests

Manfred Stienstra

In the past I usually tested the feeds a Rails application generated by writing a functional test that checked the HTTP status code and matched certain strings in the feed using a regular expression. If that checked out I hand-tested the feed using the online feedvalidator. Needless to say, this became very cumbersome after a few times, especially for one of our projects that generates a whole list of different feeds depending on the state of the account. Time to add validation to the functional tests.

Unfortunately the feedvalidator is (not yet) written in Ruby, so we have to do system calls to a python script to validate. I installed the feedvalidator in the script directory, which looked like the correct place to put this. A protected method on the testcase makes sure we can easily test feeds.

def validate_feed(content)
  validate = File.dirname(__FILE__) + '/../../script/feedvalidator/validate.py'
  path = Pathname.new(File.dirname(__FILE__) + '/../tmp')
  Tempfile.open('feed', path.cleanpath) do |tmpfile|
    tmpfile.write(content)
    tmpfile.flush
    result = `#{validate} #{tmpfile.path} A`
    unless result =~ /No errors or warnings/
      raise "Feed did not validate: #{result}"
    end
  end
end

So now the testcases looks like this:

def test_atom
  get :atom
  validate_feed @response.body
  assert_equal 'application/rss+xml', @response.headers['Content-Type']
end

Note that this validates the feeds on level ‘A’ which only tests for MUST directives. For completeness you should probably still test either with the online validator or temporarily set the validation to ‘AA’ or even ‘AAA’.

Rumor has it that if you validate your feeds at ‘AAA’ level Mark Pilgrim will come to your house and crown you Prins of the Feeds. Lucky lucky!