2016-03-21 15 views
4

Ich versuche, einen Test für das App Engine-Python-Lernprogramm einzurichten. Es scheint, dass die unittest.tearDown() nicht aufgerufen wird, da die print-Anweisung, die ich in die Methode tearDown eingab, nicht angezeigt wird.Warum ruft das App Engine-Projekt unittest.TestCase.tearDown() nicht auf?

Die unittest.TestCase.setUp() wird aufgerufen, also warum wird die tearDown() nicht aufgerufen? Hier

import sys, os, subprocess, time, unittest, shlex  
sys.path.append("/usr/local/google_appengine") 
sys.path.append('/usr/local/google_appengine/lib/')  
sys.path.append("/usr/local/google_appengine/lib/yaml/lib")  
sys.path.append("/usr/local/google_appengine/lib/webapp2-2.5.2")  
sys.path.append("/usr/local/google_appengine/lib/django-1.5")  
sys.path.append("/usr/local/google_appengine/lib/cherrypy")  
sys.path.append("/usr/local/google_appengine/lib/concurrent")  
sys.path.append("/usr/local/google_appengine/lib/docker")  
sys.path.append("/usr/local/google_appengine/lib/requests")  
sys.path.append("/usr/local/google_appengine/lib/websocket")  
sys.path.append("/usr/local/google_appengine/lib/fancy_urllib")  
sys.path.append("/usr/local/google_appengine/lib/antlr3")  

from selenium import webdriver  
from selenium.webdriver.common.keys import Keys 

from google.appengine.api import memcache, apiproxy_stub, apiproxy_stub_map  
from google.appengine.ext import testbed  
from google.appengine.datastore import datastore_stub_util  
from google.appengine.tools.devappserver2 import devappserver2  
from guestbook import Author, Greeting  
from google.appengine.api import users 
from google.appengine.ext import ndb 


class NewVisitorTest(unittest.TestCase):  
    # enable the datastore stub 
    nosegae_datastore_v3 = True 
    nosegae_datastore_v3_kwargs = { 
     'datastore_file': '/tmp/nosegae.sqlite3', 
     'use_sqlite': True 
    } 

    def setUp(self):  
     self.testbed = testbed.Testbed() 
     self.testbed.setup_env(app_id='guestbook')  
     self.testbed.activate()   
     self.datastore_stub = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')  
     ndb.get_context().clear_cache()  
     APP_CONFIGS = ['app.yaml']  

    def tearDown(self): 
     print("#####################functional_tests.teardown called") 
     self.testbed.deactivate() 
     # I put a print statement into testbed.deactivate and it's not showing up.  
     ndb.get_context().clear_cache()  

    def loginUser(self, email="[email protected]", id='888', is_admin=False): 
     self.testbed.setup_env( 
      user_email=email, 
      user_id=id, 
      user_is_admin='1' if is_admin else '0', 
      overwrite=True 
     ) 
     self.testbed.init_user_stub() 

    def test_guest_can_submit_new_greeting_and_author(self): 

     #self.browser.get('http://localhost:8080') 
     self.loginUser() 
     greetings = Greeting.query(Greeting.author.email=='[email protected]').get() 
     pprint.pprint(greetings) 
     assert(Greeting.query(Greeting.author.email=='[email protected]').get() 
self.assertEqual(1, len(Greeting.query().fetch(10))) 

    def test_entity_saves(self): 
     self.loginUser()    
     entity_key = Greeting(content="Test Value", 
          author = Author( 
            identity=users.get_current_user().user_id(), 
            email=users.get_current_user().email()) 
          ).put() 
     print(entity_key) 
     self.assertIsNotNone(entity_key.id())  
     #self.assertNotNone(entity.key.id()) 

ist die Ausgabe aus den Tests:

nosetests -v --with-GAE

test_entity_saves (functional_tests.NewVisitorTest) ... ok 
test_guest_can_submit_new_greeting_and_author (functional_tests.NewVisitorTest) ... FAIL 

====================================================================== 
FAIL: test_guest_can_submit_new_greeting_and_author (functional_tests.NewVisitorTest) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/Users/Bryan/work/GoogleAppEngine/guestbook/functional_tests.py", line 124, in test_guest_can_submit_new_greeting_and_author 
    self.assertEqual(1, len(Greeting.query().fetch(10))) 
AssertionError: 1 != 10 
-------------------- >> begin captured stdout << --------------------- 
#*#**#*#*#*#*#*#*#*#*nosegae.py startTest 
Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460)) 

--------------------- >> end captured stdout << ---------------------- 
-------------------- >> begin captured logging << -------------------- 
root: DEBUG: all_pending: add <Future 106a2e690 created by get_async(query.py:1245) for tasklet _get_async(query.py:1247); pending> 
root: DEBUG: Clearing stale EventLoop instance... 
root: DEBUG: current = deque([(<bound method AutoBatcher._finished_callback of AutoBatcher(_memcache_del_tasklet)>, (<Future 1069e9650 created by run_queue(context.py:185) for tasklet _memcache_del_tasklet(context.py:1131); result None>, [(<Future 1069e9590 created by add(context.py:211) for AutoBatcher(_memcache_del_tasklet).add(NDB9:ag1kZXZ-Z3Vlc3Rib29rcg8LEghHcmVldGluZxjhXQw, (0, '', None)); result 1>, 'NDB9:ag1kZXZ-Z3Vlc3Rib29rcg8LEghHcmVldGluZxjhXQw')]), {})]) 
root: DEBUG: Cleared 
root: DEBUG: nowevent: _help_tasklet_along 
root: DEBUG: Sending None to initial generator _get_async(query.py:1247) 
root: DEBUG: all_pending: add <Future 106a2e850 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); pending> 
root: DEBUG: initial generator _get_async(query.py:1247) yielded <Future 106a2e850 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); pending> 
root: DEBUG: <Future 106a2e690 created by get_async(query.py:1245) for tasklet _get_async(query.py:1247) suspended generator _get_async(query.py:1250); pending> is now blocked waiting for <Future 106a2e850 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); pending> 
root: DEBUG: nowevent: _help_tasklet_along 
root: DEBUG: Sending None to initial generator _run_to_list(query.py:971) 
root: DEBUG: initial generator _run_to_list(query.py:971) yielded <google.appengine.api.apiproxy_stub_map.UserRPC object at 0x106a2ed50> 
root: DEBUG: rpc: datastore_v3.RunQuery 
root: DEBUG: Sending <google.appengine.datastore.datastore_query.Batch object at 0x106a2ec50> to suspended generator _run_to_list(query.py:979) 
root: DEBUG: suspended generator _run_to_list(query.py:979) returned [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))] 
root: DEBUG: all_pending: success: remove <Future 106a2e850 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); result [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))]> 
root: DEBUG: nowevent: _on_future_completion 
root: DEBUG: <Future 106a2e690 created by get_async(query.py:1245) for tasklet _get_async(query.py:1247); pending> is no longer blocked waiting for <Future 106a2e850 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); result [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))]> 
root: DEBUG: Sending [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))] to suspended generator _get_async(query.py:1250) 
root: DEBUG: suspended generator _get_async(query.py:1250) returned Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460)) 
root: DEBUG: all_pending: success: remove <Future 106a2e690 created by get_async(query.py:1245) for tasklet _get_async(query.py:1247); result Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))> 
root: DEBUG: all_pending: add <Future 1069e9ad0 created by get_async(query.py:1245) for tasklet _get_async(query.py:1247); pending> 
root: DEBUG: nowevent: _help_tasklet_along 
root: DEBUG: Sending None to initial generator _get_async(query.py:1247) 
root: DEBUG: all_pending: add <Future 106a2e650 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); pending> 
root: DEBUG: initial generator _get_async(query.py:1247) yielded <Future 106a2e650 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); pending> 
root: DEBUG: <Future 1069e9ad0 created by get_async(query.py:1245) for tasklet _get_async(query.py:1247) suspended generator _get_async(query.py:1250); pending> is now blocked waiting for <Future 106a2e650 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); pending> 
root: DEBUG: nowevent: _help_tasklet_along 
root: DEBUG: Sending None to initial generator _run_to_list(query.py:971) 
root: DEBUG: initial generator _run_to_list(query.py:971) yielded <google.appengine.api.apiproxy_stub_map.UserRPC object at 0x106a2ee50> 
root: DEBUG: rpc: datastore_v3.RunQuery 
root: DEBUG: Sending <google.appengine.datastore.datastore_query.Batch object at 0x106a2ee10> to suspended generator _run_to_list(query.py:979) 
root: DEBUG: suspended generator _run_to_list(query.py:979) returned [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))] 
root: DEBUG: all_pending: success: remove <Future 106a2e650 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); result [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))]> 
root: DEBUG: nowevent: _on_future_completion 
root: DEBUG: <Future 1069e9ad0 created by get_async(query.py:1245) for tasklet _get_async(query.py:1247); pending> is no longer blocked waiting for <Future 106a2e650 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); result [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))]> 
root: DEBUG: Sending [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))] to suspended generator _get_async(query.py:1250) 
root: DEBUG: suspended generator _get_async(query.py:1250) returned Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460)) 
root: DEBUG: all_pending: success: remove <Future 1069e9ad0 created by get_async(query.py:1245) for tasklet _get_async(query.py:1247); result Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460))> 
root: DEBUG: all_pending: add <Future 1069cf8d0 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); pending> 
root: DEBUG: nowevent: _help_tasklet_along 
root: DEBUG: Sending None to initial generator _run_to_list(query.py:971) 
root: DEBUG: initial generator _run_to_list(query.py:971) yielded <google.appengine.api.apiproxy_stub_map.UserRPC object at 0x106a2edd0> 
root: DEBUG: rpc: datastore_v3.RunQuery 
root: DEBUG: Sending <google.appengine.datastore.datastore_query.Batch object at 0x106a2ef10> to suspended generator _run_to_list(query.py:979) 
root: DEBUG: suspended generator _run_to_list(query.py:979) returned [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460)), Greeting(key=Key('Greeting', 1001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 43, 164283)), Greeting(key=Key('Greeting', 2001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 44, 59, 425351)), Greeting(key=Key('Greeting', 3001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 45, 39, 127541)), Greeting(key=Key('Greeting', 4001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 46, 40, 884853)), Greeting(key=Key('Greeting', 5001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 21, 10, 45, 14308)), Greeting(key=Key('Greeting', 6001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 21, 56, 12, 419565)), Greeting(key=Key('Greeting', 7001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 22, 0, 14, 800335)), Greeting(key=Key('Greeting', 8001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 22, 1, 7, 931768)), Greeting(key=Key('Greeting', 9001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 21, 13, 34, 43, 876008))] 
root: DEBUG: all_pending: success: remove <Future 1069cf8d0 created by fetch_async(query.py:1223) for tasklet _run_to_list(query.py:971); result [Greeting(key=Key('Greeting', 1), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 37, 659460)), Greeting(key=Key('Greeting', 1001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 39, 43, 164283)), Greeting(key=Key('Greeting', 2001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 44, 59, 425351)), Greeting(key=Key('Greeting', 3001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 45, 39, 127541)), Greeting(key=Key('Greeting', 4001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 20, 46, 40, 884853)), Greeting(key=Key('Greeting', 5001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 21, 10, 45, 14308)), Greeting(key=Key('Greeting', 6001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 21, 56, 12, 419565)), Greeting(key=Key('Greeting', 7001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 22, 0, 14, 800335)), Greeting(key=Key('Greeting', 8001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 18, 22, 1, 7, 931768)), Greeting(key=Key('Greeting', 9001), author=Author(email=u'[email protected]', identity=u'888'), content=u'Test Value', date=datetime.datetime(2016, 3, 21, 13, 34, 43, 876008))]> 
--------------------- >> end captured logging << --------------------- 

