diff options
author | Lingxian Kong <anlin.kong@gmail.com> | 2021-07-13 09:23:46 +1200 |
---|---|---|
committer | Lingxian Kong <anlin.kong@gmail.com> | 2021-07-13 09:23:46 +1200 |
commit | ce8014eca92961bd9ca2ced297c1c21dce31e8a4 (patch) | |
tree | e9f6b6f0e42b0485762a32913f318cae108cc52b | |
parent | af1378a8e70f0cf5a7810961464826cf01841d7d (diff) | |
download | trove-ce8014eca92961bd9ca2ced297c1c21dce31e8a4.tar.gz |
Add doc for running unit tests
Change-Id: Ib6a55b65767e89eb5411783934aa3cc362505dcb
-rw-r--r-- | doc/source/contributor/testing.rst | 112 |
1 files changed, 42 insertions, 70 deletions
diff --git a/doc/source/contributor/testing.rst b/doc/source/contributor/testing.rst index ad33a90f..8cedfbbf 100644 --- a/doc/source/contributor/testing.rst +++ b/doc/source/contributor/testing.rst @@ -1,8 +1,8 @@ .. _testing: -========================= -Notes on Trove Unit Tests -========================= +================ +Trove Unit Tests +================ Mock Object Library ------------------- @@ -12,7 +12,7 @@ This library lets the caller replace (*"mock"*) parts of the system under test w mock objects and make assertions about how they have been used. [1]_ The Problem of Dangling Mocks ------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Often one needs to mock global functions in shared system modules. The caller must restore the original state of the module @@ -42,7 +42,7 @@ mock objects (see the section on recommended patterns). Further information is available in [1]_, [2]_, [3]_. Dangling Mock Detector ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ All Trove unit tests should extend 'trove_testtools.TestCase'. It is a subclass of 'testtools.TestCase' which automatically checks for @@ -50,98 +50,70 @@ dangling mock objects at each test class teardown. It marks the tests as failed and reports the leaked reference if it finds any. -Recommended Mocking Patterns ----------------------------- +Writing Unit Tests +------------------ +Trove has some legacy unit test code for all the components which is not +recommended to follow. Use the suggested approaches below. -Mocking a class or object shared across multiple test cases. -Use the patcher pattern in conjunction with the setUp() -method [ see section 26.4.3.5. of [1]_ ]. +Writing Unit Tests for Trove API +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For trove-api unit test, we use real database (sqlite). + +Set up trove database in ``setUpClass`` method. .. code-block:: python - def setUp(self): - super(CouchbaseBackupTests, self).setUp() - self.exe_timeout_patch = patch.object(utils, 'execute_with_timeout') - self.addCleanup(self.exe_timeout_patch.stop) + from trove.tests.unittests.util import util - def test_case(self): - mock_exe_timeout = self.exe_timeout_patch.start() + @classmethod + def setUpClass(cls): + util.init_db() -If the mock object is required in the majority of test cases the following -pattern may be more efficient. +and clean up the database in the method ``tearDownClass``: .. code-block:: python - def setUp(self): - super(CouchbaseBackupTests, self).setUp() - self.exe_timeout_patch = patch.object(utils, 'execute_with_timeout') - self.addCleanup(self.exe_timeout_patch.stop) - self.mock_exe_timeout = self.exe_timeout_patch.start() + from trove.tests.unittests.util import util - def test_case(self): - # All test cases can now reference 'self.mock_exe_timeout'. + @classmethod + def tearDownClass(cls): + util.cleanup_db() -- Note also: patch.stopall() - This method stops all active patches that were started with start. +Insert some data in ``setUpClass`` in order to run the tests. -Mocking a class or object for a single entire test case. -Use the decorator pattern. +Trove sends notifications for various operations which communicates with +the message queue service. In unit test, this is also mocked and usually +called in the ``setUp`` method. .. code-block:: python - @patch.object(utils, 'execute_with_timeout') - @patch.object(os, 'popen') - def test_case(self, popen_mock, execute_with_timeout_mock): - pass - - @patch.multiple(utils, execute_with_timeout=DEFAULT, - generate_random_password=MagicMock(return_value=1)) - def test_case(self, generate_random_password, execute_with_timeout): - pass - -Mocking a class or object for a smaller scope within one test case. -Use the context manager pattern. + from trove.tests.unittests import trove_testtools -.. code-block:: python + def setUp(self): + trove_testtools.patch_notifier(self) - def test_case(self): - # Some code using real implementation of 'generate_random_password'. - with patch.object(utils, 'generate_random_password') as pwd_mock: - # Using the mocked implementation of 'generate_random_password'. - # Again code using the actual implementation of the method. +Look at an example in ``trove/tests/unittests/instance/test_service.py`` - def test_case(self): - with patch.multiple(utils, execute_with_timeout_mock=DEFAULT, - generate_random_password=MagicMock( - return_value=1)) as mocks: - password_mock = mocks['generate_random_password'] - execute_mock = mocks['execute_with_timeout_mock'] +Run Unit Test +------------- -Mocking global configuration properties. -Use 'patch_conf_property' method from 'trove_testtools.TestCase'. +Run all the unit tests in one command: -.. code-block:: python +.. code-block:: console - def test_case(self): - self.patch_conf_property('max_accepted_volume_size', 10) + tox -e py38 -Datastore-specific configuration properties can be mocked by passing -an optional 'section' argument to the above call. +Run all the tests of a specific test class: -.. code-block:: python +.. code-block:: console - def test_case(self): - self.patch_conf_property('cluster_support', False, section='redis') + tox -e py38 -- trove.tests.unittests.instance.test_service.TestInstanceController -- Note also: 'patch_datastore_manager()' - 'datastore_manager' name has to be set properly when testing - datastore-specific code to ensure correct configuration options get loaded. - This is a convenience method for mocking 'datastore_manager' name. +Run a single test case: -.. code-block:: python +.. code-block:: console - def test_case(self): - self.patch_datastore_manager('cassandra') + tox -e py38 -- trove.tests.unittests.instance.test_service.TestInstanceController.test_create_multiple_versions References ---------- |