← Back to Upcase

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


(Acandael Acandael) #1

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


(Geoff Harcourt) #2

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.


(Acandael Acandael) #3

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


(Andy Waite) #4

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.


(Geoff Harcourt) #5

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


(Pedro Moreira) #6

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:


(Acandael Acandael) #7

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


(Acandael Acandael) #8

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


(Andy Waite) #9

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

(Pedro Moreira) #10

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.


(Acandael Acandael) #11

@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:

greetings,

Anthony


(Andy Waite) #12

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.