Skip to content

Instantly share code, notes, and snippets.

@klenwell
Last active February 17, 2017 10:40
Show Gist options
  • Save klenwell/0b9ff2a15e3cbb048494 to your computer and use it in GitHub Desktop.
Save klenwell/0b9ff2a15e3cbb048494 to your computer and use it in GitHub Desktop.
A simple integration test for Flask on the Google App Engine platform.
# handlers/api.py
# Import the Flask Framework
from flask import Flask, jsonify
app = Flask(__name__)
# Note: We don't need to call run() since our application is embedded within
# the App Engine WSGI application server.
@app.route('/api/v1.0/ping', methods = ['GET'])
def ping():
return jsonify({
'ping': 'pong'
})
@app.errorhandler(404)
def page_not_found(e):
"""Return a custom 404 error."""
return 'Sorry, Nothing at this URL.', 404
@app.errorhandler(500)
def application_error(e):
"""Return a custom 500 error."""
return 'Sorry, unexpected error: {}'.format(e), 500
# This file specifies your Python application's runtime configuration
# including URL routing, versions, static file uploads, etc. See
# https://developers.google.com/appengine/docs/python/config/appconfig
# for details.
version: sample
application: appengine-sample
runtime: python27
api_version: 1
threadsafe: yes
# Handlers define how to route requests to your application.
# The script value is in the format <path.to.module>.<wsgi_application>
# where <wsgi_application> is a WSGI application object.
handlers:
#
# Task/Job Endpoints
# Restrict to admin
#
- url: /backend/.*
script: handlers.backend.app
login: admin
#
# Default
#
- url: .*
script: handlers.api.app
# Third party libraries that are included in the App Engine SDK must be listed
# here if you want to use them. See
# https://developers.google.com/appengine/docs/python/tools/libraries27 for
# a list of libraries included in the SDK.
libraries:
- name: jinja2
version: latest

This test example is based on the Google App Engine docs and Flask docs.

To run test:

python tests/test.py ~/google-cloud-sdk/platform/google_appengine/

~/google-cloud-sdk/platform/google_appengine/ is the path to the App Engine SDK.

# tests/test.py
#
# Test Runner
# https://github.com/davide-ceretti/googleappengine-python-flask-skeleton/blob/master/application/test.py
#
# USAGE
# python tests/test.py ~/google-cloud-sdk/platform/google_appengine/
#
import optparse
import sys
import unittest
import site
import os
TEST_PATH = './tests'
USAGE = """python test.py SDK_PATH
Run unit tests for App Engine apps.
SDK_PATH Path to the SDK installation"""
def main(sdk_path, test_path):
sys.path.insert(0, sdk_path)
site.addsitedir(os.path.join(os.getcwd(), 'lib'))
import dev_appserver
dev_appserver.fix_sys_path()
suite = unittest.loader.TestLoader().discover(test_path, top_level_dir='.')
unittest.TextTestRunner(verbosity=2).run(suite)
if __name__ == '__main__':
parser = optparse.OptionParser(USAGE)
options, args = parser.parse_args()
if len(args) != 1:
print 'Require Google App Engine SDK path.'
parser.print_help()
sys.exit(1)
SDK_PATH = args[0]
main(SDK_PATH, TEST_PATH)
# tests/handlers/test_api.py
import unittest
import json
from google.appengine.api import memcache
from google.appengine.ext import ndb
from google.appengine.ext import testbed
from handlers import api
class ApiHandlerTest(unittest.TestCase):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
self.testbed.init_datastore_v3_stub()
self.testbed.init_memcache_stub()
self.app = api.app.test_client()
ndb.get_context().clear_cache()
def tearDown(self):
self.testbed.deactivate()
def testPing(self):
response = self.app.get('/api/v1.0/ping')
self.assertEqual(response.status_code, 200)
json_data = json.loads(response.data)
self.assertEqual(json_data['ping'], 'pong')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment