Skip to content

Commit a7a8b1e

Browse files
author
Jon Wayne Parrott
committed
Merge pull request #197 from GoogleCloudPlatform/pytest-appengine
Moving app engine samples to py.test
2 parents 433e0e1 + 6990555 commit a7a8b1e

25 files changed

+466
-576
lines changed

appengine/app_identity/signing/main_test.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,11 @@
1313
# limitations under the License.
1414

1515
import main
16-
from testing import AppEngineTest
1716
import webtest
1817

1918

20-
class TestAppIdentityHandler(AppEngineTest):
21-
def setUp(self):
22-
super(TestAppIdentityHandler, self).setUp()
23-
24-
self.app = webtest.TestApp(main.app)
25-
26-
def test_get(self):
27-
response = self.app.get('/')
28-
self.assertEqual(response.status_int, 200)
29-
self.assertTrue('Verified: True' in response.text)
19+
def test_app(testbed):
20+
app = webtest.TestApp(main.app)
21+
response = app.get('/')
22+
assert response.status_int == 200
23+
assert 'Verified: True' in response.text

appengine/bigquery/main_test.py

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,47 +17,48 @@
1717
from apiclient.http import HttpMock
1818
import main
1919
import mock
20-
import testing
20+
import pytest
2121
import webtest
2222

2323

24-
class TestAuthSample(testing.AppEngineTest):
24+
@pytest.fixture
25+
def app(cloud_config, testbed):
26+
main.PROJECTID = cloud_config.GCLOUD_PROJECT
27+
return webtest.TestApp(main.app)
2528

26-
def setUp(self):
27-
super(TestAuthSample, self).setUp()
28-
self.app = webtest.TestApp(main.app)
29-
main.PROJECTID = self.config.GCLOUD_PROJECT
3029

31-
def test_anonymous_get(self):
32-
response = self.app.get('/')
30+
def test_anonymous(app):
31+
response = app.get('/')
3332

34-
# Should redirect to login
35-
self.assertEqual(response.status_int, 302)
36-
self.assertRegexpMatches(response.headers['Location'],
37-
r'.*accounts.*Login.*')
33+
# Should redirect to login
34+
assert response.status_int == 302
35+
assert re.search(r'.*accounts.*Login.*', response.headers['Location'])
3836

39-
def test_loggedin_get(self):
40-
self.login_user()
4137

42-
response = self.app.get('/')
38+
def test_loggedin(app, login):
39+
login()
4340

44-
# Should redirect to login
45-
self.assertEqual(response.status_int, 302)
46-
self.assertRegexpMatches(response.headers['Location'], r'.*oauth2.*')
41+
response = app.get('/')
4742

48-
@mock.patch.object(main.decorator, 'has_credentials', return_value=True)
49-
def test_oauthed_get(self, *args):
50-
self.login_user()
43+
# Should redirect to oauth2
44+
assert response.status_int == 302
45+
assert re.search(r'.*oauth2.*', response.headers['Location'])
5146

52-
mock_http = HttpMock(
53-
self.resource_path('datasets-list.json'),
54-
{'status': '200'})
5547

56-
with mock.patch.object(main.decorator, 'http', return_value=mock_http):
57-
response = self.app.get('/')
48+
def test_oauthed(resource, app, login):
49+
login()
5850

59-
# Should make the api call
60-
self.assertEqual(response.status_int, 200)
61-
self.assertRegexpMatches(
62-
response.body,
63-
re.compile(r'.*datasets.*datasetReference.*etag.*', re.DOTALL))
51+
mock_http = HttpMock(
52+
resource('datasets-list.json'),
53+
{'status': '200'})
54+
55+
with mock.patch.object(main.decorator, 'http', return_value=mock_http):
56+
with mock.patch.object(
57+
main.decorator, 'has_credentials', return_value=True):
58+
response = app.get('/')
59+
60+
# Should make the api call
61+
assert response.status_int == 200
62+
assert re.search(
63+
re.compile(r'.*datasets.*datasetReference.*etag.*', re.DOTALL),
64+
response.body)