---------------------------------------------------------------------- 
Ran 2 tests in 0.835s 

FAILED (failures=1) 
#

EDIT Richtung Auflösung:
Die Teardown() aufgerufen wurde , die Ausgabe von dem Druck wurde von Nosetests geschluckt.
Das Flag --nocapture stoppt dieses Verhalten.

Die Persistenz der Datenspeicherentitäten in den fehlgeschlagenen Tests rührt von der Tatsache her, dass testbed.deactivate() scheinbar nur den speicherinternen Datenspeicher und nicht die in einer Datei auf der Festplatte gespeicherten Daten löscht.
I definiert hatte ‚datastore_file‘ mit dem Weg zu einer sqlite3 Datenbank, den Staat trotz testbed.deactivate zu halten scheint()

+0

gab es irgendeine Ausnahme im Setup ?. Teardown in nur aufgerufen, wenn Setup erfolgreich ist –

+0

Ich habe nach Ausnahmen gesucht. Wenn sie auftreten, werden sie nicht protokolliert, da ich alle obigen Ausgaben einbezogen habe. Ich habe auch versucht, print Anweisungen im Setup zu platzieren und sie sind protokolliert, so denke ich, dass das Setup ohne Probleme läuft. Wie könnte ich granularer werden? – BryanWheelock

+1

Ihr Test ist fehlgeschlagen bei 'test_guest_can_submit_new_greeting_and_author' oder? Ich war eine Zeitlang nicht in Python-Tests, aber würde "tearDown" aufrufen, da eine Methode auf Klassenebene aufgerufen wird, wenn der Test fehlschlägt, bevor die Klasse beendet wird? – PieOhPah

Antwort

2

Die tearDown Methode aufgerufen wird, aber nosetests die Ausgabe verschlingt.

