diff --git a/modules/account_fr_chorus/tests/test_scenario.py b/modules/account_fr_chorus/tests/test_scenario.py index 3ee52b344c..79930da5a2 100644 --- a/modules/account_fr_chorus/tests/test_scenario.py +++ b/modules/account_fr_chorus/tests/test_scenario.py @@ -3,13 +3,17 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if (os.getenv('CHORUS_PISTE_CLIENT_ID') - and os.getenv('CHORUS_PISTE_CLIENT_SECRET') - and os.getenv('CHORUS_LOGIN') - and os.getenv('CHORUS_PASSWORD') - and os.getenv('CHORUS_COMPANY_SIRET') - and os.getenv('CHORUS_CUSTOMER_SIRET')): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('CHORUS_PISTE_CLIENT_ID') + and os.getenv('CHORUS_PISTE_CLIENT_SECRET') + and os.getenv('CHORUS_LOGIN') + and os.getenv('CHORUS_PASSWORD') + and os.getenv('CHORUS_COMPANY_SIRET') + and os.getenv('CHORUS_CUSTOMER_SIRET'))): + kwargs.setdefault('skips', set()).add( + 'scenario_account_fr_chorus_invoice.rst') + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/account_payment_braintree/tests/test_scenario.py b/modules/account_payment_braintree/tests/test_scenario.py index b3e4e848c9..70d0c816f4 100644 --- a/modules/account_payment_braintree/tests/test_scenario.py +++ b/modules/account_payment_braintree/tests/test_scenario.py @@ -3,10 +3,14 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if (os.getenv('BRAINTREE_MERCHANT_ID') - and os.getenv('BRAINTREE_PUBLIC_KEY') - and os.getenv('BRAINTREE_PRIVATE_KEY')): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('BRAINTREE_MERCHANT_ID') + and os.getenv('BRAINTREE_PUBLIC_KEY') + and os.getenv('BRAINTREE_PRIVATE_KEY'))): + kwargs.setdefault('skips', set()).add( + 'scenario_account_payment_braintree.rst') + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/account_payment_stripe/tests/test_scenario.py b/modules/account_payment_stripe/tests/test_scenario.py index 54d46817a4..c9071a8c0a 100644 --- a/modules/account_payment_stripe/tests/test_scenario.py +++ b/modules/account_payment_stripe/tests/test_scenario.py @@ -3,9 +3,17 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if (os.getenv('STRIPE_SECRET_KEY') - and os.getenv('STRIPE_PUBLISHABLE_KEY')): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('STRIPE_SECRET_KEY') + and os.getenv('STRIPE_PUBLISHABLE_KEY'))): + kwargs.setdefault('skips', set()).update({ + 'scenario_account_payment_stripe.rst', + 'scenario_account_payment_stripe_dispute.rst', + 'scenario_account_payment_stripe_identical.rst', + 'scenario_account_payment_stripe_intent.rst', + }) + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/country/tests/test_scenario.py b/modules/country/tests/test_scenario.py index dc1d23e7e5..e4dfead9df 100644 --- a/modules/country/tests/test_scenario.py +++ b/modules/country/tests/test_scenario.py @@ -1,8 +1,10 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests def load_tests(*args, **kwargs): + if not TEST_NETWORK: + kwargs.setdefault('skips', set()).add('scenario_country_import.rst') return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/currency/tests/test_scenario.py b/modules/currency/tests/test_scenario.py index dc1d23e7e5..58d321c0c9 100644 --- a/modules/currency/tests/test_scenario.py +++ b/modules/currency/tests/test_scenario.py @@ -1,8 +1,10 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests def load_tests(*args, **kwargs): + if not TEST_NETWORK: + kwargs.setdefault('skips', set()).add('scenario_currency_import.rst') return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/currency_ro/tests/test_scenario.py b/modules/currency_ro/tests/test_scenario.py index dc1d23e7e5..91115c72d6 100644 --- a/modules/currency_ro/tests/test_scenario.py +++ b/modules/currency_ro/tests/test_scenario.py @@ -1,8 +1,10 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests def load_tests(*args, **kwargs): + if not TEST_NETWORK: + kwargs.setdefault('skips', set()).add('scenario_currency_ro.rst') return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/currency_rs/tests/test_scenario.py b/modules/currency_rs/tests/test_scenario.py index 02d551d711..08e98e7a98 100644 --- a/modules/currency_rs/tests/test_scenario.py +++ b/modules/currency_rs/tests/test_scenario.py @@ -3,10 +3,13 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if (os.getenv('NBS_RS_USERNAME') - and os.getenv('NBS_RS_PASSWORD') - and os.getenv('NBS_RS_LICENSE_ID')): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('NBS_RS_USERNAME') + and os.getenv('NBS_RS_PASSWORD') + and os.getenv('NBS_RS_LICENSE_ID'))): + kwargs.setdefault('skips', set()).add('scenario_currency_rs.rst') + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/document_incoming_ocr_typless/tests/test_scenario.py b/modules/document_incoming_ocr_typless/tests/test_scenario.py index 6c3e2b0556..085b927b01 100644 --- a/modules/document_incoming_ocr_typless/tests/test_scenario.py +++ b/modules/document_incoming_ocr_typless/tests/test_scenario.py @@ -3,9 +3,13 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if (os.getenv('TYPLESS_API_KEY') - and os.getenv('TYPLESS_DOCUMENT_TYPE')): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('TYPLESS_API_KEY') + and os.getenv('TYPLESS_DOCUMENT_TYPE'))): + kwargs.setdefault('skips', set()).add( + 'scenario_document_incoming_ocr_typless.rst') + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/product_image/tests/test_module.py b/modules/product_image/tests/test_module.py index 6e41f14600..67f16cbfd9 100644 --- a/modules/product_image/tests/test_module.py +++ b/modules/product_image/tests/test_module.py @@ -1,18 +1,21 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import io +import unittest import urllib.request import PIL.Image from trytond.pool import Pool -from trytond.tests.test_tryton import ModuleTestCase, with_transaction +from trytond.tests.test_tryton import ( + TEST_NETWORK, ModuleTestCase, with_transaction) class ProductImageTestCase(ModuleTestCase): 'Test Product Image module' module = 'product_image' + @unittest.skipUnless(TEST_NETWORK, "requires network") @with_transaction() def test_image_square(self): "Test image square" @@ -43,6 +46,7 @@ class ProductImageTestCase(ModuleTestCase): img = PIL.Image.open(io.BytesIO(image.get(size=(150, 200)))) self.assertEqual(img.size, (150, 150)) + @unittest.skipUnless(TEST_NETWORK, "requires network") @with_transaction() def test_image_non_square(self): "Test image non square" @@ -89,6 +93,7 @@ class ProductImageTestCase(ModuleTestCase): with self.subTest(size=size): self.assertEqual(Image._round_size(size), result) + @unittest.skipUnless(TEST_NETWORK, "requires network") @with_transaction() def test_get_image_url(self): "Test get_image_url" diff --git a/modules/product_image_attribute/tests/test_module.py b/modules/product_image_attribute/tests/test_module.py index 9d602ae316..5e38b10bd4 100644 --- a/modules/product_image_attribute/tests/test_module.py +++ b/modules/product_image_attribute/tests/test_module.py @@ -1,15 +1,18 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. +import unittest import urllib.request from trytond.pool import Pool -from trytond.tests.test_tryton import ModuleTestCase, with_transaction +from trytond.tests.test_tryton import ( + TEST_NETWORK, ModuleTestCase, with_transaction) class ProductImageAttributeTestCase(ModuleTestCase): 'Test Product Image Attribute module' module = 'product_image_attribute' + @unittest.skipUnless(TEST_NETWORK, "requires network") @with_transaction() def test_image_attribute(self): "Test image with attribute" diff --git a/modules/stock_package_shipping_dpd/tests/test_scenario.py b/modules/stock_package_shipping_dpd/tests/test_scenario.py index a32779e0c7..9c0db3521b 100644 --- a/modules/stock_package_shipping_dpd/tests/test_scenario.py +++ b/modules/stock_package_shipping_dpd/tests/test_scenario.py @@ -3,8 +3,11 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if os.getenv('DPD_USER_ID') and os.getenv('DPD_PASSWORD'): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('DPD_USER_ID') and os.getenv('DPD_PASSWORD'))): + kwargs.setdefault('skips', set()).add('scenario_shipping_dpd.rst') + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/stock_package_shipping_mygls/tests/test_scenario.py b/modules/stock_package_shipping_mygls/tests/test_scenario.py index 31fa2fd652..7b84c9c0e8 100644 --- a/modules/stock_package_shipping_mygls/tests/test_scenario.py +++ b/modules/stock_package_shipping_mygls/tests/test_scenario.py @@ -3,10 +3,14 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if (os.getenv('MYGLS_USERNAME') - and os.getenv('MYGLS_PASSWORD') - and os.getenv('MYGLS_CLIENT_NUMBER')): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('MYGLS_USERNAME') + and os.getenv('MYGLS_PASSWORD') + and os.getenv('MYGLS_CLIENT_NUMBER'))): + kwargs.setdefault('skips', set()).add( + 'scenario_stock_package_shipping_mygls.rst') + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/stock_package_shipping_sendcloud/tests/test_scenario.py b/modules/stock_package_shipping_sendcloud/tests/test_scenario.py index a1a5c197f4..787e6aaccb 100644 --- a/modules/stock_package_shipping_sendcloud/tests/test_scenario.py +++ b/modules/stock_package_shipping_sendcloud/tests/test_scenario.py @@ -3,9 +3,13 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if (os.getenv('SENDCLOUD_PUBLIC_KEY') - and os.getenv('SENDCLOUD_SECRET_KEY')): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('SENDCLOUD_PUBLIC_KEY') + and os.getenv('SENDCLOUD_SECRET_KEY'))): + kwargs.setdefault('skips', set()).add( + 'scenario_stock_package_shipping_sendcloud.rst') + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/stock_package_shipping_ups/tests/test_scenario.py b/modules/stock_package_shipping_ups/tests/test_scenario.py index fb52637c17..2fda2be23d 100644 --- a/modules/stock_package_shipping_ups/tests/test_scenario.py +++ b/modules/stock_package_shipping_ups/tests/test_scenario.py @@ -3,10 +3,13 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if (os.getenv('UPS_CLIENT_ID') - and os.getenv('UPS_CLIENT_SECRET') - and os.getenv('UPS_ACCOUNT_NUMBER')): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('UPS_CLIENT_ID') + and os.getenv('UPS_CLIENT_SECRET') + and os.getenv('UPS_ACCOUNT_NUMBER'))): + kwargs.setdefault('skips', set()).add('scenario_shipping_ups.rst') + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/modules/web_shop_shopify/tests/test_scenario.py b/modules/web_shop_shopify/tests/test_scenario.py index 6b9f6c423f..a6bf3011ee 100644 --- a/modules/web_shop_shopify/tests/test_scenario.py +++ b/modules/web_shop_shopify/tests/test_scenario.py @@ -3,8 +3,15 @@ import os -from trytond.tests.test_tryton import load_doc_tests +from trytond.tests.test_tryton import TEST_NETWORK, load_doc_tests -if os.getenv('SHOPIFY_PASSWORD') and os.getenv('SHOPIFY_URL'): - def load_tests(*args, **kwargs): - return load_doc_tests(__name__, __file__, *args, **kwargs) + +def load_tests(*args, **kwargs): + if (not TEST_NETWORK + or not (os.getenv('SHOPIFY_PASSWORD') + and os.getenv('SHOPIFY_URL'))): + kwargs.setdefault('skips', set()).update({ + 'scenario_web_shop_shopify.rst', + 'scenario_web_shop_shopify_secondary_unit.rst', + }) + return load_doc_tests(__name__, __file__, *args, **kwargs) diff --git a/trytond/CHANGELOG b/trytond/CHANGELOG index 2bbe5920ea..89243e8dee 100644 --- a/trytond/CHANGELOG +++ b/trytond/CHANGELOG @@ -1,3 +1,4 @@ +* Add option to skip tests that require network * Add language support per field in export data * Add translated descriptor for Char and Text fields * Include row and column in error message when importing data diff --git a/trytond/doc/ref/tests.rst b/trytond/doc/ref/tests.rst index 1a9a94ad60..7dd78730ec 100644 --- a/trytond/doc/ref/tests.rst +++ b/trytond/doc/ref/tests.rst @@ -17,6 +17,11 @@ Tests The context used to test the transactions +.. attribute:: TEST_NETWORK + + If false, tests that requires network are skipped. + Its value is taken from the environment variable of the same name. + .. function:: activate_module(name) Activate the named module for the tested database. @@ -135,7 +140,7 @@ doctest helpers A specialized doctest checker to ensure the Python compatibility. -.. function:: load_doc_tests(name, path, loader, tests, pattern) +.. function:: load_doc_tests(name, path, loader, tests, pattern[, skips]) An helper that follows the ``load_tests`` protocol to load as :py:class:`~doctest.DocTest` all ``*.rst`` files in ``directory``, @@ -143,6 +148,7 @@ doctest helpers doc tests are registered. If a file with the same name but the extension ``.json`` exists, the test is registered for each globals defined in the JSON list. + ``skips`` constains the name of the scenario to skip. .. function:: suite() diff --git a/trytond/trytond/tests/test_tryton.py b/trytond/trytond/tests/test_tryton.py index a49a79360a..9773395286 100644 --- a/trytond/trytond/tests/test_tryton.py +++ b/trytond/trytond/tests/test_tryton.py @@ -76,6 +76,7 @@ def _cpu_count(): DB_CACHE_JOBS = os.environ.get('DB_CACHE_JOBS', str(_cpu_count())) +TEST_NETWORK = bool(int(os.getenv('TEST_NETWORK', 1))) def activate_module(modules, lang='en'): @@ -1117,13 +1118,14 @@ class OutputChecker(doctest.OutputChecker): doctest_checker = OutputChecker() -def load_doc_tests(name, path, loader, tests, pattern): +def load_doc_tests(name, path, loader, tests, pattern, skips=None): def shouldIncludeScenario(path): return ( loader.testNamePatterns is None or any( fnmatchcase(path, pattern) for pattern in loader.testNamePatterns)) + skips = set() if skips is None else set(skips) directory = os.path.dirname(path) # TODO: replace by glob root_dir in Python 3.10 cwd = os.getcwd() @@ -1143,12 +1145,13 @@ def load_doc_tests(name, path, loader, tests, pattern): configs = json.load(fp) else: configs = [{}] + s_optionflags = doctest.SKIP if scenario in skips else optionflags for globs in configs: tests.addTests(doctest.DocFileSuite( scenario, package=name, globs=globs, tearDown=doctest_teardown, encoding='utf-8', checker=doctest_checker, - optionflags=optionflags)) + optionflags=s_optionflags)) finally: os.chdir(cwd) return tests