appengine/blobstore/main_test.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,13 @@
1313
# limitations under the License.
1414

1515
import main
16-
import testing
1716
import webtest
1817

1918

20-
class TestBlobstoreSample(testing.AppEngineTest):
19+
def test_app(testbed, login):
20+
app = webtest.TestApp(main.app)
2121

22-
def setUp(self):
23-
super(TestBlobstoreSample, self).setUp()
24-
self.app = webtest.TestApp(main.app)
22+
login()
23+
response = app.get('/')
2524

26-
def test_form(self):
27-
self.login_user()
28-
response = self.app.get('/')
29-
30-
self.assertTrue('/_ah/upload' in response)
25+
assert '/_ah/upload' in response

appengine/cloudsql/main_test.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,20 @@
1414

1515
import os
1616
import re
17-
from unittest.case import SkipTest
1817

1918
import main
20-
import testing
19+
import pytest
2120
import webtest
2221

2322

24-
class TestMySQLSample(testing.AppEngineTest):
23+
@pytest.mark.skipif(
24+
not os.path.exists('/var/run/mysqld/mysqld.sock'),
25+
reason='MySQL server not available.')
26+
def test_app():
27+
app = webtest.TestApp(main.app)
28+
response = app.get('/')
2529

26-
def setUp(self):
27-
if not os.path.exists('/var/run/mysqld/mysqld.sock'):
28-
raise SkipTest('No MySQL server found.')
29-
super(TestMySQLSample, self).setUp()
30-
self.app = webtest.TestApp(main.app)
31-
32-
def test_get(self):
33-
response = self.app.get('/')
34-
self.assertEqual(response.status_int, 200)
35-
self.assertRegexpMatches(
36-
response.body,
37-
re.compile(r'.*version.*', re.DOTALL))
30+
assert response.status_int == 200
31+
assert re.search(
32+
re.compile(r'.*version.*', re.DOTALL),
33+
response.body)

appengine/conftest.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import pytest
12
import testing.appengine
23

34

@@ -7,3 +8,28 @@ def pytest_configure(config):
78

89
def pytest_runtest_call(item):
910
testing.appengine.import_appengine_config()
11+
12+
13+
@pytest.yield_fixture
14+
def testbed():
15+
testbed = testing.appengine.setup_testbed()
16+
yield testbed
17+
testbed.deactivate()
18+
19+
20+
@pytest.fixture
21+
def login(testbed):
22+
def _login(email='[email protected]', id='123', is_admin=False):
23+
testbed.setup_env(
24+
user_email=email,
25+
user_id=id,
26+
user_is_admin='1' if is_admin else '0',
27+
overwrite=True)
28+
return _login
29+
30+
31+
@pytest.fixture
32+
def run_tasks(testbed):
33+
def _run_tasks(app):
34+
testing.appengine.run_tasks(testbed, app)
35+
return _run_tasks

appengine/images/main_test.py

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,60 +14,64 @@
1414

1515
import main
1616
import mock
17-
from testing import AppEngineTest
17+
import pytest
1818
import webtest
1919

2020

21-
class TestHandlers(AppEngineTest):
22-
def setUp(self):
23-
super(TestHandlers, self).setUp()
24-
self.app = webtest.TestApp(main.app)
21+
@pytest.fixture
22+
def app(testbed):
23+
return webtest.TestApp(main.app)
2524

26-
def test_get(self):
27-
main.Greeting(
28-
parent=main.guestbook_key('default_guestbook'),
29-
author='123',
30-
content='abc'
31-
).put()
3225

33-
response = self.app.get('/')
26+
def test_get(app):
27+
main.Greeting(
28+
parent=main.guestbook_key('default_guestbook'),
29+
author='123',
30+
content='abc'
31+
).put()
3432

35-
# Let's check if the response is correct.
36-
self.assertEqual(response.status_int, 200)
33+
response = app.get('/')
3734

