测试Flask render_template() 上下文

38 投票
4 回答
21353 浏览
提问于 2025-04-18 08:15

我有一个Flask的路由,看起来是这样的:

@app.route('/')                                                                 
def home():                                                                                                                  
    return render_template(                                                     
        'home.html',                                                            
        greeting:"hello"                                       
    )                                                                           

我该如何测试一下,'home.html'这个模板是否被正确渲染了,并且render_template()这个函数里定义的greeting变量是否有特定的值呢?

这些测试应该是(而且可能确实是)很简单的,但我真的不太确定该如何用Flask和unittest来做到这一点。

4 个回答

-2

你可能想在你的HTML页面中使用Jinja设置,把变量传递到页面上,然后看看是否更新了。

http://flask.pocoo.org/docs/0.11/templating/#jinja-setup

http://jinja.pocoo.org/

举个例子:

flask模板

@app.route('/')                                                                 
def home():                                                                                                                  
    return render_template(                                                     
        'home.html',                                                            
        greetingDictionary = {"greeting": "hello" , "forthoseabouttorock" :"wesaluteyou" }                                       
    )   

html页面

{% for key in greetingDictionary %}
<h1>{{key}}</h1>
<p>{{greetingDictionary[key]}}</p>
{% endfor %}
5

我建议你去看看Flask的测试文档

按照文档的指导,你应该能设置一个测试案例,用来检查响应的内容。

import unittest
import yourappname

class MyAppTestCase(unittest.TestCase):
    def setUp(self):
        self.app = yourappname.app.test_client()

    def test_greeting(self):
        rv = self.app.get('/')
        self.assertIn('hello', rv.data)

这里的yourappname是你应用或项目的名字。

18

Flask的官方文档建议你使用template_rendered信号 (自0.6版本起可用)来对你的模板和渲染时使用的变量进行单元测试。

举个例子,这里有一个辅助的上下文管理器,可以在单元测试中使用,以确定哪些模板被渲染了,以及传递给模板的变量是什么:

from flask import template_rendered
from contextlib import contextmanager

@contextmanager
def captured_templates(app):
    recorded = []
    def record(sender, template, context, **extra):
        recorded.append((template, context))
    template_rendered.connect(record, app)
    try:
        yield recorded
    finally:
        template_rendered.disconnect(record, app)

现在,这个可以很方便地和测试客户端配合使用:

with captured_templates(app) as templates:
    rv = app.test_client().get('/')
    assert rv.status_code == 200
    assert len(templates) == 1
    template, context = templates[0]
    assert template.name == 'index.html'
    assert len(context['items']) == 10
19

你可以使用 TestCase 里面的 assert_template_used 方法,这个方法是由 flask-testing 提供的。

from flask.ext.testing import TestCase

class MyTest(TestCase):

    def create_app(self):
        return myflaskapp

    def test_greeting(self):
        self.app.get('/')
        self.assert_template_used('hello.html')
        self.assert_context("greeting", "hello")

方法 create_app 需要提供你的 Flask 应用程序。

撰写回答