Hier ist ein minimales Beispiel.

import unittest 


class MyTestCase(unittest.TestCase): 

    def setUp(self): 
     pass 

    def tearDown(self): 
     print 'Calling tearDown' 

    def test_1(self): 
     self.assertTrue(True) 

    def test_2(self): 
     self.assertTrue(False) 

mit der Standardbibliothek Unittest Test runner Genannt, Ausgabe aus dem Druck Anweisung wird für jeden Test gezeigt:

$ python -m unittest tests 
Calling tearDown 
.FCalling tearDown 

====================================================================== 
FAIL: test_2 (tests.MyTestCase) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "tests.py", line 16, in test_2 
    self.assertTrue(False) 
AssertionError: False is not true 

---------------------------------------------------------------------- 
Ran 2 tests in 0.000s 

FAILED (failures=1) 

mit nosetests genannt wird, ist der Ausgang nicht gezeigt:

$ nosetests -v --with-gae --gae-lib-root=$APPENGINE 
test_1 (tests.MyTestCase) ... ok 
test_2 (tests.MyTestCase) ... FAIL 

====================================================================== 
FAIL: test_2 (tests.MyTestCase) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/kev/python_projects/usr/local/bin/python2.7/tests.py", line 16, in test_2 
    self.assertTrue(False) 
AssertionError: False is not true 

---------------------------------------------------------------------- 
Ran 2 tests in 0.268s 

FAILED (failures=1) 

Wenn wir das --nocapture - Flag an nosetests übergeben, wird die Ausgabe der print - Anweisung angezeigt:

$ nosetests -v --nocapture --with-gae --gae-lib-root=$APPENGINE 
test_1 (tests.MyTestCase) ... Calling tearDown 
ok 
test_2 (tests.MyTestCase) ... FAIL 
Calling tearDown 

====================================================================== 
FAIL: test_2 (tests.MyTestCase) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/kev/python_projects/usr/local/bin/python2.7/tests.py", line 16, in test_2 
    self.assertTrue(False) 
AssertionError: False is not true 

---------------------------------------------------------------------- 
Ran 2 tests in 0.265s 

FAILED (failures=1) 

Die --nocapture Option wird bei http://nose.readthedocs.org/en/latest/plugins/capture.html

+0

--no-capture zeigt die Druckanweisungen, die zuvor ausgeblendet wurden. Sieht so aus, als ob teardown() aufgerufen wird, aber aus irgendeinem Grund die Datenbank nicht löscht. – BryanWheelock

+1

@BryanWheelock Ich kann nicht mit Sicherheit sagen, aber es sieht so aus, als wäre Ihr Code eine Mischung aus dem "untestest" -Ansatz zum Testen in den GAE-Dokumenten und der Beschreibung in den Nosegae-Dokumenten, wo es keine Aufrufe von setUp/tearDown gibt . Wenn Sie bei nosegae bleiben wollen, würde ich vorschlagen, http://pythonhosted.org/NoseGAE/#configuring-the-testbed zu betrachten und ihrem Beispielcode näher zu folgen. – snakecharmerb

+0

Danke für den Link. Ich habe es schwer gehabt, einen Beispielcode außerhalb der Dokumentation zu finden https://cloud.google.com/appengine/docs – BryanWheelock

2

-Code vorhanden beschrieben nicht mit Ausgabe überein. Nach Ausgabe fehlgeschlagenen Test test_guest_can_submit_new_greeting_and_author ist und ein Fehler folgt:

Traceback (most recent call last): 
     File "/Users/Bryan/work/GoogleAppEngine/guestbook/functional_tests.py", line 124, in test_guest_can_submit_new_greeting_and_author 
     self.assertEqual(1, len(Greeting.query().fetch(10))) 
    AssertionError: 1 != 10 

Aber test_guest_can_submit_new_greeting_and_author enthält nicht gezeigt Behauptung:

def test_guest_can_submit_new_greeting_and_author(self): 

    #self.browser.get('http://localhost:8080') 
    self.loginUser() 
    greetings = Greeting.query(Greeting.author.email=='[email protected]').get() 
    pprint.pprint(greetings) 
    assert(Greeting.query(Greeting.author.email=='[email protected]').get()) 

aussieht wie du andere Version von Datei mit Tests auszuführen.

+0

Gutes Auge. Ich hatte eine Reihe von Kommentaren zu meinem Code, die ich gelöscht und versehentlich gelöscht habe: self.assertEqual (1, len (Greeting.query(). Fetch (10))) – BryanWheelock

Verwandte Themen