A testable Python skeleton application for Google App Engine and AppScale environments.
Writing properly testable Python applications to run on Google App Engine is not trivial. Keeping the different application environments segregated is also an issue if all environments share the same SDK and Python environment. This template helps you build your application in such way it's contained in a folder, along with its virtualenvironment and separate copy of the SDK. It also preinstall ipdb and pudb debuggers, nose, pytest and webtest testing tools, appengine-fixture-loader (to load test or bootstrap data), and flake8 to do style checks on your code.
This tree was extracted from a larger project that makes use of it and further evolved on its own, with the enhancements ported back.
![nosetests running] (https://raw.githubusercontent.com/wiki/rbanffy/testable_appengine/screenshot.png)
When you clone the Git repo, you'll have a tree structure not unlike the one below. This is the starting point for yout app.
├── build (will be created when you run `make venv`) ├── cache (will be created when you run `make venv`) ├── LICENSE ├── Makefile (includes resourecs/Makefile) ├── README.md (this file) ├── requirements.txt ├── resources │ ├── autogenerated │ ├── get_current_sdk_version.sh │ ├── Makefile │ └── requirements.txt (includes ../requirements.txt) ├── src (contains a sample application) │ ├── app.yaml │ └── main.py └── tests ├── __init__.py ├── persons.json └── sanity_test.py
Setting up your development environment
There is a makefile in the root directory. Running
make venv will
build a virtualenv in the
.env folder, download the App Engine SDK,
build the appropriate .pth files for your machine and install all
requirements from the
resources/requirements.txt file. If you wish to
use a Python environment you provide yourself, you can make the
virtualenv youself and run
make libraries with VENV pointing to your
virtualenv (as in
VENV=.my_env make libraries)
The actual makefile is under resources. Your own makefile (with your own targets) should include it and extend it like the included Makefile does.
Please check the makefile before using it, as it may not make sense for your environment. It was tested on Ubuntu, Fedora, OSX (10.7+, provided you have functional pip and virtualenv utilities) and Windows 8.1 under Cygwin and Windows 10 under Ubuntu on Windows. If you are developing under Windows and don't use Cygwin or the Windows Subsystem for Linux, you are suffering more than you need for no good reason.
![Under Windows+Cygwin] (https://raw.githubusercontent.com/wiki/rbanffy/testable_appengine/windows.png)
![Under Ubuntu on Windows] (https://raw.githubusercontent.com/wiki/rbanffy/testable_appengine/ubuntu_on_windows.png)
When done, you can activate your virtualenv with the usual
source .env/bin/activate or your favorite virtualenv tool. The tests will not
function outside the local virtualenv. From the virtualenv, invoking
dev_appserver.py and appcfg.py will use the versions in the SDK
downloaded during install (check the
Makefile for current version).
Your app should go in the local folder. Run your application using the
dev_appserver.py script from within the virtualenv, as in
dev_appserver.py .. Deploying ignores the files that do not belong to
your application (the license, this README, cache, tests, resources and
There are tests in the tests folder. The sanity_test.py checks whether everything is sane after you set up the environment.
Debugging works like you'd expect. You just use pdb, ipdb or pudb (ipdb
and pudb seem to have a tendency not to work under the dev_appserver,
but pdb is just fine). Rule is, use ipbd or pudb if you want to debug
something that's called by a test (run something like
pudb .env/bin/nosetests), pdb for a live web application. Worst case
scenario is that you just need to edit a little more. You can also
easily use iPython to explore your ideas before you commit them to code.
![ipython prompt and ipdb in a test] (https://raw.githubusercontent.com/wiki/rbanffy/testable_appengine/using_ipdb.png)
File a bug report (enhancement suggestions are fine too), fork it, PEP-8 it, test it, and, if it works, send a pull request. When in doubt, get in touch. We'll figure out what needs to be done.