在Django测试中检测权限错误
我正在为我的视图编写详细的功能测试,以补充我对模型的单元测试。这是一个Django项目,我使用的是Django自带的测试框架和unittest。显然,在这些功能测试中,一个重要的检查点就是权限设置是否正确。考虑到这一点,我尝试了以下方法:
anonclient = Client()
userclient = Client()
userclient.login(username='test_user', password='test')
adminclient = Client()
adminclient.login(username='test_admin', password='test')
path = "/path/to/my/page"
anonresponse = anonclient.get(path)
userresponse = userclient.get(path)
adminresponse = adminclient.get(path)
我需要确认anonclient和userclient都被拒绝了权限,而adminclient则正常工作。然而,我找不到一个可靠的方法来测试这一点!
起初,我决定检查响应是否是302重定向(因为权限检查失败的一个副作用就是会被重定向),但这样就无法区分是功能自动重定向用户,还是权限检查失败。(我不能仅仅使用self.assertRedirects(response, url),因为目标网址可以通过permission_required装饰器的login_url参数在视图中被覆盖!)
也许我应该考虑扩展user_passes_test装饰器,让它在测试失败时给响应对象添加一个属性?这样在测试中就可以检查这个属性。如果这样不行,我就得通过检查请求的副作用来判断请求是否成功。这样做是可行的,但会非常繁琐,尤其是需要进行很多这样的检查时。
我想我不是第一个遇到这个问题的人,处理这个问题的正确方法是什么,或者我遗漏了什么?
非常感谢!
2 个回答
permission_required 装饰器和 PermissionRequiredMixin 都有一个叫 raise_exception
的参数。
处理这个参数的一种方法是在你的 settings_test.py
文件中设置一个类似 PERMISSIONS_RAISE_EXCEPTION=True
的配置选项(如果你在测试时使用了单独的设置文件)。
from django.conf import settings
@permission_required('<perm>',
raise_exception=settings.PERMISSIONS_RAISE_EXCEPTION)
def your_view(...)
pass
class YourView(PermissionRequired):
raise_exception = settings.PERMISSIONS_RAISE_EXCEPTION
这样,你就可以在测试中捕捉到这个异常,检查是否出现了403错误,同时还能保持重定向到登录页面。
client.login('user', 'blah')
response = client.get('/yourview')
assertNot(403, response.status_code)
不过,把这个设置加到你所有的 permission_required
装饰器上可能不是你喜欢的做法,因为这感觉有点像把测试代码放进了源代码里,但这是我目前见过的唯一方法。
Django的测试客户端在你调用登录方法时,会返回一个布尔值,这个值告诉你登录是否成功。
[17] >>> from django.test import Client
[18] >>> c = Client()
[19] >>> c.login(username='superuser', password='bar')
[19] : False
[20] >>> c.login(username='superuser', password='correct_password')
[20] : True