From 2439669f0440f8e3f4d1bfeeac6e36c8611995be Mon Sep 17 00:00:00 2001 From: Nils Hamerlinck Date: Sun, 3 Jan 2021 19:31:16 +0700 Subject: [PATCH 1/5] [FIX] run doctests as part of standard tests --- queue_job/tests/common.py | 40 ++++++++++++++++++++++++- queue_job/tests/test_runner_channels.py | 7 ++--- queue_job/tests/test_runner_runner.py | 7 ++--- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/queue_job/tests/common.py b/queue_job/tests/common.py index cdb2e4e8e3..1391b10996 100644 --- a/queue_job/tests/common.py +++ b/queue_job/tests/common.py @@ -1,10 +1,14 @@ # Copyright 2019 Camptocamp # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import doctest from contextlib import contextmanager import mock -from ..job import Job +from odoo.tests import BaseCase, tagged + +# pylint: disable=odoo-addons-relative-import +from odoo.addons.queue_job.job import Job class JobCounter: @@ -96,3 +100,37 @@ def test_export(self): delayable = mock.MagicMock(name="DelayableBinding") delayable_cls.return_value = delayable yield delayable_cls, delayable + + +@tagged("doctest") +class OdooDocTestCase(BaseCase): + """ + We need a custom DocTestCase class in order to: + - define test_tags to run as part of standard tests + - output a more meaningful test name than default "DocTestCase.runTest" + """ + + __qualname__ = "doctests for " + + def __init__(self, test): + self.__test = test + self.__name = test._dt_test.name + super().__init__(self.__name) + + def __getattr__(self, item): + if item == self.__name: + return self.__test + + +def load_doctests(module): + """ + Generates a tests loading method for the doctests of the given module + https://docs.python.org/3/library/unittest.html#load-tests-protocol + """ + + def load_tests(loader, tests, ignore): + for test in doctest.DocTestSuite(module): + tests.addTest(OdooDocTestCase(test)) + return tests + + return load_tests diff --git a/queue_job/tests/test_runner_channels.py b/queue_job/tests/test_runner_channels.py index 93333fa490..d323d00683 100644 --- a/queue_job/tests/test_runner_channels.py +++ b/queue_job/tests/test_runner_channels.py @@ -1,13 +1,10 @@ # Copyright 2015-2016 Camptocamp SA # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) -import doctest - # pylint: disable=odoo-addons-relative-import # we are testing, we want to test as we were an external consumer of the API from odoo.addons.queue_job.jobrunner import channels +from .common import load_doctests -def load_tests(loader, tests, ignore): - tests.addTests(doctest.DocTestSuite(channels)) - return tests +load_tests = load_doctests(channels) diff --git a/queue_job/tests/test_runner_runner.py b/queue_job/tests/test_runner_runner.py index 817ac6396e..c6486e27ef 100644 --- a/queue_job/tests/test_runner_runner.py +++ b/queue_job/tests/test_runner_runner.py @@ -1,13 +1,10 @@ # Copyright 2015-2016 Camptocamp SA # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) -import doctest - # pylint: disable=odoo-addons-relative-import # we are testing, we want to test as we were an external consumer of the API from odoo.addons.queue_job.jobrunner import runner +from .common import load_doctests -def load_tests(loader, tests, ignore): - tests.addTests(doctest.DocTestSuite(runner)) - return tests +load_tests = load_doctests(runner) From 45ace9b10e042d42e95e4951c083fd9322562377 Mon Sep 17 00:00:00 2001 From: Pieter Paulussen Date: Wed, 21 Apr 2021 10:53:55 +0200 Subject: [PATCH 2/5] [FIX] add test tags to DocTestCase since failures are not registered correctly with OdooDocTestCase --- queue_job/tests/common.py | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/queue_job/tests/common.py b/queue_job/tests/common.py index 1391b10996..99aa27ac7c 100644 --- a/queue_job/tests/common.py +++ b/queue_job/tests/common.py @@ -5,8 +5,6 @@ import mock -from odoo.tests import BaseCase, tagged - # pylint: disable=odoo-addons-relative-import from odoo.addons.queue_job.job import Job @@ -102,26 +100,6 @@ def test_export(self): yield delayable_cls, delayable -@tagged("doctest") -class OdooDocTestCase(BaseCase): - """ - We need a custom DocTestCase class in order to: - - define test_tags to run as part of standard tests - - output a more meaningful test name than default "DocTestCase.runTest" - """ - - __qualname__ = "doctests for " - - def __init__(self, test): - self.__test = test - self.__name = test._dt_test.name - super().__init__(self.__name) - - def __getattr__(self, item): - if item == self.__name: - return self.__test - - def load_doctests(module): """ Generates a tests loading method for the doctests of the given module @@ -129,8 +107,12 @@ def load_doctests(module): """ def load_tests(loader, tests, ignore): - for test in doctest.DocTestSuite(module): - tests.addTest(OdooDocTestCase(test)) + """ + Apply the 'test_tags' attribute to each DocTestCase found by the DocTestSuite + """ + tests.addTests(doctest.DocTestSuite(module)) + for test in tests: + test.test_tags = {"standard", "at_install", "queue_job", "doctests"} return tests return load_tests From 69837153782f2a081bb18df5dc090d7b1205674a Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Wed, 21 Apr 2021 14:40:43 +0200 Subject: [PATCH 3/5] [FIX] Patch Python 3.8 class teardown API to doctest --- queue_job/tests/common.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/queue_job/tests/common.py b/queue_job/tests/common.py index 99aa27ac7c..6971ed0c5d 100644 --- a/queue_job/tests/common.py +++ b/queue_job/tests/common.py @@ -1,6 +1,7 @@ # Copyright 2019 Camptocamp # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import doctest +import sys from contextlib import contextmanager import mock @@ -108,8 +109,13 @@ def load_doctests(module): def load_tests(loader, tests, ignore): """ - Apply the 'test_tags' attribute to each DocTestCase found by the DocTestSuite + Apply the 'test_tags' attribute to each DocTestCase found by the DocTestSuite. + Also extend the DocTestCase class trivially to fit the class teardown + that Odoo backported for its own test classes from Python 3.8. """ + if sys.version_info < (3, 8): + doctest.DocTestCase.doClassCleanups = lambda: None + doctest.DocTestCase.tearDown_exceptions = [] tests.addTests(doctest.DocTestSuite(module)) for test in tests: test.test_tags = {"standard", "at_install", "queue_job", "doctests"} From 53e8743e1624fc9367c444b478ee5c897ada19a6 Mon Sep 17 00:00:00 2001 From: Pieter Paulussen Date: Thu, 29 Apr 2021 13:10:50 +0200 Subject: [PATCH 4/5] [FIX] Ouput a clear log statement when starting the doctest --- queue_job/tests/common.py | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/queue_job/tests/common.py b/queue_job/tests/common.py index 6971ed0c5d..fd7ccc2f8d 100644 --- a/queue_job/tests/common.py +++ b/queue_job/tests/common.py @@ -1,6 +1,7 @@ # Copyright 2019 Camptocamp # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import doctest +import logging import sys from contextlib import contextmanager @@ -101,6 +102,28 @@ def test_export(self): yield delayable_cls, delayable +class OdooDocTestCase(doctest.DocTestCase): + """ + We need a custom DocTestCase class in order to: + - define test_tags to run as part of standard tests + - output a more meaningful test name than default "DocTestCase.runTest" + """ + + def __init__(self, doctest, optionflags=0, setUp=None, tearDown=None, checker=None): + super().__init__( + doctest._dt_test, + optionflags=optionflags, + setUp=setUp, + tearDown=tearDown, + checker=checker, + ) + + def setUp(self): + """Log an extra statement which test is started.""" + super(OdooDocTestCase, self).setUp() + logging.getLogger(__name__).info("Running tests for %s", self._dt_test.name) + + def load_doctests(module): """ Generates a tests loading method for the doctests of the given module @@ -116,9 +139,12 @@ def load_tests(loader, tests, ignore): if sys.version_info < (3, 8): doctest.DocTestCase.doClassCleanups = lambda: None doctest.DocTestCase.tearDown_exceptions = [] - tests.addTests(doctest.DocTestSuite(module)) - for test in tests: - test.test_tags = {"standard", "at_install", "queue_job", "doctests"} + + for test in doctest.DocTestSuite(module): + odoo_test = OdooDocTestCase(test) + odoo_test.test_tags = {"standard", "at_install", "queue_job", "doctest"} + tests.addTest(odoo_test) + return tests return load_tests From faf222eee524b7527c6e5822862f8d211055844f Mon Sep 17 00:00:00 2001 From: Pieter Paulussen Date: Mon, 3 May 2021 15:46:24 +0200 Subject: [PATCH 5/5] [FIX] Restore use of relative import --- queue_job/tests/common.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/queue_job/tests/common.py b/queue_job/tests/common.py index fd7ccc2f8d..e1e877b0a2 100644 --- a/queue_job/tests/common.py +++ b/queue_job/tests/common.py @@ -7,8 +7,7 @@ import mock -# pylint: disable=odoo-addons-relative-import -from odoo.addons.queue_job.job import Job +from ..job import Job class JobCounter: