Wednesday, May 7, 2008

Running Google AppEngine Django Unit Test Cases

If you want to run standalone google appengine code, you will need to establish some setup routines and initializations. Here is some code that I used to prepare the google appengine datastore and run a collection of python unit test cases.


#!/usr/bin/env python

'''
Author: Berlin Brown
Filename: run_all_tests.py
Application: test case for botlist django front-end (ghostnet)
Environment: Python 2.5.2
-------------------------- Description --

With the following code, you can run google-appengine
stand-alone database driven test cases.

* Run batch python unit test scripts
* The script ensures that the google libraries are imported and
added to the python sys path.

'''


import os
import sys
import unittest

# Add the parent directory, ghostnet to the sys path.
# We are assuming that google_appengine is also in the
# For example:
# -----------------------------
# PROJECT_HOME/google_appengine
# PROJECT_HOME/projects/ghostnet/tests

DIR_PATH = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
PROJECT_HOME = os.path.join(DIR_PATH, '..', '..', '..')

print("INFO: project_home=%s" % PROJECT_HOME)

EXTRA_PATHS = [
DIR_PATH,
os.path.join(PROJECT_HOME, 'projects', 'ghostnet'),
os.path.join(PROJECT_HOME, 'google_appengine'),
os.path.join(PROJECT_HOME, 'google_appengine', 'lib', 'django'),
os.path.join(PROJECT_HOME, 'google_appengine', 'lib', 'webob'),
os.path.join(PROJECT_HOME, 'google_appengine', 'lib', 'yaml', 'lib')
]
sys.path = EXTRA_PATHS + sys.path

# End of path setup

import datetime
import logging

# Google App Engine includes
from google.appengine.api import apiproxy_stub_map
from google.appengine.api import datastore_file_stub
from google.appengine.api import mail_stub
from google.appengine.api import user_service_stub
from google.appengine.ext import db

APP_ID = 'ghostnet_tests'
DS_PATH = '/tmp/dev_ds_tests.db'
HIST_PATH = '/tmp/dev_ds_tests.hist'

apiproxy_stub_map.apiproxy.RegisterStub(
'user',
user_service_stub.UserServiceStub())

# From the dev_appserver source:
# ----------------------
# datastore = datastore_file_stub.DatastoreFileStub(
# app_id, datastore_path, history_path, require_indexes=require_indexes)
# ----------------------
apiproxy_stub_map.apiproxy.RegisterStub(
'datastore_v3',
datastore_file_stub.DatastoreFileStub('ghostnet_tests',
DS_PATH,
HIST_PATH))
apiproxy_stub_map.apiproxy.RegisterStub(
'mail',
mail_stub.MailServiceStub())

# ----------------------
# Django Setups
# ----------------------

# A workaround to fix the partial initialization of Django before we are ready
from django.conf import settings
settings._target = None

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

# Import various parts of Django.
import django.core.handlers.wsgi
import django.core.signals
import django.dispatch.dispatcher
import django.db

# --------------
# Tests includes
# --------------
from tests.create_models import suite as suite_create
from tests.read_models import suite as suite_read
from tests.agent_rpc_test import suite as suite_rpc
from tests.client.client_rpc_test import suite as suite_client_rpc

def run_test_suite():
suite = unittest.TestSuite()
suite.addTest(suite_create())
suite.addTest(suite_read())
suite.addTest(suite_rpc())
suite.addTest(suite_client_rpc())
runner = unittest.TextTestRunner()
runner.run(suite)

# End of appengine setups for command-line test apps

if __name__ == '__main__':
print "Running model create"
run_test_suite()
print "Done"

# End of Script

7 comments:

Will Sargent said...

Oh sweet. Thank you, this is perfect.

wtanaka said...
This comment has been removed by the author.
wtanaka said...
This comment has been removed by the author.
wtanaka said...

I'm running into this:

Traceback (most recent call last):
File "./test.py", line 71, in <module>
import django.db
File ".../test/../google_appengine/lib/django/django/db/__init__.py", line 7, in <module>
if not settings.DATABASE_ENGINE:
File ".../test/../google_appengine/lib/django/django/conf/__init__.py", line 28, in __getattr__
self._import_settings()
File ".../test/../google_appengine/lib/django/django/conf/__init__.py", line 55, in _import_settings
self._target = Settings(settings_module)
File ".../test/../google_appengine/lib/django/django/conf/__init__.py", line 83, in __init__
raise EnvironmentError, "Could not import settings '%s' (Is it on sys.path? Does it have syntax errors?): %s" % (self.SETTINGS_MODULE, e)
EnvironmentError: Could not import settings 'settings' (Is it on sys.path? Does it have syntax errors?): No module named settings

wtanaka said...

I'm finding it useful to remove the database file before each test run:

DS_PATH = '/tmp/dev_ds_tests.db'
os.remove(DS_PATH)

George Lei said...

Running standalone app engine test is an urgly thing because there are too many environmental dependencies. GAEUnit is a simpler but better solution that can run unit test in a running Google App Server

http://code.google.com/p/gaeunit/

Jone Duff said...

Thank you for showing such an useful article. The sample in your article is quite good.Do you have any idea about how to create qr code j2ee? If you have some view, please give some advice.