2010-04-14 55 views
5

我正在为我的视图编写详细的功能测试,以补充我的模型上的单元测试。这是一个Django项目,我用unittest使用内置的Django测试框架。显然,在这些功能测试中检查的重要事情之一是权限设置正确。考虑到这一点,我试图这样的事情:在django测试中检测权限错误

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工作。 Howerver,我无法找到一种方法来测试这发生了robustly

起初我决定检查响应是302重定向(因为重定向失败的副作用),但这意味着不可能区分自动重定向用户的功能和失败的权限检查。 (我不能只使用self.assertRedirects(response,url),因为目标url可以通过视图中permission_required装饰器的login_url参数覆盖!)

也许我应该考虑扩展user_passes_test修饰器,以便它添加如果测试失败,则返回响应对象的属性?这可以在测试中检查。否则,我将不得不通过检查请求的副作用是否发生来确定请求是否成功。这样做会起作用,但它会非常长时间的啰嗦,特别是有很多这些检查正在完成。

我无法想象我是第一个遇到这个问题的人,处理这个问题的正确方法是什么,或者我错过了什么?

非常感谢!

回答

1

当您调用登录方法时,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 
+0

感谢贾斯汀,但你误解了我的问题 - 我需要检查后续获取是否成功或者是否发生权限错误(导致重定向)。 登录工作正常 - 我需要能够测试权限检查工作在Django视图。 – adamnfish 2010-04-14 15:51:44

+0

您应该能够检查产生的网址是否是您尝试访问的网址。 my_url ='/ foo /' resp = c.get(my_url) 然后,您可以检查与您的结果页面相关的事件的resp对象。 docs.djangoproject。com/en/dev/topics/testing /#testing-responses具体而言,状态代码,检查是否使用了正确的模板等。希望有帮助! – 2010-04-16 05:54:27

+0

正如我所说,我希望能够区分服务重定向的视图和未通过测试的用户重定向的视图。我知道我可以检查副作用或嗅探结果页面(实际上,这是我现在所做的),但我想知道是否有方法检测用户未通过测试并且视图不是直接运行。 看来现在还没有,所以我想我会在1.2版本之后提交一个功能请求,或者自己修改一个打补丁的user_passes_test装饰器。 – adamnfish 2010-04-16 09:51:02

1

permission_required装饰和PermissionRequiredMixin具有raise_exception参数。

处理这个问题的一种可能的方式是有一些像一个PERMISSIONS_RAISE_EXCEPTION=True配置选项在settings_test.py(如果您使用的测试运行一个单独的设置,并有

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装饰未必是你的味道,感觉有点像您将测试代码添加到源代码中,但这是迄今为止我看到的唯一方法。