Reducing redundancy in tests, logged-in vs. not-logged-in

18 views
Skip to first unread message

Tim Chase

unread,
Nov 16, 2015, 3:37:55 PM11/16/15
to django...@googlegroups.com
Are there best practices for writing tests where every case has a
"not logged in" and a "logged in" pairing? I'm finding myself writing
too much redundant test-code where the only difference is whether the
user is anonymous (and thus the test should fail) or logged in with
appropriate rights (and thus the test should pass).

For context, this is being run within Django-WebTest as recommended
to me by Carl Meyer in case it has features I haven't yet encountered
that would help me.

Are there best practices to keep these sorts of tests DRY?

Thanks,

-tkc




Carl Meyer

unread,
Nov 16, 2015, 3:50:31 PM11/16/15
to django...@googlegroups.com
Hi Tim,
Now I'm going to recommend another testing tool: py.test :-)

I handle this type of situation by using py.test parametrization.
Usually I have a bunch of views that are all login-required, so I just
write a single test to check that a view returns redirect-to-login if
accessed anonymously, and then parametrize that test over all the urls
it should apply to. It looks something like this (parametrizing over
just two views):

@pytest.mark.parametrize(
'urlname,urlkwargs',
[('oneview', {}), ('otherview', {'id': 999})],
)
def test_login_required(client, urlname, urlkwargs):
url = reverse(urlname, kwargs=urlkwargs)
resp = client.get(url)

assert utils.redirects_to(resp) == reverse('accounts_login')

I use url-reversing in my tests; the parametrization would be slightly
simpler if you just used raw URLs. The `client` kwarg is a py.test
fixture that returns a WebTest client instance. `utils.redirects_to` is
just a helper that pulls out the `Location` header from the response,
and strips out everything but the path portion.

HTH,

Carl

signature.asc
Reply all
Reply to author
Forward
0 new messages