2015-05-11 11 views
8

Sto cercando di capire come impostare lo sviluppo Test Driven per GAE.Come faccio a ricevere "InternalError: table" dev ~ guestbook !! Le entità "esistono già" quando ho appena creato il datastore?

avvio il test con:

nosetests -v --with-gae 

continuo a ricevere l'errore:

InternalError: table "dev~guestbook!!Entities" already exists 

Il datastore non esiste finché non mi creo nel setup(), ma sono riscontri ancora un errore che le entità esistono già?

Sto usando il codice dallo GAE tutorial.

Ecco il mio codice di prova in functional_tests.py:

import sys, os, subprocess, time, unittest, shlex 
sys.path.append("/usr/local/google_appengine")  
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 google.appengine.api import memcache, apiproxy_stub, apiproxy_stub_map 
from google.appengine.ext import db  
from google.appengine.ext import testbed  
from google.appengine.datastore import datastore_stub_util  
from google.appengine.tools.devappserver2 import devappserver2  


class NewVisitorTest(unittest.TestCase):  

    def setUp(self):  
     # Start the dev server 
     cmd = "/usr/local/bin/dev_appserver.py /Users/Bryan/work/GoogleAppEngine/guestbook/app.yaml --port 8080 --storage_path /tmp/datastore --clear_datastore --skip_sdk_update_check" 
     self.dev_appserver = subprocess.Popen(shlex.split(cmd), 
               stdout=subprocess.PIPE) 
     time.sleep(2) # Important, let dev_appserver start up 

     self.testbed = testbed.Testbed() 
     self.testbed.setup_env(app_id='dermal')  
     self.testbed.activate()  

     self.testbed.init_user_stub()  
     # Create a consistency policy that will simulate the High Replication consistency model. 
     # with a probability of 1, the datastore should be available. 
     self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=1) 
     # Initialize the datastore stub with this policy. 
     self.testbed.init_datastore_v3_stub(datastore_file="/tmp/datastore/datastore.db", use_sqlite=True, consistency_policy=self.policy)  
     self.testbed.init_memcache_stub()  
     self.datastore_stub = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')    
     # setup the dev_appserver  
     APP_CONFIGS = ['app.yaml']  

     # setup client to make sure 
     from guestbook import Author, Greeting 
     if not (Author.query(Author.email == "[email protected]").get()): 
      logging.info("create Admin") 
      client = Author( 
      email = "[email protected]", 
      ).put() 
      Assert(Author.query(Author.email == "[email protected]").get()) 
     self.browser = webdriver.Firefox()  
     self.browser.implicitly_wait(3)  

    def tearDown(self):  
     self.browser.quit()  
     self.testbed.deactivate()  
     self.dev_appserver.terminate() 

    def test_submit_anon_greeting(self): 
      self.browser.get('http://localhost:8080') 
      self.browser.find_element_by_name('content').send_keys('Anonymous test post') 
      self.browser.find_element_by_name('submit').submit() 
      Assert.assertEquals(driver.getPageSource().contains('Anonymous test post')) 

Ecco il traceback:

test_submit_anon_greeting (functional_tests.NewVisitorTest) ... INFO  2015-05-11 14:41:40,516 devappserver2.py:745] Skipping SDK update check. 
INFO  2015-05-11 14:41:40,594 api_server.py:190] Starting API server at: http://localhost:59656 
INFO  2015-05-11 14:41:40,598 dispatcher.py:192] Starting module "default" running at: http://localhost:8080 
INFO  2015-05-11 14:41:40,600 admin_server.py:118] Starting admin server at: http://localhost:8000 
WARNING 2015-05-11 14:41:45,008 tasklets.py:409] suspended generator _run_to_list(query.py:964) raised InternalError(table "dev~guestbook!!Entities" already exists) 
ERROR 2015-05-11 14:41:45,009 webapp2.py:1552] table "dev~guestbook!!Entities" already exists 
Traceback (most recent call last): 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__ 
    rv = self.handle_exception(request, response, e) 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__ 
    rv = self.router.dispatch(request, response) 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher 
    return route.handler_adapter(request, response) 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__ 
    return handler.dispatch() 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch 
    return self.handle_exception(e, self.app.debug) 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch 
    return method(*args, **kwargs) 
    File "/Users/Bryan/work/GoogleAppEngine/guestbook/guestbook.py", line 50, in get 
    greetings = greetings_query.fetch(10) 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/utils.py", line 142, in positional_wrapper 
    return wrapped(*args, **kwds) 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/query.py", line 1187, in fetch 
    return self.fetch_async(limit, **q_options).get_result() 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 325, in get_result 
    self.check_success() 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along 
    value = gen.throw(exc.__class__, exc, tb) 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/query.py", line 964, in _run_to_list 
    batch = yield rpc 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 454, in _on_rpc_completion 
    result = rpc.get_result() 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result 
    return self.__get_result_hook(self) 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_query.py", line 2870, in __query_result_hook 
    self._batch_shared.conn.check_rpc_success(rpc) 
    File "/Users/Bryan/Desktop/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1342, in check_rpc_success 
    raise _ToDatastoreError(err) 
