【问题标题】:How to check template context using Pyramid + webtest如何使用 Pyramid + webtest 检查模板上下文
【发布时间】:2016-01-24 10:32:33
【问题描述】:

我开始为我的 Pyramid 视图编写测试(使用 webtest),并且来自 Django 背景,我很难理解如何测试某些变量是否已传递给模板。 例如让我们考虑这个视图:

@view_config(route_name='login_or_signup', renderer='login_or_signup.html')
def login_or_sign_up(request):
    if request.method == 'POST':
        try:
            do_business_logic()
            return HTTPFound(location=next)
        except Invalid as e:
            request.response.status_code = 400
            return dict(form_errors=e.asdict())
    return {}

如何编写一个测试来证明如果表单不正确,则将form_errors 字典传递给模板?在 Django 中,我会使用 context 属性,但在 Pyramid/webtest 中我找不到类似的东西......似乎无法通过响应对象访问模板的数据。为了访问这些数据,我发现的唯一方法是通过事件侦听器:

@subscriber(BeforeRender)
def print_template_context(event):
    for k, v in event.rendering_val.items():
        print(k, v)

但我认为使用这种方法是不可行的,因为:

  1. 它是一个全局监听器
  2. 它无权访问响应对象

所以...我尝试扩展基础 Response 类(以便为其附加额外的字段):

class TemplateResponse(Response):
    def __init__(self, template, template_context=None, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.template = template
        self.template_context = template_context or {}
        self.text = render(self.template, self.template_context, self.request)

并将原始视图更改为:

   @view_config(route_name='login_or_signup')
    def login_or_sign_up(request):
        if request.method == 'POST':
            try:
                do_buisness_logic()
                return HTTPFound(location=next)
            except Invalid as e:
                return TemplateResponse(
                    'login_or_signup.html', 
                    dict(form_errors=e.asdict()), 
                    status=400
            )
        return TemplateResponse('login_or_signup.html')

但是很无奈,因为webtest返回的是自己的TestResponse对象而不是我的TemplateResponse...那我该如何测试模板中的数据呢?

【问题讨论】:

    标签: python pyramid webtest


    【解决方案1】:

    尽管我并不完全满意,但我目前使用 webtest 和默认 Pyramid 测试工具解决了问题:

    template_request = DummyRequest(path='/login-signup', post=data)
    template_context = LoginSignupView(template_request).post()
    response = self.app.post('/login-signup', data, status=HTTPBadRequest.code)
    self.assertEqual(response.status_code, HTTPBadRequest.code)
    self.assertIsInstance(template_context['form_errors'], dict)
    

    DummyRequest 直接传递给 View,它只返回一个包含模板变量的字典。相反,实际的“导航”被委托给 TestApp 实例,该实例能够取回已呈现的实际 html 响应。

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 2012-04-16
      • 2016-05-05
      • 2020-07-23
      • 1970-01-01
      • 2017-07-02
      • 1970-01-01
      • 2016-02-19
      • 2012-03-06
      相关资源
      最近更新 更多