Consolidating and restructuring test code

This commit is contained in:
Martin Zibricky 2011-09-11 23:53:19 +02:00
parent eef786f85c
commit 655245051a
4 changed files with 89 additions and 76 deletions

View File

@ -49,14 +49,73 @@ TESTS_PATH = os.path.dirname(os.path.abspath(__file__))
RESOURCES_PATH = os.path.join(TESTS_PATH, 'resources')
SONGS_PATH = os.path.join(RESOURCES_PATH, 'songs')
# set up logging to stderr (console)
_handler = logging.StreamHandler(stream=None)
_handler.setFormatter(logging.Formatter(
u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s'))
logging.addLevelName(15, u'Timer')
log = logging.getLogger()
log.addHandler(_handler)
log.setLevel(logging.DEBUG)
# class to setup and teardown settings for running openlp tests
class OpenLPRunner(object):
def __init__(self, tmpdir):
self.tmpdir = tmpdir
self._setup_qapp()
self._setup_logging()
self._cleanup_qsettings()
# override data dir of OpenLP - it points to tmpdir of a test case
AppLocation.BaseDir = tmpdir.strpath
def _setup_qapp(self):
QtCore.QCoreApplication.setOrganizationName(u'OpenLP')
QtCore.QCoreApplication.setOrganizationDomain(u'openlp.org')
QtCore.QCoreApplication.setApplicationName(u'TestOpenLP')
def _setup_logging(self):
# set up logging to stderr/stdout (console)
_handler = logging.StreamHandler(stream=None)
_handler.setFormatter(logging.Formatter(
u'%(asctime)s %(name)-55s %(levelname)-8s %(message)s'))
logging.addLevelName(15, u'Timer')
log = logging.getLogger()
log.addHandler(_handler)
log.setLevel(logging.DEBUG)
def _cleanup_qsettings(self):
# Clean up QSettings for all plugins
# The issue with QSettings is that is global for a running process
# and thus it is necessary to clean it before another test case.
# If it would not be cleaned up it could be saved in the system.
s = QtCore.QSettings()
keys = s.allKeys()
for k in keys:
s.setValue(k, None)
## Public interface
def get_songs_db(self, empty=False):
# return initialized db Manager with empty db or db containing
# some example songs
if not empty:
# copy test data to tmpdir
datadir = self.tmpdir.mkdir(u'data').mkdir(u'songs')
orig_db = py.path.local(SONGS_PATH).join('songs.sqlite')
orig_db.copy(datadir)
manager = Manager('songs', init_schema)
return manager
def get_app(self):
# return QGui.QApplication of OpenLP - this object allows
# running different gui tests and allows access to gui objects
# (e.g MainWindow etc.)
# To allow creating multiple instances of OpenLP in one process
# it would be necessary use diffrent configuration and data files.
# Created instance will use your OpenLP settings.
return openlp_main(['--testing'])
def teardown(self):
# clean up code to run after running the test case
self._cleanup_qsettings()
# sqlalchemy allows to map classess to only one database at a time
clear_mappers()
# set data dir to original value
AppLocation.BaseDir = None
# Paths with resources for tests
@ -68,66 +127,15 @@ def pytest_funcarg__pth(request):
self.resources = py.path.local(RESOURCES_PATH)
self.songs = py.path.local(SONGS_PATH)
return Pth()
return request.cached_setup(setup=setup, scope='module')
return request.cached_setup(setup=setup, scope='session')
# Test function argument to make openlp gui instance persistent for all tests.
# Test cases in module have to access the same instance. To allow creating
# multiple
# instances it would be necessary use diffrent configuraion and data files.
# Created instance will use your OpenLP settings.
def pytest_funcarg__openlpapp(request):
# Test function argument giving access to OpenLP runner
def pytest_funcarg__openlp_runner(request):
def setup():
return openlp_main(['--testing'])
def teardown(app):
# sqlalchemy allows to map classess to only one database at a time
clear_mappers()
return request.cached_setup(setup=setup, teardown=teardown, scope='module')
# Clean up QSettings for all plugins
def _cleanup_qsettings():
s = QtCore.QSettings()
keys = s.allKeys()
for k in keys:
s.setValue(k, QtCore.QVariant(None))
# Test function argument giving access to empty song database.
def pytest_funcarg__empty_songs_db(request):
#def get_data_dir(section):
# return request.getfuncargvalue('tmpdir').strpath
def setup():
tmpdir = request.getfuncargvalue('tmpdir')
# override data dir
AppLocation.BaseDir = tmpdir.strpath
manager = Manager('songs', init_schema)
return manager
def teardown(manager):
_cleanup_qsettings()
# sqlalchemy allows to map classess to only one database at a time
clear_mappers()
AppLocation.BaseDir = None
return request.cached_setup(setup=setup, teardown=teardown, scope='function')
# Test function argument giving access to song database.
def pytest_funcarg__songs_db(request):
def setup():
tmpdir = request.getfuncargvalue('tmpdir')
# override data dir
AppLocation.BaseDir = tmpdir.strpath
datadir = tmpdir.mkdir(u'data').mkdir( u'songs')
# copy test data to tmpdir
orig_db = py.path.local(SONGS_PATH).join('songs.sqlite')
orig_db.copy(datadir)
manager = Manager('songs', init_schema)
return manager
def teardown(manager):
_cleanup_qsettings()
# sqlalchemy allows to map classess to only one database at a time
clear_mappers()
AppLocation.BaseDir = None
return OpenLPRunner(request.getfuncargvalue('tmpdir'))
def teardown(openlp_runner):
openlp_runner.teardown()
return request.cached_setup(setup=setup, teardown=teardown, scope='function')

View File

@ -34,7 +34,10 @@ from openlp.core import OpenLP
from openlp.core.ui.mainwindow import MainWindow
#def test_start_app(openlpapp):
#assert type(openlpapp) == OpenLP
#assert type(openlpapp.mainWindow) == MainWindow
#assert unicode(openlpapp.mainWindow.windowTitle()) == u'OpenLP 2.0'
# TODO Uncommend when using custom OpenLP configuration is implemented.
# Otherwise it would mess up user's OpenLP settings
#def test_start_app(openlp_runner):
#app = openlp_runner.get_app()
#assert type(app) == OpenLP
#assert type(app.mainWindow) == MainWindow
#assert unicode(app.mainWindow.windowTitle()) == u'OpenLP 2.0'

View File

@ -35,10 +35,11 @@ from lxml import etree
from openlp.plugins.songs.lib.db import Song
from openlp.plugins.songs.lib import OpenLyrics
def test_openlyrics_export(songs_db, openlyrics_validator, pth, tmpdir):
def test_openlyrics_export(openlp_runner, openlyrics_validator, pth, tmpdir):
# export song to file
f = tmpdir.join('out.xml')
db = songs_db
db = openlp_runner.get_songs_db()
s = db.get_all_objects(Song)[0]
o = OpenLyrics(db)
xml = o.song_to_xml(s)

View File

@ -37,14 +37,15 @@ from sqlalchemy.orm.exc import UnmappedInstanceError
from openlp.plugins.songs.lib.db import Author, Book, MediaFile, Song, Topic
def test_empty_songdb(empty_songs_db):
g = empty_songs_db.get_all_objects
def test_empty_songdb(openlp_runner):
db = openlp_runner.get_songs_db(empty=True)
g = db.get_all_objects
assert g(Author) == []
assert g(Book) == []
assert g(MediaFile) == []
assert g(Song) == []
assert g(Topic) == []
c = empty_songs_db.get_object_count
c = db.get_object_count
assert c(Author) == 0
assert c(Book) == 0
assert c(MediaFile) == 0
@ -52,11 +53,11 @@ def test_empty_songdb(empty_songs_db):
assert c(Topic) == 0
def test_unmapped_class(empty_songs_db):
def test_unmapped_class(openlp_runner):
# test class not mapped to any sqlalchemy table
class A(object):
pass
db = empty_songs_db
db = openlp_runner.get_songs_db(empty=True)
assert db.save_object(A()) == False
assert db.save_objects([A(), A()]) == False
# no key - new object instance is created from supplied class