How to test for being on the right template in a feature test

Hi, for my feature test (spec/features/admin_handles_researcher_spec.rb), I want to test that clicking a link brings me to the right template.

    click_link @researcher.fullname

this should bring me to the

show.html.erb

template.

How can I test for this in a feature (integration) test?

thanks for your help,

Anthony

I think the least brittle way to test for this is to check for unique text in your template that is listed in your i18n locale file. Then, no matter what copy changes you make to copy, you have a reliable check for the content that is relevant to that template.

If you’re using the Flutie gem and the accompanying body_class method, you can also check to see if the right body class (something like .user_profiles-show) has been applied to the document body using Capybara CSS selectors.

Hi Geoff,

thanks for the info. I hoped there was some kind of straightforward way in a feature test, to test for the template. But if I understand you correctly, there is no direct way of testing that you are on the right template in a feature test.

greetings,

Anthony

For these kind of situations I usually compare Capybara’s current_path to a Rails named route, i.e.

expect(current_path).to eq researcher_path(@researcher)

Of course, this doesn’t actually check the content of page, only that it renders successfully, so even if your show template was empty this would still pass. But I would expect there to be a test elsewhere that verifies the show behaviour, so for this test verifying that we are on the correct path should be sufficient.

3 Likes

Hey @acandael_acanda,

No problem. If you’re very concerned about the template and not so much about the specific content, I’d just write a very small controller test and check which template was used there. Verifying an implementation detail like this is more of a unit test than an integration test.

-Geoff

2 Likes

Totally agree with @geoffharcourt, this feels like the concern of a controller test, where you have DSL for directly asserting this (render_template)

It is always tricky to find the correct level at which to test different parts of your system, this is a very welcome discussion :slight_smile:

Hi Andy,

This is exactly what I’m looking for, thanks. This line is testing that clicking the researcher link is bringing me to the researcher show template:

expect(current_path).to eq admin_researcher_path(@researcher)

greetings,

Anthony

Thanks everyone for your feedback. I agree with Pedro and Geoff, a controller test would probably be more appropriate for this.

However, in my integration test, I want to test that clicking a link is bringing me to the right page (template).

For people interested, my full integration test looks like this:

feature "Admin interacts with researcher" do
  background do
    @researcher = Fabricate(:researcher)
    admin = Fabricate(:admin)
    sign_in(admin)
    visit admin_researchers_path
  end

  scenario "Admin clicks researcher link and views researcher details" do
    project = Fabricate(:research_project)
    @researcher.research_projects << project
    course = Fabricate(:course)
    @researcher.courses << course
    @researcher.phone = "some number"
    @researcher.address = "Korte Meer 3, 9000 Ghent, Belgium"
    @researcher.bibliography = "http://biblio.ugent.be"
    @researcher.save

    click_link @researcher.fullname

    expect(current_path).to eq admin_researcher_path(@researcher)
    expect(page).to have_css 'h1', text: @researcher.fullname
    expect(page).to have_css 'p', text: @researcher.bio
    expect(page).to have_css 'a', text: @researcher.email
    expect(page).to have_css 'p', text: "some number"
    expect(page).to have_css 'p', text: "Korte Meer 3, 9000 Ghent, Belgium"
    page.should have_xpath("//img[@src=\"/uploads/researcher/image/#{@researcher.id}/#   {File.basename(@researcher.image.url)}\"]")
    expect(page).to have_css 'a', text: "http://biblio.ugent.be"
    expect(page).to have_css 'a', text: course.title
    expect(page).to have_css 'a', text: project.title
  end
end

greetings,

Anthony

Using Page objects would really help to clean this up and keep it focused on a higher level of abstraction, so you could end up with something like:

researcher_page = AdminResearcherPage.new
expect(researcher_page.header).to eq @researcher.fullname
expect(researcher_page.bio).to eq @researcher.bio
expect(researcher_page.researcher_email).to eq @researcher.email
1 Like

I agree with @andyw8 on the Page object. It also feels that the path check should be implicit at your integration level: asserting the proper information is there should imply that you are hitting the correct path.

@Andy, @Pedro, thanks for the advice. I will definitly look into Page objects.

In the meantime I wrote a controller test for my Admin::ResearchersController:

https://github.com/acandael/posplus-rails/blob/master/spec/controllers/admin/researchers_controller_spec.rb

greetings,

Anthony

Looks pretty good. You might want to use a factory to avoid repeating the researcher attributes in each spec.

Edit - I see you are actually using Fabricate, but you’re repeating the attributes in many places, which shouldn’t be necessary.