2014-11-14 11 views
7

Próbuję nauczyć się testowania jednostek za pomocą Google App Engine, korzystając z dokładnego kodu umieszczonego na stronie Testowanie jednostki lokalnej w języku Python (https://cloud.google.com/appengine/docs/python/tools/localunittesting). Nie mogę dowiedzieć się tego błędu, ale:Testowanie urządzenia App Engine: ImportError: Katalog startowy nie podlega importowaniu.

ImportError: Start directory is not importable: 'testmem.py' 

Ja tylko używając ich proste ramy testowania jako testrunner.py i ich magazynu danych i testach Memcache w pliku o nazwie testmem.py. Wzywam test z katalogu głównego projektu, jak:

<me>$ python testrunner.py ~/google_appengine testmem.py 

ten pasuje do wykorzystania w miarę mogę powiedzieć:% prog SDK_PATH TEST_PATH.

Moja struktura pliku jest:

__init__.py 
app.yaml 
testrunner.py 
testmem.py 
helloworld.py 

ktoś może mi powiedzieć co robię źle tutaj? Z góry dziękuję.

Kompletny komunikat o błędzie:

Traceback (most recent call last): 
    File "testrunner.py", line 30, in <module> 
    main(SDK_PATH, TEST_PATH) 
    File "testrunner.py", line 17, in main 
    suite = unittest.loader.TestLoader().discover(test_path) 
    File "/usr/lib/python2.7/unittest/loader.py", line 204, in discover 
    raise ImportError('Start directory is not importable: %r' % start_dir) 
ImportError: Start directory is not importable: 'testmem.py' 

testrunner.py:

#!/usr/bin/python 
import optparse 
import sys 
import unittest 

USAGE = """%prog SDK_PATH TEST_PATH 
Run unit tests for App Engine apps. 

SDK_PATH Path to the SDK installation 
TEST_PATH Path to package containing test modules""" 


def main(sdk_path, test_path): 
    sys.path.insert(0, sdk_path) 
    import dev_appserver 
    dev_appserver.fix_sys_path() 
    suite = unittest.loader.TestLoader().discover(test_path) 
    unittest.TextTestRunner(verbosity=2).run(suite) 


if __name__ == '__main__': 
    parser = optparse.OptionParser(USAGE) 
    options, args = parser.parse_args() 
    if len(args) != 2: 
     print 'Error: Exactly 2 arguments required.' 
     parser.print_help() 
     sys.exit(1) 
    SDK_PATH = args[0] 
    TEST_PATH = args[1] 
    main(SDK_PATH, TEST_PATH) 

testmem.py:

import unittest 
from google.appengine.api import memcache 
from google.appengine.ext import db 
from google.appengine.ext import testbed 

class TestModel(db.Model): 
    """A model class used for testing.""" 
    number = db.IntegerProperty(default=42) 
    text = db.StringProperty() 

class TestEntityGroupRoot(db.Model): 
    """Entity group root""" 
    pass 

def GetEntityViaMemcache(entity_key): 
    """Get entity from memcache if available, from datastore if not.""" 
    entity = memcache.get(entity_key) # @UndefinedVariable 
    if entity is not None: 
     return entity 
    entity = TestModel.get(entity_key) 
    if entity is not None: 
     memcache.set(entity_key, entity) # @UndefinedVariable 
    return entity 

class DemoTestCase(unittest.TestCase): 

    def setUp(self):  
     # First, create an instance of the Testbed class. 
     self.testbed = testbed.Testbed() 
     # Then activate the testbed, which prepares the service stubs for use. 
     self.testbed.activate() 
     # Next, declare which service stubs you want to use. 
     self.testbed.init_datastore_v3_stub() 
     self.testbed.init_memcache_stub() 

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

    def testInsertEntity(self): 
     TestModel().put() 
     self.assertEqual(1, len(TestModel.all().fetch(2))) 

    def testFilterByNumber(self): 
     root = TestEntityGroupRoot(key_name="root") 
     TestModel(parent=root.key()).put() 
     TestModel(number=17, parent=root.key()).put() 
     query = TestModel.all().ancestor(root.key()).filter('number =', 42) 
     results = query.fetch(2) 
     self.assertEqual(1, len(results)) 
     self.assertEqual(42, results[0].number) 

    def testGetEntityViaMemcache(self): 
     entity_key = str(TestModel(number=18).put()) 
     retrieved_entity = GetEntityViaMemcache(entity_key) 
     self.assertNotEqual(None, retrieved_entity) 
     self.assertEqual(18, retrieved_entity.number) 


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

Odpowiedz

8

Tutaj "ścieżka test" powinien być katalogiem, który zawiera testy, które chcesz uruchomić, a nie ścieżkę do pojedynczego modułu. Spróbuj po prostu użyć . jako katalogu (zakładając, że uruchamiasz go z katalogu projektu/aplikacji najwyższego poziomu) i sprawdź, czy to pomaga.

Mój zespół przechowuje nasze testy w oddzielnym katalogu od naszego kodu źródłowego, więc użyjemy ścieżki do naszego katalogu testowego jako drugiego argumentu.

+0

Dziękuję bardzo: to było to. Nie było dla mnie intuicyjne, że testrunner przejdzie przez cały katalog znajdujący wszystkie moduły z testami; Zakładałem, że muszę być konkretny. To ma sens, dlaczego wszystkie testy powinny znajdować się w ich własnym katalogu. – Mike