Implement shared fixture base class.
Change-Id: I98919acb54bcd112bf633615391876175d819a8c
This commit is contained in:
parent
0d7fe979c2
commit
19a8039f11
|
@ -12,7 +12,7 @@
|
|||
# under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from tobiko.common.managers import fixture as fixture_manager
|
||||
from tobiko.common.managers import fixture
|
||||
from tobiko.common.managers import testcase as testcase_manager
|
||||
from tobiko.common.managers import loader as loader_manager
|
||||
|
||||
|
@ -22,12 +22,16 @@ load_module = loader_manager.load_module
|
|||
|
||||
discover_testcases = testcase_manager.discover_testcases
|
||||
|
||||
is_fixture = fixture_manager.is_fixture
|
||||
get_fixture = fixture_manager.get_fixture
|
||||
get_fixture_name = fixture_manager.get_fixture_name
|
||||
setup_fixture = fixture_manager.setup_fixture
|
||||
cleanup_fixture = fixture_manager.cleanup_fixture
|
||||
list_required_fixtures = fixture_manager.list_required_fixtures
|
||||
iter_required_fixtures = fixture_manager.iter_required_fixtures
|
||||
setup_required_fixtures = fixture_manager.setup_required_fixtures
|
||||
cleanup_required_fixtures = fixture_manager.cleanup_required_fixtures
|
||||
is_fixture = fixture.is_fixture
|
||||
get_fixture = fixture.get_fixture
|
||||
get_fixture_name = fixture.get_fixture_name
|
||||
remove_fixture = fixture.remove_fixture
|
||||
setup_fixture = fixture.setup_fixture
|
||||
setup_shared_fixture = fixture.setup_shared_fixture
|
||||
cleanup_fixture = fixture.cleanup_fixture
|
||||
cleanup_shared_fixture = fixture.cleanup_shared_fixture
|
||||
list_required_fixtures = fixture.list_required_fixtures
|
||||
iter_required_fixtures = fixture.iter_required_fixtures
|
||||
setup_required_fixtures = fixture.setup_required_fixtures
|
||||
cleanup_required_fixtures = fixture.cleanup_required_fixtures
|
||||
SharedFixture = fixture.SharedFixture
|
||||
|
|
|
@ -36,12 +36,33 @@ def get_fixture_name(obj):
|
|||
return get_fixture(obj).__tobiko_fixture_name__
|
||||
|
||||
|
||||
def remove_fixture(obj, manager=None):
|
||||
manager = manager or FIXTURES
|
||||
return manager.remove_fixture(obj)
|
||||
|
||||
|
||||
def setup_fixture(obj, manager=None):
|
||||
get_fixture(obj, manager=manager).setUp()
|
||||
fixture = get_fixture(obj, manager=manager)
|
||||
fixture.setUp()
|
||||
return fixture
|
||||
|
||||
|
||||
def setup_shared_fixture(obj, manager=None):
|
||||
fixture = get_fixture(obj, manager=manager)
|
||||
fixture.setup_shared_fixture()
|
||||
return fixture
|
||||
|
||||
|
||||
def cleanup_fixture(obj, manager=None):
|
||||
get_fixture(obj, manager=manager).cleanUp()
|
||||
fixture = get_fixture(obj, manager=manager)
|
||||
fixture.cleanUp()
|
||||
return fixture
|
||||
|
||||
|
||||
def cleanup_shared_fixture(obj, manager=None):
|
||||
fixture = get_fixture(obj, manager=manager)
|
||||
fixture.cleanup_shared_fixture()
|
||||
return fixture
|
||||
|
||||
|
||||
def iter_required_fixtures(objects):
|
||||
|
@ -80,15 +101,14 @@ def list_required_fixtures(objects):
|
|||
|
||||
|
||||
def setup_required_fixtures(objects, manager=None):
|
||||
manager = manager or FIXTURES
|
||||
for _fixture in iter_required_fixtures(objects=objects):
|
||||
manager.get_fixture(_fixture).setUp()
|
||||
for name in iter_required_fixtures(objects=objects):
|
||||
yield setup_fixture(name, manager=manager)
|
||||
|
||||
|
||||
def cleanup_required_fixtures(objects, manager=None):
|
||||
manager = manager or FIXTURES
|
||||
for _fixture in iter_required_fixtures(objects=objects):
|
||||
manager.get_fixture(_fixture).cleanUp()
|
||||
for name in iter_required_fixtures(objects=objects):
|
||||
yield cleanup_fixture(name, manager=manager)
|
||||
|
||||
|
||||
def init_fixture(obj, name):
|
||||
|
@ -168,5 +188,52 @@ class FixtureManager(object):
|
|||
assert isinstance(fixture, fixtures.Fixture)
|
||||
return fixture
|
||||
|
||||
def remove_fixture(self, obj):
|
||||
name = get_object_name(obj)
|
||||
return self.fixtures.pop(name, None)
|
||||
|
||||
|
||||
FIXTURES = FixtureManager()
|
||||
|
||||
|
||||
class SharedFixture(fixtures.Fixture):
|
||||
"""Base class for fixtures intended to be shared between multiple tests
|
||||
|
||||
Make sure that fixture setUp method can be called more than once, but
|
||||
actually executing _setUp method only the first time. This allows the
|
||||
fixture to be passed to useFixture methods multiple times without caring
|
||||
about if has already been used before.
|
||||
|
||||
Fixture set up can anyway be forced by calling 'setup_shared_fixture'
|
||||
method.
|
||||
|
||||
Because cleanup policy in a shared fixture is different from a common
|
||||
fixture, cleanUp method simply doesn't nothing.
|
||||
|
||||
Actual fixture cleanup is executed by calling
|
||||
cleanup_shared_fixture method.
|
||||
|
||||
"""
|
||||
|
||||
_setup_executed = False
|
||||
|
||||
def __init__(self):
|
||||
self._clear_cleanups()
|
||||
|
||||
def setUp(self):
|
||||
"""Executes _setUp method only the first time setUp is called"""
|
||||
if not self._setup_executed:
|
||||
self.setup_shared_fixture()
|
||||
|
||||
def setup_shared_fixture(self):
|
||||
"""Forces execution of _setUp method"""
|
||||
super(SharedFixture, self).setUp()
|
||||
self._setup_executed = True
|
||||
|
||||
def cleanUp(self, raise_first=True):
|
||||
"""Id doesn't nothing"""
|
||||
|
||||
def cleanup_shared_fixture(self, raise_first=True):
|
||||
"""Executes registered cleanups"""
|
||||
super(SharedFixture, self).cleanUp(raise_first)
|
||||
self._setup_executed = False
|
||||
|
|
|
@ -17,29 +17,47 @@ import fixtures
|
|||
import mock
|
||||
|
||||
import tobiko
|
||||
from tobiko.tests import base
|
||||
from tobiko.tests import unit
|
||||
|
||||
|
||||
class MyFixtureClass(fixtures.Fixture):
|
||||
class MyFixture(fixtures.Fixture):
|
||||
pass
|
||||
|
||||
|
||||
MY_FIXTURE_NAME = __name__ + '.' + MyFixtureClass.__name__
|
||||
MY_FIXTURE_NAME = __name__ + '.' + MyFixture.__name__
|
||||
|
||||
|
||||
class FixtureTypeTest(base.TobikoTest):
|
||||
class FixtureManagerTest(unit.TobikoUnitTest):
|
||||
|
||||
def setUp(self):
|
||||
super(FixtureManagerTest, self).setUp()
|
||||
tobiko.remove_fixture(MyFixture)
|
||||
|
||||
def test_get_fixture_by_name(self):
|
||||
self._test_get_fixture(MY_FIXTURE_NAME, fixture_type=MyFixtureClass)
|
||||
self._test_get_fixture(MY_FIXTURE_NAME, fixture_type=MyFixture)
|
||||
|
||||
def test_get_fixture_by_type(self):
|
||||
self._test_get_fixture(MyFixtureClass, fixture_type=MyFixtureClass)
|
||||
self._test_get_fixture(MyFixture, fixture_type=MyFixture)
|
||||
|
||||
def _test_get_fixture(self, obj, fixture_type):
|
||||
fixture = tobiko.get_fixture(obj)
|
||||
self.assertIsInstance(fixture, fixture_type)
|
||||
self.assertIs(fixture, tobiko.get_fixture(obj))
|
||||
|
||||
def test_remove_fixture_by_name(self):
|
||||
self._test_remove_fixture(MY_FIXTURE_NAME)
|
||||
|
||||
def test_remove_fixture_by_type(self):
|
||||
self._test_remove_fixture(MyFixture)
|
||||
|
||||
def _test_remove_fixture(self, obj):
|
||||
fixture = tobiko.get_fixture(obj)
|
||||
|
||||
result = tobiko.remove_fixture(obj)
|
||||
|
||||
self.assertIs(fixture, result)
|
||||
self.assertIsNot(fixture, tobiko.get_fixture(obj))
|
||||
|
||||
def test_get_name(self):
|
||||
fixture = tobiko.get_fixture(MY_FIXTURE_NAME)
|
||||
result = tobiko.get_fixture_name(fixture)
|
||||
|
@ -49,42 +67,42 @@ class FixtureTypeTest(base.TobikoTest):
|
|||
self._test_setup_fixture(MY_FIXTURE_NAME)
|
||||
|
||||
def test_setup_fixture_by_type(self):
|
||||
self._test_setup_fixture(MyFixtureClass)
|
||||
self._test_setup_fixture(MyFixture)
|
||||
|
||||
def _test_setup_fixture(self, obj):
|
||||
fixture = tobiko.get_fixture(obj)
|
||||
fixture.setUp = setup = mock.MagicMock()
|
||||
setup = self.patch('fixtures.Fixture.setUp')
|
||||
|
||||
tobiko.setup_fixture(obj)
|
||||
result = tobiko.setup_fixture(obj)
|
||||
|
||||
setup.assert_called_once_with()
|
||||
self.assertIs(tobiko.get_fixture(obj), result)
|
||||
|
||||
def test_cleanup_fixture_by_name(self):
|
||||
self._test_cleanup_fixture(MY_FIXTURE_NAME)
|
||||
|
||||
def test_cleanup_fixture_by_type(self):
|
||||
self._test_cleanup_fixture(MyFixtureClass)
|
||||
self._test_cleanup_fixture(MyFixture)
|
||||
|
||||
def _test_cleanup_fixture(self, obj):
|
||||
cleanup = mock.MagicMock()
|
||||
fixture = tobiko.get_fixture(obj)
|
||||
fixture.setUp()
|
||||
fixture = tobiko.setup_fixture(obj)
|
||||
fixture.addCleanup(cleanup)
|
||||
|
||||
tobiko.cleanup_fixture(obj)
|
||||
result = tobiko.cleanup_fixture(obj)
|
||||
|
||||
cleanup.assert_called_once_with()
|
||||
self.assertIs(tobiko.get_fixture(obj), result)
|
||||
|
||||
def test_list_required_fixtures_from_module(self):
|
||||
result = tobiko.list_required_fixtures([__name__])
|
||||
self.assertEqual([MY_FIXTURE_NAME], result)
|
||||
self.assertEqual([MY_FIXTURE_NAME, MY_SHARED_FIXTURE_NAME], result)
|
||||
|
||||
def test_list_required_fixtures_from_testcase_type(self):
|
||||
result = tobiko.list_required_fixtures([FixtureTypeTest])
|
||||
result = tobiko.list_required_fixtures([FixtureManagerTest])
|
||||
self.assertEqual([MY_FIXTURE_NAME], result)
|
||||
|
||||
def test_list_required_fixtures_from_fixture_type(self):
|
||||
result = tobiko.list_required_fixtures([MyFixtureClass])
|
||||
result = tobiko.list_required_fixtures([MyFixture])
|
||||
self.assertEqual([MY_FIXTURE_NAME], result)
|
||||
|
||||
def test_list_required_fixtures_from_fixture_name(self):
|
||||
|
@ -92,7 +110,7 @@ class FixtureTypeTest(base.TobikoTest):
|
|||
self.assertEqual([MY_FIXTURE_NAME], result)
|
||||
|
||||
def test_list_required_fixtures_from_method(
|
||||
self, fixture_type=MyFixtureClass):
|
||||
self, fixture_type=MyFixture):
|
||||
result = tobiko.list_required_fixtures([self.id()])
|
||||
self.assertEqual([MY_FIXTURE_NAME], result)
|
||||
self.assertIsInstance(tobiko.get_fixture(MY_FIXTURE_NAME),
|
||||
|
@ -103,20 +121,79 @@ class FixtureTypeTest(base.TobikoTest):
|
|||
result = tobiko.list_required_fixtures([fixture])
|
||||
self.assertEqual([MY_FIXTURE_NAME], result)
|
||||
|
||||
def test_setup_required_fixtures(self, fixture_type=MyFixtureClass):
|
||||
fixture = tobiko.get_fixture(fixture_type)
|
||||
fixture.setUp = setup = mock.MagicMock()
|
||||
def test_setup_required_fixtures(self, fixture_type=MyFixture):
|
||||
setup = self.patch('fixtures.Fixture.setUp')
|
||||
|
||||
tobiko.setup_required_fixtures([self.id()])
|
||||
result = list(tobiko.setup_required_fixtures([self.id()]))
|
||||
|
||||
setup.assert_called_once_with()
|
||||
self.assertEqual([tobiko.get_fixture(fixture_type)], result)
|
||||
|
||||
def test_cleanup_required_fixtures(self, fixture_type=MyFixtureClass):
|
||||
def test_cleanup_required_fixtures(self, fixture_type=MyFixture):
|
||||
cleanup = mock.MagicMock()
|
||||
fixture = tobiko.get_fixture(fixture_type)
|
||||
fixture.setUp()
|
||||
fixture = tobiko.setup_fixture(fixture_type)
|
||||
fixture.addCleanup(cleanup)
|
||||
|
||||
tobiko.cleanup_required_fixtures([self.id()])
|
||||
result = list(tobiko.cleanup_required_fixtures([self.id()]))
|
||||
|
||||
cleanup.assert_called_once_with()
|
||||
self.assertEqual([tobiko.get_fixture(fixture_type)], result)
|
||||
|
||||
|
||||
class MySharedFixture(tobiko.SharedFixture):
|
||||
pass
|
||||
|
||||
|
||||
MY_SHARED_FIXTURE_NAME = __name__ + '.' + MySharedFixture.__name__
|
||||
|
||||
|
||||
class SharedFixtureTest(unit.TobikoUnitTest):
|
||||
|
||||
def setUp(self):
|
||||
super(SharedFixtureTest, self).setUp()
|
||||
tobiko.remove_fixture(MySharedFixture)
|
||||
self.mock_setup = self.patch('fixtures.Fixture.setUp')
|
||||
self.mock_cleanup = self.patch('fixtures.Fixture.cleanUp')
|
||||
|
||||
def test_initial_state(self):
|
||||
self.mock_setup.assert_not_called()
|
||||
self.mock_cleanup.assert_not_called()
|
||||
|
||||
def test_use_fixture(self):
|
||||
self.addCleanup(self.mock_cleanup.assert_not_called)
|
||||
fixture = tobiko.get_fixture(MySharedFixture)
|
||||
|
||||
self.useFixture(fixture)
|
||||
self.mock_setup.assert_called_once_with()
|
||||
|
||||
self.useFixture(fixture)
|
||||
self.mock_setup.assert_called_once_with()
|
||||
|
||||
def test_setup_fixture(self):
|
||||
tobiko.setup_fixture(MySharedFixture)
|
||||
tobiko.setup_fixture(MySharedFixture)
|
||||
self.mock_setup.assert_called_once_with()
|
||||
|
||||
def test_cleanup_fixture(self):
|
||||
tobiko.cleanup_fixture(MySharedFixture)
|
||||
self.mock_cleanup.assert_not_called()
|
||||
|
||||
def test_setup_shared_fixture(self):
|
||||
tobiko.setup_shared_fixture(MySharedFixture)
|
||||
tobiko.setup_shared_fixture(MySharedFixture)
|
||||
self.mock_setup.assert_has_calls([mock.call(), mock.call()])
|
||||
|
||||
def test_cleanup_shared_fixture(self):
|
||||
tobiko.cleanup_shared_fixture(MySharedFixture)
|
||||
self.mock_cleanup.assert_called_once()
|
||||
|
||||
def test_cleanup_shared_fixture_workflow(self):
|
||||
tobiko.setup_fixture(MySharedFixture)
|
||||
tobiko.setup_fixture(MySharedFixture)
|
||||
self.mock_setup.assert_called_once_with()
|
||||
|
||||
tobiko.cleanup_shared_fixture(MySharedFixture)
|
||||
self.mock_cleanup.assert_called_once()
|
||||
|
||||
tobiko.setup_fixture(MySharedFixture)
|
||||
self.mock_setup.assert_has_calls([mock.call(), mock.call()])
|
||||
|
|
Loading…
Reference in New Issue