Topic: DRY in testing with authenticated systems

I've got an app with pages that will do different actions depending on your login state. eg,
Not logged in: redirect to login page
Logged in as user: if user has permission then display page, else display error

The app itself works fine, but for all my test's, i'd like to automagically try the action w/out the login and confirm it redirect's okay (rather than having two or three tests for the same page testing how it behaves for different log in conditions violating badly the DRY principle smile.

Any one have any ideas on how I could do this?

Dave Smylie

Re: DRY in testing with authenticated systems

I'm assuming you DRYed the application by putting the login check in a before filter. Is it really necessary to test every action since it is all calling the same code? I would think testing one or two actions is sufficient.

Railscasts - Free Ruby on Rails Screencasts

Re: DRY in testing with authenticated systems

I easily see both sides of this debate.  Personally, only test a token few require authentication actions (often one per controller).  I would prefer to test all, though, if there was a convienent, DRY way to do so.

There's several things that need to be tested:
a) controller helper (or model depending on your bent)
  1) is the current session authenticated
b) controller/action logic
  1) does this controller/action require authentication
  2) if authentication is required and the session isn't authenticated, what should happen next

In most applications b2 is univerisal -- redirect to a login page, save the initial requested page for redirect back to after successful authentication.  Thus this should be tested once.  Ditto of a1 -- its a single function that's unverisal.

b1, however, is the tricky bit.  You want to assert that every action that requires authentication, is properly requiring it.  It would be enough, I think to reflect on the controller that the named before_filter would run before the action.  So in psudeo code a DRY test would be something like

  actions = controller.get_actions
  actions.each do |action|
    assert_before_filter controller, action, :require_authentication

If you had actions that didn't require authentication you could do action - [:some_action], etc.  You also might want the compliment to test that for specified actions the before_filter won't be called.

However I'm not sure how easy/hard it would be to generate the needed custom assertion to handle these cases.

If you don't use :except=>, :only=> on your before filters, then perhaps you can trust it with a single test action.  But once you start using either of the qualifiers I feel like you should explicitly test each action to avoid oversights causing problems.

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: DRY in testing with authenticated systems

Thanks for your responses. I am using a before_filter, but do also use except/only clause with it smile
I think i might walk the middle line and test only those that require authentication.