Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

PIVOTAL LABS
Standup 02/05/2008

Interesting Things

  • In exploring options for RSpec testing of XML responses, one project decided
    a custom XPath matcher
    would do the trick nicely:

    items = Item.find(:all)
    get :index
    
    
    response.body.should     have_nodes("//items/item", items.size)
    response.body.should     have_xpath("//items/item[ position() = 1 and @id = '0001' ]")
    response.body.should_not have_xpath("//bogus")
    

    Some other possibilities:

    • Hashes…

      items = Item.find(:all)
      get :index
      
      
      hash = Hash.from_xml(response.body)
      hash['ancestor']['parent']['items']['item'].size.should == items.size
      hash['ancestor']['parent']['items']['item'][0]['id'].should == '0001'
      hash['ancestor']['parent']['bogus'].should be_nil
      
    • Hpricot…

      items = Item.find(:all)
      get :index
      
      
      doc = Hpricot(response.body)
      doc.search("//items/item").size.should == items.size
      doc.at("//items/item[ @id = '0001' ]").position.should == 1
      doc.at("//bogus").should be_nil
      
    • assert_select from Rail’s Test::Unit (using CSS-style selectors)…

      items = Item.find(:all)
      get :index
      
      
      assert_select("items > item", :count => 5)
      assert_select("items > item:nth-child(1)[id=?]", '0001')
      assert_select("bogus", false)
      

    What are your favorite techniques for asserting XML/XPath?

  • Something to consider when test-driving controller code:

    You’re working with ActionController::TestResponse. So, response.success?,
    response.redirect?, etc. are available for you there (since they are
    defined on TestResponse), but not in your actual controllers. That is,
    things blow up if you try to use @response.success? in your application,

    e.g. to determine whether or not to store the current URL and redirect there
    after a login.

Comments
  1. Hualing says:

    I always use ruby more for applications. I’ve read somewhere that they’re coming up with a more advanced and stable version of it. Any thoughts?

  2. We use a custom XPath matcher, based on the link you provided, using Hpricot to do the parsing. I found a decent speed improvement by using Hpricot instead of REXML. Also, if you are considering assert_select, but want to use RSpec, then why wouldn’t you use have_tag, it’s just a wrapper around assert_select.

  3. Corey says:

    @James – Great feedback. We actually also have at least one project using custom matchers backed by Hpricot, but they’re less complete (and less publicly accessible) than the one linked above. Good suggestion with Rspec’s `have_tag`; example set ported to `have_tag` below. Keep in mind that you take a performance hit when using `have_tag` (and by extension `assert_select`) since Rails loads the entire DOM.

    items = Item.find(:all)
    get :index

    response.should have_tag(“items > item”, :count => 5)
    response.should have_tag(“items > item:nth-child(1)[id=?]”, ‘0001’)
    response.should have_tag(“bogus”, false)

  4. Corey says:

    And, I guess this would be nicer for that last one… `response.should_not have_tag(“bogus”)`

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *