Peter Marklund

Peter Marklund's Home

Thu August 24, 2006
Programming

Rails Recipe: Checking for Broken Links in Integration Tests

Having a way to automatically check for broken links in your application can be quite valuable and there is a simple way to do that with integration tests. Here is the DSL methods that I used for that purpose along with some sample usage:

  module TestingDSL
    def visits_start_page      
      get_with_links("/mcm") do
        assert_tag :tag => 'a', :attributes => {:href => '/mcm/contacts/search_form'}
      end
    end

    def get_with_links(*args)
      request_with_links(:get, *args)
    end

    def post_with_links(*args)
      request_with_links(:post, *args)
    end

    def request_with_links(method, *args)
      self.send(method, *args)
      yield if block_given?
      assert_response :success
      check_links            
    end

    def check_links
      find_all_tag(:tag => 'a').each do |anchor|
        url = anchor.attributes['href']
        if check_url?(url)
          get(url)
          assert_response_code
        end
      end      
    end

    def check_url?(url)
      [/mailto:/, /javascript:/, /user\/logout$/, /:\/\//, /^\#$/].each do |skip_pattern|
        return false if url =~ skip_pattern
      end
      true
    end
    
    def assert_response_code
      assert [200, 302].include?(@response.response_code), 
        "Invalid response code #{@response.response_code} for path #{@request.path} #{@response.body}"
    end
  end

I've found this approach to link checking helps me find bugs that other tests don't find. The only downside is that it can significantly increase the number of requests in your integration tests and thus the test time. There are ways to work around that though, you don't have to check links on every page request, and the link checker could be extended to not request the same URL twice.

Comments

Kelly said over 8 years ago:

Peter,

Thanks for posting this. I think this is just what I need. However, I don’t
understand all of it.

  • Why is this included in a module? I assume you mix it in to integration tests?
  • If its for mixing in it seems to have test specific stuff in it, like ‘visits_start_page’.

It looks like there are 2 things here — the mixin and some sample code, but all in the same mixin…

In any case, this looks like just what I need. Thanks for posting.

-Kelly

--------------------------------------------------------------------------------

needfornews said over 6 years ago:

urls to the latest world news.

--------------------------------------------------------------------------------