2016-10-02 7 views
2

Flaskでは、render_templateでJinjaテンプレートに戻された変数をどのようにテストできますか?この例ではフラスコテスト - Jinjaに渡された変数を取り出す方法は?

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

、私はfoo"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" 

どうすればいいですか?

答えて

3

signalsを使用してこれを行うことができます。私はここで、コードsnippitを再現します:ここでは

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

template一部を削除し、イテレータに変換します別の実装です。

 
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) 
0

そのような何かを使用することで最良の方法:

self.assertTrue('Hello bar!' in r.body) 

そしてfoo.html中:もちろん

<div>Hello {{ foo }}!</div> 

を私はあなたのhtmlの構造を知らないので、この例では、上記でありますちょうどプロトタイプ。

+0

単語「バー」は 'foo'は「バー」 –

+0

編集以外に設定された場合でも、HTMLのどこにもレンダリングされた場合、これは偽陽性を返します。すべては用途に依存します。もちろん、それを達成するために多くのトリックを使うことができますが、単純にすることができれば、それはなぜですか? – turkus

+0

私はあなたの意見を見ます。私が投稿した回答は、醜いもので、合計で12行あり、それがどのように動作するかを知るためには、信号のドキュメントを読む必要があります。あなたのものは1つのライナーです。私はあなたの答えがバックエンドの単体テストにビューを結合していると主張していると思います。たとえば、将来あなたが "hello"から "hi"に変更された場合は、テストでも同様に行う必要があります。 –

関連する問題