From dbd03b5341571db3102752b08667ee68bcd27ab6 Mon Sep 17 00:00:00 2001 From: Jon Wayne Parrott Date: Mon, 14 Sep 2015 14:10:29 -0700 Subject: [PATCH] Switching app engine tests to webtest and consolidating testing utils into AppEngineTestbedCase --- .../bigquery/tests/test_appengine_auth.py | 32 ++++----------- appengine/images/tests/test_guestbook.py | 41 ++++++------------- .../guestbook/tests/test_guestbook.py | 13 +++--- .../tests/test_contact_with_group_models.py | 6 +-- .../modeling/tests/test_keyproperty_models.py | 5 +-- .../ndb/modeling/tests/test_naive_models.py | 5 +-- .../tests/test_parent_child_models.py | 6 +-- .../tests/test_relation_model_models.py | 6 +-- .../tests/test_structured_property_models.py | 5 +-- appengine/ndb/overview/tests/test_overview.py | 15 +++---- .../transactions/tests/test_transactions.py | 6 +-- tests/__init__.py | 4 +- tests/utils.py | 18 +++++++- tox.ini | 1 + 14 files changed, 63 insertions(+), 100 deletions(-) diff --git a/appengine/bigquery/tests/test_appengine_auth.py b/appengine/bigquery/tests/test_appengine_auth.py index 59669166959a..c8206c2cbb02 100644 --- a/appengine/bigquery/tests/test_appengine_auth.py +++ b/appengine/bigquery/tests/test_appengine_auth.py @@ -16,34 +16,20 @@ import re from apiclient.http import HttpMock - from appengine.bigquery import main - import mock - import tests - -import webapp2 +import webtest -class TestAuthSample(tests.DatastoreTestbedCase, tests.CloudBaseTest): +class TestAuthSample(tests.AppEngineTestbedCase): def setUp(self): - tests.DatastoreTestbedCase.setUp(self) - tests.CloudBaseTest.setUp(self) - - self.testbed.init_user_stub() - - def loginUser(self, email='user@example.com', id='123', is_admin=False): - self.testbed.setup_env( - user_email=email, - user_id=id, - user_is_admin='1' if is_admin else '0', - overwrite=True) + super(TestAuthSample, self).setUp() + self.app = webtest.TestApp(main.app) def test_anonymous_get(self): - request = webapp2.Request.blank('/') - response = request.get_response(main.app) + response = self.app.get('/') # Should redirect to login self.assertEqual(response.status_int, 302) @@ -53,8 +39,7 @@ def test_anonymous_get(self): def test_loggedin_get(self): self.loginUser() - request = webapp2.Request.blank('/') - response = request.get_response(main.app) + response = self.app.get('/') # Should redirect to login self.assertEqual(response.status_int, 302) @@ -64,16 +49,15 @@ def test_loggedin_get(self): def test_oauthed_get(self, *args): self.loginUser() - request = webapp2.Request.blank('/') - mock_http = HttpMock( os.path.join(self.resource_path, 'datasets-list.json'), {'status': '200'}) + with mock.patch.object(main.decorator, 'http', return_value=mock_http): original_projectid = main.PROJECTID try: main.PROJECTID = self.constants['projectId'] - response = request.get_response(main.app) + response = self.app.get('/') finally: main.PROJECTID = original_projectid diff --git a/appengine/images/tests/test_guestbook.py b/appengine/images/tests/test_guestbook.py index dd07ca79f8c1..b13e42f1c49f 100644 --- a/appengine/images/tests/test_guestbook.py +++ b/appengine/images/tests/test_guestbook.py @@ -15,18 +15,19 @@ # from the app main.py from appengine.images import main import mock -from tests import DatastoreTestbedCase +from tests import AppEngineTestbedCase +import webtest -import webapp2 - -class TestHandlers(DatastoreTestbedCase): +class TestHandlers(AppEngineTestbedCase): def setUp(self): super(TestHandlers, self).setUp() # Workaround for other tests clobbering our Greeting model. reload(main) + self.app = webtest.TestApp(main.app) + def test_get(self): main.Greeting( parent=main.guestbook_key('default_guestbook'), @@ -34,11 +35,7 @@ def test_get(self): content='abc' ).put() - # 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) + response = self.app.get('/') # Let's check if the response is correct. self.assertEqual(response.status_int, 200) @@ -46,11 +43,8 @@ def test_get(self): @mock.patch('appengine.images.main.images') def test_post(self, mock_images): mock_images.resize.return_value = 'asdf' - request = webapp2.Request.blank( - '/sign', - POST={'content': 'asdf'}, - ) - response = request.get_response(main.app) + + response = self.app.post('/sign', {'content': 'asdf'}) mock_images.resize.assert_called_once_with(mock.ANY, 32, 32) # Correct response is a redirect @@ -66,30 +60,19 @@ def test_img(self): greeting.avatar = b'123' greeting.put() - request = webapp2.Request.blank( - '/img?img_id=%s' % greeting.key.urlsafe() - ) - response = request.get_response(main.app) + response = self.app.get('/img?img_id=%s' % greeting.key.urlsafe()) self.assertEqual(response.status_int, 200) def test_img_missing(self): # Bogus image id, should get error - request = webapp2.Request.blank('/img?img_id=123') - response = request.get_response(main.app) - - self.assertEqual(response.status_int, 500) + self.app.get('/img?img_id=123', status=500) @mock.patch('appengine.images.main.images') def test_post_and_get(self, mock_images): mock_images.resize.return_value = 'asdf' - request = webapp2.Request.blank( - '/sign', - POST={'content': 'asdf'}, - ) - response = request.get_response(main.app) - request = webapp2.Request.blank('/') - response = request.get_response(main.app) + self.app.post('/sign', {'content': 'asdf'}) + response = self.app.get('/') self.assertEqual(response.status_int, 200) diff --git a/appengine/memcache/guestbook/tests/test_guestbook.py b/appengine/memcache/guestbook/tests/test_guestbook.py index b9747929d070..eedfc8ed47b8 100644 --- a/appengine/memcache/guestbook/tests/test_guestbook.py +++ b/appengine/memcache/guestbook/tests/test_guestbook.py @@ -14,18 +14,15 @@ # from the app main.py from appengine.memcache.guestbook import main -from tests import DatastoreTestbedCase +from tests import AppEngineTestbedCase +import webtest -import webapp2 +class TestHandlers(AppEngineTestbedCase): -class TestHandlers(DatastoreTestbedCase): def test_hello(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) + app = webtest.TestApp(main.app) + response = app.get('/') # Let's check if the response is correct. self.assertEqual(response.status_int, 200) diff --git a/appengine/ndb/modeling/tests/test_contact_with_group_models.py b/appengine/ndb/modeling/tests/test_contact_with_group_models.py index b20e6b8485ac..517bb56e0e34 100644 --- a/appengine/ndb/modeling/tests/test_contact_with_group_models.py +++ b/appengine/ndb/modeling/tests/test_contact_with_group_models.py @@ -15,13 +15,11 @@ """Test classes for code snippet for modeling article.""" from appengine.ndb.modeling import contact_with_group_models as models - from google.appengine.ext import ndb - -from tests import DatastoreTestbedCase +from tests import AppEngineTestbedCase -class ContactTestCase(DatastoreTestbedCase): +class ContactTestCase(AppEngineTestbedCase): """A test case for the Contact model with groups.""" def setUp(self): """Creates 3 contacts and 1 group. diff --git a/appengine/ndb/modeling/tests/test_keyproperty_models.py b/appengine/ndb/modeling/tests/test_keyproperty_models.py index febee712714d..cb096d0b612e 100644 --- a/appengine/ndb/modeling/tests/test_keyproperty_models.py +++ b/appengine/ndb/modeling/tests/test_keyproperty_models.py @@ -17,11 +17,10 @@ import unittest from appengine.ndb.modeling import keyproperty_models as models +from tests import AppEngineTestbedCase -from tests import DatastoreTestbedCase - -class ContactTestCase(DatastoreTestbedCase): +class ContactTestCase(AppEngineTestbedCase): """A test case for the Contact model class with KeyProperty.""" NAME = 'Takashi Matsuo' diff --git a/appengine/ndb/modeling/tests/test_naive_models.py b/appengine/ndb/modeling/tests/test_naive_models.py index 383a3636540a..60a5109258c8 100644 --- a/appengine/ndb/modeling/tests/test_naive_models.py +++ b/appengine/ndb/modeling/tests/test_naive_models.py @@ -15,11 +15,10 @@ """Test classes for code snippet for modeling article.""" from appengine.ndb.modeling import naive_models as models +from tests import AppEngineTestbedCase -from tests import DatastoreTestbedCase - -class ContactTestCase(DatastoreTestbedCase): +class ContactTestCase(AppEngineTestbedCase): """A test case for the naive Contact model classe.""" NAME = 'Takashi Matsuo' diff --git a/appengine/ndb/modeling/tests/test_parent_child_models.py b/appengine/ndb/modeling/tests/test_parent_child_models.py index 0dcd6b0aba1c..f5710633a934 100644 --- a/appengine/ndb/modeling/tests/test_parent_child_models.py +++ b/appengine/ndb/modeling/tests/test_parent_child_models.py @@ -15,13 +15,11 @@ """Test classes for code snippet for modeling article.""" from appengine.ndb.modeling import parent_child_models as models - from google.appengine.ext import ndb - -from tests import DatastoreTestbedCase +from tests import AppEngineTestbedCase -class ContactTestCase(DatastoreTestbedCase): +class ContactTestCase(AppEngineTestbedCase): """A test case for the Contact model class with KeyProperty.""" NAME = 'Takashi Matsuo' diff --git a/appengine/ndb/modeling/tests/test_relation_model_models.py b/appengine/ndb/modeling/tests/test_relation_model_models.py index d470c113a5d2..5dd324b9b454 100644 --- a/appengine/ndb/modeling/tests/test_relation_model_models.py +++ b/appengine/ndb/modeling/tests/test_relation_model_models.py @@ -15,13 +15,11 @@ """Test classes for code snippet for modeling article.""" from appengine.ndb.modeling import relation_model_models as models - from google.appengine.ext import ndb - -from tests import DatastoreTestbedCase +from tests import AppEngineTestbedCase -class ContactTestCase(DatastoreTestbedCase): +class ContactTestCase(AppEngineTestbedCase): """A test case for the Contact model with relationship model.""" def setUp(self): """Creates 1 contact and 1 company. diff --git a/appengine/ndb/modeling/tests/test_structured_property_models.py b/appengine/ndb/modeling/tests/test_structured_property_models.py index 0869a62611a5..e1c8be50c76c 100644 --- a/appengine/ndb/modeling/tests/test_structured_property_models.py +++ b/appengine/ndb/modeling/tests/test_structured_property_models.py @@ -15,11 +15,10 @@ """Test classes for code snippet for modeling article.""" from appengine.ndb.modeling import structured_property_models as models +from tests import AppEngineTestbedCase -from tests import DatastoreTestbedCase - -class ContactTestCase(DatastoreTestbedCase): +class ContactTestCase(AppEngineTestbedCase): """A test case for the Contact model with StructuredProperty.""" def setUp(self): """Creates one Contact entity with 2 phone numbers.""" diff --git a/appengine/ndb/overview/tests/test_overview.py b/appengine/ndb/overview/tests/test_overview.py index 3b8e6dcc6ad6..2c43dab110f2 100644 --- a/appengine/ndb/overview/tests/test_overview.py +++ b/appengine/ndb/overview/tests/test_overview.py @@ -14,19 +14,14 @@ # from the app main.py from appengine.ndb.overview import main +from tests import AppEngineTestbedCase +import webtest -from tests import DatastoreTestbedCase -import webapp2 - - -class TestHandlers(DatastoreTestbedCase): +class TestHandlers(AppEngineTestbedCase): def test_hello(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) + app = webtest.TestApp(main.app) + response = app.get('/') # Let's check if the response is correct. self.assertEqual(response.status_int, 200) diff --git a/appengine/ndb/transactions/tests/test_transactions.py b/appengine/ndb/transactions/tests/test_transactions.py index de53389fc404..d81637291660 100644 --- a/appengine/ndb/transactions/tests/test_transactions.py +++ b/appengine/ndb/transactions/tests/test_transactions.py @@ -14,14 +14,12 @@ # from the app main.py from appengine.ndb.transactions import main +from tests import AppEngineTestbedCase -from tests import DatastoreTestbedCase - -class TestHandlers(DatastoreTestbedCase): +class TestHandlers(AppEngineTestbedCase): def setUp(self): super(TestHandlers, self).setUp() - self.testbed.init_taskqueue_stub() main.app.config['TESTING'] = True self.app = main.app.test_client() diff --git a/tests/__init__.py b/tests/__init__.py index 2305025918a2..8c68e5c9bd73 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -13,20 +13,20 @@ # from .utils import ( + AppEngineTestbedCase, BUCKET_NAME_ENV, capture_stdout, CloudBaseTest, - DatastoreTestbedCase, mock_input_answers, PROJECT_ID_ENV, RESOURCE_PATH) __all__ = [ + 'AppEngineTestbedCase', 'BUCKET_NAME_ENV', 'capture_stdout', 'CloudBaseTest', - 'DatastoreTestbedCase', 'mock_input_answers', 'PROJECT_ID_ENV', 'RESOURCE_PATH' diff --git a/tests/utils.py b/tests/utils.py index 4006262afe4f..095eb66ae7c8 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -96,13 +96,15 @@ def tearDown(self): os.environ['SERVER_SOFTWARE'] = self._server_software_org -class DatastoreTestbedCase(unittest.TestCase): +class AppEngineTestbedCase(CloudBaseTest): """A base test case for common setup/teardown tasks for test.""" def setUp(self): + super(AppEngineTestbedCase, self).setUp() + if not APPENGINE_AVAILABLE: raise SkipTest() - """Setup the datastore and memcache stub.""" + # Setup the datastore and memcache stub. # First, create an instance of the Testbed class. self.testbed = testbed.Testbed() # Then activate the testbed, which prepares the service stubs for @@ -118,9 +120,21 @@ def setUp(self): consistency_policy=self.policy) self.testbed.init_memcache_stub() + # Setup remaining stubs. + self.testbed.init_user_stub() + self.testbed.init_taskqueue_stub() + def tearDown(self): + super(AppEngineTestbedCase, self).tearDown() self.testbed.deactivate() + def loginUser(self, email='user@example.com', id='123', is_admin=False): + self.testbed.setup_env( + user_email=email, + user_id=id, + user_is_admin='1' if is_admin else '0', + overwrite=True) + @contextlib.contextmanager def capture_stdout(): diff --git a/tox.ini b/tox.ini index 521cba106558..009ca087e601 100644 --- a/tox.ini +++ b/tox.ini @@ -12,6 +12,7 @@ deps = mock nose coverage + webtest nose-exclude coverargs = --with-coverage