Flask Testing - How to retrieve variables that were passed to Jinja?
<p>In Flask, how can I test what variables were returned to a Jinja template with <code>render_template</code>?</p>

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

<p>In this example, I want to test that <code>foo</code> is equal to <code>"bar"</code>. </p>

<pre><code>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"
</code></pre>

<p>How can I do this?</p>

<p>This can be done using <a href="http://flask.pocoo.org/docs/0.11/signals/" rel="nofollow">signals</a>. I will reproduce the code snippit here:</p>

<pre>
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')
</pre>

<hr>

<p>Here is another implementation that removes the <code>template</code> part and turns it into an iterator.</p>

<pre>
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)
</pre>

python flask