38-
@mock.patch('main.images')
39-
def test_post(self, mock_images):
35+
# Let's check if the response is correct.
36+
assert response.status_int == 200
37+
38+
39+
def test_post(app):
40+
with mock.patch('main.images') as mock_images:
4041
mock_images.resize.return_value = 'asdf'
4142

42-
response = self.app.post('/sign', {'content': 'asdf'})
43+
response = app.post('/sign', {'content': 'asdf'})
4344
mock_images.resize.assert_called_once_with(mock.ANY, 32, 32)
4445

4546
# Correct response is a redirect
46-
self.assertEqual(response.status_int, 302)
47+
assert response.status_int == 302
48+
49+
50+
def test_img(app):
51+
greeting = main.Greeting(
52+
parent=main.guestbook_key('default_guestbook'),
53+
id=123
54+
)
55+
greeting.author = 'asdf'
56+
greeting.content = 'asdf'
57+
greeting.avatar = b'123'
58+
greeting.put()
59+
60+
response = app.get('/img?img_id=%s' % greeting.key.urlsafe())
4761

48-
def test_img(self):
49-
greeting = main.Greeting(
50-
parent=main.guestbook_key('default_guestbook'),
51-
id=123
52-
)
53-
greeting.author = 'asdf'
54-
greeting.content = 'asdf'
55-
greeting.avatar = b'123'
56-
greeting.put()
62+
assert response.status_int == 200
5763

58-
response = self.app.get('/img?img_id=%s' % greeting.key.urlsafe())
5964

60-
self.assertEqual(response.status_int, 200)
65+
def test_img_missing(app):
66+
# Bogus image id, should get error
67+
app.get('/img?img_id=123', status=500)
6168

62-
def test_img_missing(self):
63-
# Bogus image id, should get error
64-
self.app.get('/img?img_id=123', status=500)
6569

66-
@mock.patch('main.images')
67-
def test_post_and_get(self, mock_images):
70+
def test_post_and_get(app):
71+
with mock.patch('main.images') as mock_images:
6872
mock_images.resize.return_value = 'asdf'
6973

70-
self.app.post('/sign', {'content': 'asdf'})
71-
response = self.app.get('/')
74+
app.post('/sign', {'content': 'asdf'})
75+
response = app.get('/')
7276

73-
self.assertEqual(response.status_int, 200)
77+
assert response.status_int == 200

appengine/logging/reading_logs/main_test.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,12 @@
1313
# limitations under the License.
1414

1515
import main
16-
from testing import AppEngineTest
1716
import webtest
1817

1918

20-
class TestReadingLogs(AppEngineTest):
21-
def setUp(self):
22-
super(TestReadingLogs, self).setUp()
23-
24-
self.app = webtest.TestApp(main.app)
25-
26-
def test_get(self):
27-
response = self.app.get('/')
28-
self.assertEqual(response.status_int, 200)
29-
self.assertTrue('No log entries found' in response.text)
30-
self.assertTrue('More' not in response.text)
19+
def test_app(testbed):
20+
app = webtest.TestApp(main.app)
21+
response = app.get('/')
22+
assert response.status_int == 200
23+
assert 'No log entries found' in response.text
24+
assert 'More' not in response.text

appengine/logging/writing_logs/main_test.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,11 @@
1313
# limitations under the License.
1414

1515
import main
16-
from testing import AppEngineTest
1716
import webtest
1817

1918

20-
class TestWritingLogs(AppEngineTest):
21-
def setUp(self):
22-
super(TestWritingLogs, self).setUp()
23-
24-
self.app = webtest.TestApp(main.app)
25-
26-
def test_get(self):
27-
response = self.app.get('/')
28-
self.assertEqual(response.status_int, 200)
29-
self.assertTrue('Logging example' in response.text)
19+
def test_app(testbed):
20+
app = webtest.TestApp(main.app)
21+
response = app.get('/')
22+
assert response.status_int == 200
23+
assert 'Logging example' in response.text

0 commit comments

Comments
 (0)