pytest_gae ========== It is `pytest <>`_ plugin that helps You to test applications written with Google's `AppEngine <>`_. Options ======= - --with-gae: Turns on this plugin - --gae-path: AppEngine's root (default *google_appengine*) - --gae-project-path: Your project's root (default *./*) Limitation ========== Plugin does not prevent You from using code/modules that AppEngine's environment refuse to execute. So, You can easily do something like that:: import socket import numpy And tests just pass. But You can not run this code on AppEngine environment, because of sandboxing. See: `AppEngine Docs <>`_ This plugin uses internal AppEngine's code and there is no guarantee that Google is not going to change it. Others ====== This project was inspired by nose-gae plugin for nose ` <>`_ Usage example ============= Let assume we have a directory that looks something like that :: ./ |-- gae # AppEngine's root | |-- ... |-- src # Your project's root | |-- app.yaml | |-- index.yaml | |-- |-- tests # Tests' dir |-- |-- #!/usr/bin/env python from google.appengine.ext import webapp from google.appengine.ext.webapp import util from google.appengine.ext.webapp.util import login_required from google.appengine.api import users from google.appengine.ext import db class MyModel(db.Model): my_field = db.StringProperty(required=False) class IndexHandler(webapp.RequestHandler): def get(self): self.response.out.write('Index') class UsersHandler(webapp.RequestHandler): @login_required def get(self): if users.is_current_user_admin(): self.response.out.write('Admin') else: self.response.out.write('User') def make_application(): return webapp.WSGIApplication([('/index', IndexHandler), ('/users', UsersHandler)], debug=True) def main(): application = make_application() util.run_wsgi_app(application) if __name__ == '__main__': main() Testing models -------------- from google.appengine.ext import db import pytest from main import MyModel def test_basic(): m = MyModel(my_field='Foo') assert 'Foo' == m.my_field def test_new_model(): m = MyModel(my_field='Foo') pytest.raises(db.NotSavedError, lambda: m.key()) def test_saved_model(): m = MyModel(my_field='Foo') m.put() assert m.key() Using with WebTest ------------------ We could test our handlers with the help of `WebTest <>`_ library. We would create three funcargs' functions that allows us to test application: - From anonymous user perspective - From authorized user perspective - From admin perspective We could do that by altering *os.enviroment* import os from webtest import TestApp from main import make_application def pytest_funcarg__anon_app(request): os.environ.update({'USER_EMAIL': '', 'USER_ID': '', 'AUTH_DOMAIN': 'google', 'USER_IS_ADMIN': '0'}) return TestApp(make_application()) def pytest_funcarg__user_app(request): os.environ.update({'USER_EMAIL': '', 'USER_ID': '1', 'AUTH_DOMAIN': 'google', 'USER_IS_ADMIN': '0'}) return TestApp(make_application()) def pytest_funcarg__admin_app(request): os.environ.update({'USER_EMAIL': '', 'USER_ID': '2', 'AUTH_DOMAIN': 'google', 'USER_IS_ADMIN': '1'}) return TestApp(make_application()) def test_index(anon_app): assert "Index" in anon_app.get('/index') def test_user_with_user(user_app): assert "User" in user_app.get('/users') def test_user_with_anon(anon_app): assert '302 Moved Temporarily' == anon_app.get('/users').status def test_user_with_admin(admin_app): assert "Admin" in admin_app.get('/users') Running ------- :: py.test tests --with-gae --gae-path=gae --gae-project-path=./src/ : platform linux2 -- Python 2.7.12, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 collected 7 items tests/ .... tests/ ... ============ 7 passed in 0.64 seconds ============