In the last post I noted some documentation related to nose and ORM. Well, they did not work for me because my setup was not exactly like others'. Here is what worked for me. In
tests/__init__.py:
- I imported
from pylons import config
to get the SQLAlchemy engine embedded in pylons's config variable - I imported
import quickwiki.model as model
so that I could get hold of my models and metadata - I created a class
TestModel
inheriting fromTestCase
to hold the setup and teardown code - In the
tearDown
method, I domodel.metadata.drop_all(bind=engine)
to destroy all tables - In the
setUp
method, I calltearDown
to destroy tables if they have not already been cleaned up, and then callmodel.metadata.create_all(bind=engine)
to create the tables.
Here is the final code:
"""Pylons application test package
When the test runner finds and executes tests within this directory,
this file will be loaded to setup the test environment.
It registers the root directory of the project in sys.path and
pkg_resources, in case the project hasn't been installed with
setuptools. It also initializes the application via websetup (paster
setup-app) with the project's test.ini configuration file.
"""
import os
import sys
from unittest import TestCase
import pkg_resources
import paste.fixture
import paste.script.appinstall
from paste.deploy import loadapp
from routes import url_for
__all__ = ['url_for', 'TestController']
here_dir = os.path.dirname(os.path.abspath(__file__))
conf_dir = os.path.dirname(os.path.dirname(here_dir))
sys.path.insert(0, conf_dir)
pkg_resources.working_set.add_entry(conf_dir)
pkg_resources.require('Paste')
pkg_resources.require('PasteScript')
test_file = os.path.join(conf_dir, 'test.ini')
cmd = paste.script.appinstall.SetupCommand('setup-app')
cmd.run([test_file])
from pylons import config
import quickwiki.model as model
class TestModel(TestCase):
"""
We want the database to be created from scratch before each test and dropped
after each test (thus making them unit tests).
"""
def setUp(self):
self.tearDown()
engine = config['pylons.g'].sa_engine
model.metadata.create_all(bind=engine)
page = model.Page()
page.title = 'FrontPage'
page.content = 'Welcome to the QuickWiki front page'
model.Session.save(page)
model.Session.commit()
def tearDown(self):
engine = config['pylons.g'].sa_engine
model.metadata.drop_all(bind=engine)
class TestController(TestModel):
def __init__(self, *args, **kwargs):
wsgiapp = loadapp('config:test.ini', relative_to=conf_dir)
self.app = paste.fixture.TestApp(wsgiapp)
TestCase.__init__(self, *args, **kwargs)
Well, that almost worked. I fell foul of the 'setup-app' command and 'setup-config' in websetup.py. As you can see, the 'tests/__init__.py' file loads and executes the paster 'setup-app' command. Stands to reason: the app should be 'set up' before I run tests.
My setup-app is responsible for creating the DB and populating it with some initial data. But now I can't repeat my tests, because the first time I run the tests, the db is created and initial data put in, and the next time I run the tests... poof:
IntegrityError: (IntegrityError) column title is not unique
u'INSERT INTO pages (title, content) VALUES (?, ?)' ['FrontPage',
'Welcome to the QuickWiki front page']
Well, I thought, I would just drop everything in the db in the tearDown and ensure that tearDown is called before setUp is run. No go. For some reason, it seems, the tearDown() is not working.
Well, it seems I must have at least one test, for the fixtures to be run. So I created a dummy test, and all was well.
No comments:
Post a Comment