From 655245051a0da4f56f195bb7c39db5c2c3d3df48 Mon Sep 17 00:00:00 2001 From: Martin Zibricky Date: Sun, 11 Sep 2011 23:53:19 +0200 Subject: [PATCH] Consolidating and restructuring test code --- testing/conftest.py | 138 ++++++++++++++++++++----------------- testing/test_app.py | 11 +-- testing/test_openlyrics.py | 5 +- testing/test_songs_db.py | 11 +-- 4 files changed, 89 insertions(+), 76 deletions(-) diff --git a/testing/conftest.py b/testing/conftest.py index d92702fa1..0ba4f34ed 100644 --- a/testing/conftest.py +++ b/testing/conftest.py @@ -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') diff --git a/testing/test_app.py b/testing/test_app.py index 04030d95e..2c7b01d7d 100644 --- a/testing/test_app.py +++ b/testing/test_app.py @@ -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' diff --git a/testing/test_openlyrics.py b/testing/test_openlyrics.py index 32bde3fa0..bf53f053d 100644 --- a/testing/test_openlyrics.py +++ b/testing/test_openlyrics.py @@ -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) diff --git a/testing/test_songs_db.py b/testing/test_songs_db.py index ae8d78251..ace6929b5 100644 --- a/testing/test_songs_db.py +++ b/testing/test_songs_db.py @@ -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