2012-05-10 15 views
10

Nigdy wcześniej nie testowałem jednostki. Chcę to opanować.sposób na unieważnienie zmiennych szablonu przekazanych do szablonu jinja2 z programu obsługi żądań webapp2

Próbuję przetestować moje programy obsługi webapp2. Aby to zrobić, myślałem, że będzie to dobry pomysł, aby wysłać wniosek do np Handler:

request = webapp2.Request.blank('/') 
# Get a response for that request. 
response = request.get_response(main.app) 

Problem polega na tym, odpowiedź jest przeważnie tylko kilka HTML itp

chcę patrzeć na temat tego, co zostało przekazane do mojego szablonu jinja2 z programu obsługi przed przekształceniem go w HTML.

Chcę, aby mój test uzyskał stan w ramach kodu klasy obsługi. Nie będę w stanie zobaczyć, jak pewne zmienne wyglądają w module obsługi odpowiedzi, a następnie chcę zobaczyć, jak wyglądają szablony Dict, zanim zostały przekazane do render_to_response()

Chcę przetestować te zmienne prawidłowe wartości.

Oto mój kod testowy do tej pory, ale utknąłem, ponieważ response = request.get_response() po prostu daje mi kilka html, a nie surowe zmienne.

import unittest 
#from google.appengine.ext import db 
#from google.appengine.ext import testbed 
#from google.appengine.datastore import datastore_stub_util 
import main 
import webapp2 

class DemoTestCase(unittest.TestCase): 
    def setUp(self): 
     pass 

    def tearDown(self): 
     pass 

    def testNothing(self): 
     self.assertEqual(42, 21 + 21) 

    def testHomeHandler(self): 
     # Build a request object passing the URI path to be tested. 
     # You can also pass headers, query arguments etc. 
     request = webapp2.Request.blank('/') 
     # Get a response for that request. 
     response = request.get_response(main.app) 

     # Let's check if the response is correct. 
     self.assertEqual(response.status_int, 200) 
     self.assertEqual(response.body, 'Hello, world!') 


if __name__ == '__main__': 
    unittest.main() 

i tu jest moje obsługi:

class HomeHandler(BaseHandler): 
    def get(self, file_name_filter=None, category_filter=None): 
     file_names = os.listdir('blog_posts') 
     blogs = [] 

     get_line = lambda file_: file_.readline().strip().replace("<!--","").replace("-->","") 

     for fn in file_names: 
      with open('blog_posts/%s' % fn) as file_: 
       heading = get_line(file_) 
       link_name = get_line(file_) 
       category = get_line(file_) 

      date_ = datetime.strptime(fn.split("_")[0], "%Y%m%d") 

      blog_dict = {'date': date_, 'heading': heading, 
         'link_name': link_name, 
         'category': category, 
         'filename': fn.replace(".html", ""), 
         'raw_file_name': fn} 

      blogs.append(blog_dict) 

     categories = Counter(d['category'] for d in blogs) 
     templates = {'categories': categories, 
        'blogs': blogs, 
        'file_name_filter': file_name_filter, 
        'category_filter': category_filter} 

     assert(len(file_names) == len(set(d['link_name'] for d in blogs))) 

     self.render_template('home.html', **templates) 

i tu jest moje basehandler:

class BaseHandler(webapp2.RequestHandler): 
    @webapp2.cached_property 
    def jinja2(self): 
     return jinja2.get_jinja2(app=self.app) 

    def render_template(self, filename, **kwargs): 
     #kwargs.update({}) 
     #TODO() datastore caching here for caching of (handlername, handler parameters, changeable parameters, app_upload_date) 
     #TODO() write rendered page to its own html file, and just serve that whole file. (includes all posts). JQuery can show/hide posts. 
     self.response.write(self.jinja2.render_template(filename, **kwargs)) 

Może mam zły pomysł jak zrobić testy jednostkowe, czy może ja powinienem napisać mój kod w sposób, który ułatwia testowanie? czy jest jakiś sposób na uzyskanie stanu mojego kodu?

Także jeśli ktoś do ponownego pisania kodu i zmienić nazwy zmiennych, a następnie testy złamie ..

prosimy o poinformowanie o mojej sytuacji: X

Odpowiedz

6

Można kpić BaseHandler.render_template metody i przetestować jego parametry.

Aby uzyskać listę popularnych szyderczych frameworków Pythona, zobacz this question.

5

Dzięki sugestii proppy skończyło się na tym, że użyłem makiety.

http://www.voidspace.org.uk/python/mock/

(mock jest zawarty jako część lub unittest.mock w python 3)

Więc tutaj jest mój main.py kod, który jest podobny do tego, co mam w webapp2:

uwaga zamiast BaseHandler.render_template mam BaseHandler.say_yo

__author__ = 'Robert' 

print "hello from main" 

class BaseHandler(): 
    def say_yo(self,some_number=99): 
     print "yo" 
     return "sup" 

class TheHandler(BaseHandler): 
    def get(self, my_number=42): 
     print "in TheHandler's get()" 
     print self.say_yo(my_number) 
     return "TheHandler's return string" 

i atest.py:

__author__ = 'Robert' 

import unittest 
import main 
from mock import patch 

class DemoTestCase(unittest.TestCase): 
    def setUp(self): 
     pass 

    def tearDown(self): 
     pass 

    def testNothing(self): 
     self.assertEqual(42, 21 + 21) 

    def testSomeRequests(self): 
     print "hi" 
     bh = main.BaseHandler() 
     print bh.say_yo() 

     print "1111111" 

     with patch('main.BaseHandler.say_yo') as patched_bh: 
      print dir(patched_bh) 
      patched_bh.return_value = 'double_sup' 
      bh2 = main.BaseHandler() 
      print bh2.say_yo() 
      print "222222" 

     bh3 = main.BaseHandler() 
     print bh3.say_yo() 

     print "3333" 

     th = main.TheHandler() 
     print th.get() 

     print "44444" 
     with patch('main.BaseHandler.say_yo') as patched_bh: 
      patched_bh.return_value = 'last_sup' 
      th = main.TheHandler() 
      print th.get() 
      print th.get(123) 
      print "---" 
      print patched_bh.called 
      print patched_bh.call_args_list 
      print "555555" 



if __name__ == '__main__': 
    unittest.main() 

kod ten daje dużo mocy, oto próbka:

44444 
in TheHandler's get() 
last_sup 
TheHandler's return string 
in TheHandler's get() 
last_sup 
TheHandler's return string 
--- 
True 
[call(42), call(123)] 
555555 
Powiązane problemy