【问题标题】:Detecting permission errors in django tests在 django 测试中检测权限错误
【发布时间】:2010-04-14 14:43:29
【问题描述】:

我正在为我的视图编写详细的功能测试,以补充我的模型上的单元测试。这是一个 Django 项目,我正在使用带有 unittest 的内置 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 工作正常。但是,我无法找到一种方法来测试这是否已发生可靠

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

也许我应该考虑扩展 user_passes_test 装饰器,以便在测试失败时向响应对象添加一个属性?然后可以在测试中检查这一点。如果失败,我将不得不通过检查请求的副作用是否发生来确定请求是否成功。这样做会奏效,但会非常冗长,尤其是在进行大量此类检查的情况下。

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

非常感谢!

【问题讨论】:

    标签: python django unit-testing permissions client


    【解决方案1】:

    django 测试客户端在调用 login 方法时返回一个布尔值,告诉你登录是否成功。

    [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
    

    【讨论】:

    • 谢谢贾斯汀,但你误解了我的问题 - 我需要检查后续获取是否成功或是否发生权限错误(导致重定向)。登录工作正常 - 我需要能够测试权限检查是否在 Django 视图上工作。
    • 您应该能够检查生成的 url 是否是您尝试访问的那个。 my_url = '/foo/' resp = c.get(my_url) 然后您可以检查resp 对象以获取与结果页面相关的内容。 docs.djangoproject.com/en/dev/topics/testing/#testing-responses 具体来说,状态码、检查是否使用了正确的模板等。希望对您有所帮助!
    • 正如我所说,我希望能够区分提供重定向的视图和未通过测试的用户重定向的视图。我知道我可以检查副作用或嗅探结果页面(实际上,这就是我现在正在做的)但我想知道是否有办法检测用户未通过测试并且视图不是直接跑现在似乎没有,所以我想我会在 1.2 版本之后提交一个功能请求,或者自己推出一个修补过的 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 装饰器可能不符合您的口味,感觉有点像您将测试代码添加到源代码中,但这是迄今为止我看到的唯一方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      • 2010-10-07
      相关资源
      最近更新 更多