Getting the TDD ball rolling

@joshclayton Wow, thanks for such a lengthy response. The header_on_page? method was definitely an example of hasty naming, so I get a slap on the wrist. But I completely get your point.

As far as creating two separate objects, I do have a couple of questions. Since a ShoutsOnPage object represents the index page, could we call it ShoutsIndexPage? I’m not asking this to nitpick your naming, but rather to make sure that is what it is ACTUALLY representing (also it could be hard to see the difference between ShoutOnPage and ShoutsOnPage).

If this is the case would the ShoutIndexPage method look something like this:

class ShoutsIndexPage
  ...

  def create_shout_for(user)
    ShoutOnPage.create_for(user)
  end

  def view
    visit shouts_path
  end
end

So we would have a ShoutsIndexPage to handle the logic of the page itself and then ‘on page objects’ to handle that (ShoutOnPage or CommentOnPage). I don’t know if this is overkill though.

Also, it seems like there could be a fair amount of overhead in terms of creating page objects versus driving through the conventional Capybara method. I really enjoy using these objects because it forces me to think and test my system in a more OO manner. I’m curious what you think the threshold is for saying ‘Hey, I’m going to use a page object!’ or if you’ve run into any situations where you tried to use one and it just didn’t fit.

@dolphorama I’m on board with the ShoutsIndexPage - again, I’m not sold on the naming conventions and something I’m very aware as something I don’t feel I have a good set of patterns for yet.

As for the ShoutOnPage object and CommentOnPage object, I typically just write the tests exactly how I want them worded, run the tests, and have them drive my implementation of my page objects (just like application code - isn’t it great how test-driven design is applicable for all layers of the application!?)

As for when to use page objects, I don’t think I never immediately jump into using them; it’s more an evolution of the tests. I typically start with helper methods in the individual feature blocks, extract to modules when I start to reuse the methods across feature files, and finally extract to page objects once there’s grouped behaviors.

Hopefully this helps clarify, and if anything else comes up, don’t hesitate to ask!

1 Like

Sorry to be this guy but I just have to point out that the downloadable video files of this screencast contain a typo in the filenames. It should be TDD not TTD.

I’m only pointing this out because I DL’d it to watch later and when I did a quick folder search for TDD nothing came up. In the ensuing seconds of chaos I realized it was just a filename typo.

If I was a funnier guy I would’ve cut the blather and just written something like

expect(video.filename).to include("TDD") # FAIL

Thanks for pointing that out. I’ve opened an issue for us to fix that up.

Fixed now! Thanks for the heads-up.