InternalError: table "dev~guestbook!!Entities" already exists 

risposta

5

Sembra che ci sono un paio di cose che accadono qui.

In primo luogo, sembra che si stia utilizzando NoseGAE --with-gae. Il plugin gestisce la configurazione e lo smontaggio del banco di prova in modo da non doverlo fare. Ciò significa che non è necessario alcuno dei codici self.testbed e che in realtà può causare conflitti interni. Passare alla modalità NoseGAE o non utilizzare il flag --with-gae. Se si configura con NoseGAE, ha un'opzione --gae-datastore che consente di impostare il percorso per il datastore che verrà utilizzato per i test. Poi all'interno della vostra classe di test, impostare la proprietà nosegae_datastore_v3 = True di averlo impostato per voi:

class NewVisitorTest(unittest.TestCase): 
    # enable the datastore stub 
    nosegae_datastore_v3 = True 

In secondo luogo, il modo in cui dev_appserver lavoro/sqlite insieme, l'appserver carica il file sqlite db in memoria e funziona con esso ci . Quando il server dell'app si chiude, scarica nuovamente il contenuto del database su disco. Poiché si sta utilizzando lo stesso archivio dati per i test del processo dev_appserver.py che si sta aprendo per il selenio, potrebbero o non potrebbero vedere i dati della fixture impostati nel test.

Ecco un esempio da https://github.com/Trii/NoseGAE/blob/master/nosegae.py#L124-L140

class MyTest(unittest.TestCase): 
    nosegae_datastore_v3 = True 
    nosegae_datastore_v3_kwargs = { 
     'datastore_file': '/tmp/nosegae.sqlite3', 
     'use_sqlite': True 
    } 
    def test_something(self): 
     entity = MyModel(name='NoseGAE') 
     entity.put() 
     self.assertNotNone(entity.key.id()) 
+1

ho tentato di messa a punto in quanto sono al di sopra, in modo che il file di archivio dati utilizzato è:/tmp/nosegae.sqlite3 – BryanWheelock

+1

Ha gettato: nosetests: errore: l'opzione --gae-datastore richiede un argomento – BryanWheelock

+1

Perché dovrebbe farlo se il percorso è stato impostato in setUp? – BryanWheelock

2

Credo che questa linea potrebbe essere il guasto uno:

self.testbed.init_datastore_v3_stub(datastore_file="/tmp/datastore/datastore.db", use_sqlite=True, consistency_policy=self.policy) 

Impostazione di datastore_file = "/ tmp/datastore/datastore.db" indica che si desidera riutilizzare questo datastore esistente nei test

La documentazione codice Python dice:

The 'datastore_file' argument can be the path to an existing datastore file, or None (default) to use an in-memory datastore that is initially empty.

Personalmente io uso questi nel mio test:

def setUp(self): 
    self.testbed = testbed.Testbed() 
    self.testbed.activate() 
    self.testbed.init_datastore_v3_stub(
     consistency_policy=datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=0) 
    ) 
    self.testbed.init_memcache_stub() 

def tearDown(self): 
    self.testbed.deactivate() 
+1

Commentando init_datastore_v3_stub getta: – BryanWheelock

+1

AssertionError: Nessun proxy api trovato per il servizio "datastore_v3" – BryanWheelock

Problemi correlati