2016-10-02 20 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完成。我將在這裏重現代碼片段:

 
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

這將返回誤報,如果在HTML被渲染詞「欄」其他地方,即使'foo'被設置爲「欄中的」編輯 –

+0

以外的東西。一切都取決於使用。當然,我們可以使用很多技巧來完成它,但如果我們可以簡單地做到這一點,那爲什麼不呢? – turkus

+0

我明白你的觀點。我發佈的答案很難看,總共有12行,並且需要閱讀信號文檔以瞭解其工作原理;而你的是一個班輪。我想我會爭辯說,你的答案是將視圖耦合到後端單元測試;例如,如果將來您將「hello」改爲「hi」,那麼您必須記得在測試中也這樣做。 –