Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask Testing - How to retrieve variables that were passed to Jinja?

Tags:

python

flask

In Flask, how can I test what variables were returned to a Jinja template with render_template?

@app.route('/foo/'):
def foo():
    return render_template('foo.html', foo='bar')

In this example, I want to test that foo is equal to "bar".

import unittest
from app import app

class TestFoo(unittest.TestCase):
    def test_foo(self):
        with app.test_client() as c:
            r = c.get('/foo/')
            # Prove that the foo variable is equal to "bar"

How can I do this?

like image 794
Matthew Moisen Avatar asked Oct 02 '16 22:10

Matthew Moisen


1 Answers

This can be done using signals. I will reproduce the code snippit here:

import unittest
from app import app
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)

class TestFoo(unittest.TestCase):
    def test_foo(self):
        with app.test_client() as c:
            with captured_templates(app) as templates:
                r = c.get('/foo/')
                template, context = templates[0]
                self.assertEquals(context['foo'], 'bar')

Here is another implementation that removes the template part and turns it into an iterator.

import unittest
from app import app
from flask import template_rendered
from contextlib import contextmanager

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

class TestFoo(unittest.TestCase):
    def test_foo(self):
        with app.test_client() as c:
            with get_context_variables(app) as contexts:
                r = c.get('/foo/')
                context = next(context)
                self.assertEquals(context['foo'], 'bar')
                
                r = c.get('/foo/?foo=bar')
                context = next(context)
                self.assertEquals(context['foo'], 'foo')
                
                # This will raise a StopIteration exception because I haven't rendered
                # and new templates
                next(context)
like image 74
Matthew Moisen Avatar answered Sep 27 '22 22:09

Matthew Moisen