From 902efea03de528311758457c5442d50b472fc9ff Mon Sep 17 00:00:00 2001 From: Michael Hanke Date: Mon, 5 Feb 2024 13:57:27 +0100 Subject: [PATCH] Define public API of `datalad_next.tests` This pretty much takes the role of `datalad_next.tests.utils`. The new setup treats `tests` like any other sub-package and exposes reusable tools as a public API at the top-level. In doing so, `SkipTest` was made obsolete and excluded from that API. The usage of `rmtree` is altered to import from `datalad_next.utils`. For the first time, test tooling helpers have their documentation rendered too. https://github.com/datalad/datalad-next/issues/613 --- datalad_next/annexbackends/tests/test_base.py | 2 +- .../annexremotes/tests/test_archivist.py | 2 +- .../annexremotes/tests/test_uncurl.py | 2 +- .../tests/test_create_sibling_webdav.py | 2 +- .../commands/tests/test_credentials.py | 2 +- datalad_next/commands/tests/test_download.py | 2 +- .../commands/tests/test_ls_file_collection.py | 2 +- datalad_next/commands/tests/test_status.py | 2 +- datalad_next/commands/tests/test_tree.py | 2 +- datalad_next/credman/tests/test_credman.py | 2 +- .../gitremotes/tests/test_datalad_annex.py | 4 +- .../iter_collections/tests/test_iterdir.py | 6 +- .../tests/test_itergitdiff.py | 2 +- .../tests/test_itergittree.py | 2 +- .../tests/test_itergitworktree.py | 7 ++- .../iter_collections/tests/test_itertar.py | 2 +- .../iter_collections/tests/test_utils.py | 2 +- .../patches/tests/test_cli_configoverrides.py | 2 +- .../patches/tests/test_configuration.py | 5 +- datalad_next/patches/tests/test_push.py | 2 +- .../tests/test_push_to_export_remote.py | 6 +- datalad_next/patches/tests/test_run.py | 7 +-- datalad_next/tests/__init__.py | 55 +++++++++++++++++++ datalad_next/tests/fixtures.py | 17 +++--- datalad_next/tests/utils.py | 4 +- .../url_operations/tests/test_http.py | 2 +- datalad_next/url_operations/tests/test_ssh.py | 2 +- docs/source/pyutils.rst | 1 + 28 files changed, 103 insertions(+), 45 deletions(-) diff --git a/datalad_next/annexbackends/tests/test_base.py b/datalad_next/annexbackends/tests/test_base.py index 5dc065ee..9d740ec3 100644 --- a/datalad_next/annexbackends/tests/test_base.py +++ b/datalad_next/annexbackends/tests/test_base.py @@ -1,7 +1,7 @@ import logging import io -from datalad_next.tests.utils import ( +from datalad_next.tests import ( assert_raises, eq_, ) diff --git a/datalad_next/annexremotes/tests/test_archivist.py b/datalad_next/annexremotes/tests/test_archivist.py index 0972304d..7ea8a2ab 100644 --- a/datalad_next/annexremotes/tests/test_archivist.py +++ b/datalad_next/annexremotes/tests/test_archivist.py @@ -9,7 +9,7 @@ from datalad_next.datasets import Dataset from datalad_next.runners import CommandError -from datalad_next.tests.utils import assert_result_count +from datalad_next.tests import assert_result_count @pytest.fixture(autouse=False, scope="function") diff --git a/datalad_next/annexremotes/tests/test_uncurl.py b/datalad_next/annexremotes/tests/test_uncurl.py index 0ce4cfeb..c37809eb 100644 --- a/datalad_next/annexremotes/tests/test_uncurl.py +++ b/datalad_next/annexremotes/tests/test_uncurl.py @@ -3,7 +3,7 @@ import re from datalad_next.consts import on_windows -from datalad_next.tests.utils import ( +from datalad_next.tests import ( create_tree, skip_if_on_windows, skip_if_root, diff --git a/datalad_next/commands/tests/test_create_sibling_webdav.py b/datalad_next/commands/tests/test_create_sibling_webdav.py index cd222329..1a8a0cae 100644 --- a/datalad_next/commands/tests/test_create_sibling_webdav.py +++ b/datalad_next/commands/tests/test_create_sibling_webdav.py @@ -5,7 +5,7 @@ ) from urllib.parse import quote as urlquote -from datalad_next.tests.utils import ( +from datalad_next.tests import ( assert_in, assert_in_results, assert_raises, diff --git a/datalad_next/commands/tests/test_credentials.py b/datalad_next/commands/tests/test_credentials.py index 377d9d07..f2f2c2bf 100644 --- a/datalad_next/commands/tests/test_credentials.py +++ b/datalad_next/commands/tests/test_credentials.py @@ -18,7 +18,7 @@ ) from datalad_next.exceptions import IncompleteResultsError from datalad_next.utils import external_versions -from datalad_next.tests.utils import ( +from datalad_next.tests import ( assert_in, assert_in_results, assert_raises, diff --git a/datalad_next/commands/tests/test_download.py b/datalad_next/commands/tests/test_download.py index ac79a521..43d52aae 100644 --- a/datalad_next/commands/tests/test_download.py +++ b/datalad_next/commands/tests/test_download.py @@ -7,7 +7,7 @@ credentials, download, ) -from datalad_next.tests.utils import ( +from datalad_next.tests import ( assert_result_count, assert_status, ) diff --git a/datalad_next/commands/tests/test_ls_file_collection.py b/datalad_next/commands/tests/test_ls_file_collection.py index 1a3222e3..5374ae50 100644 --- a/datalad_next/commands/tests/test_ls_file_collection.py +++ b/datalad_next/commands/tests/test_ls_file_collection.py @@ -9,7 +9,7 @@ from datalad_next.constraints.exceptions import CommandParametrizationError # we need this fixture from datalad_next.iter_collections.tests.test_iterzip import sample_zip -from datalad_next.tests.marker import skipif_no_network +from datalad_next.tests import skipif_no_network from ..ls_file_collection import LsFileCollectionParamValidator diff --git a/datalad_next/commands/tests/test_status.py b/datalad_next/commands/tests/test_status.py index 55b91d24..83a4508d 100644 --- a/datalad_next/commands/tests/test_status.py +++ b/datalad_next/commands/tests/test_status.py @@ -6,7 +6,7 @@ CommandParametrizationError, ParameterConstraintContext, ) -from datalad_next.tests.utils import chpwd +from datalad_next.utils import chpwd from ..status import ( opt_eval_subdataset_state_values, diff --git a/datalad_next/commands/tests/test_tree.py b/datalad_next/commands/tests/test_tree.py index 2b5a3d4a..0b3b2158 100644 --- a/datalad_next/commands/tests/test_tree.py +++ b/datalad_next/commands/tests/test_tree.py @@ -3,7 +3,7 @@ from os import sep import pytest -from datalad_next.tests.utils import ( +from datalad_next.tests import ( BasicGitTestRepo, assert_raises, create_tree, diff --git a/datalad_next/credman/tests/test_credman.py b/datalad_next/credman/tests/test_credman.py index e781b26e..b9e6fad6 100644 --- a/datalad_next/credman/tests/test_credman.py +++ b/datalad_next/credman/tests/test_credman.py @@ -16,7 +16,7 @@ CredentialManager, _get_cred_cfg_var, ) -from datalad_next.tests.utils import ( +from datalad_next.tests import ( assert_in, assert_raises, eq_, diff --git a/datalad_next/gitremotes/tests/test_datalad_annex.py b/datalad_next/gitremotes/tests/test_datalad_annex.py index ccff18af..24d9b808 100644 --- a/datalad_next/gitremotes/tests/test_datalad_annex.py +++ b/datalad_next/gitremotes/tests/test_datalad_annex.py @@ -19,17 +19,17 @@ Dataset, clone, ) -from datalad_next.tests.utils import ( +from datalad_next.tests import ( DEFAULT_BRANCH, DEFAULT_REMOTE, assert_raises, assert_status, eq_, - rmtree, skip_if_root, ) from datalad_next.consts import on_windows from datalad_next.exceptions import CommandError +from datalad_next.utils import rmtree from ..datalad_annex import get_initremote_params_from_url diff --git a/datalad_next/iter_collections/tests/test_iterdir.py b/datalad_next/iter_collections/tests/test_iterdir.py index 57ab806d..c1b3805e 100644 --- a/datalad_next/iter_collections/tests/test_iterdir.py +++ b/datalad_next/iter_collections/tests/test_iterdir.py @@ -2,11 +2,13 @@ from pathlib import PurePath import pytest -from datalad_next.tests.utils import ( +from datalad_next.tests import ( create_tree, +) +from datalad_next.utils import ( + check_symlink_capability, rmtree, ) -from datalad_next.utils import check_symlink_capability from ..directory import ( DirectoryItem, diff --git a/datalad_next/iter_collections/tests/test_itergitdiff.py b/datalad_next/iter_collections/tests/test_itergitdiff.py index 9c639673..897b582d 100644 --- a/datalad_next/iter_collections/tests/test_itergitdiff.py +++ b/datalad_next/iter_collections/tests/test_itergitdiff.py @@ -2,7 +2,7 @@ import pytest import shutil -from datalad_next.tests.utils import rmtree +from datalad_next.utils import rmtree from ..gitdiff import ( GitTreeItemType, diff --git a/datalad_next/iter_collections/tests/test_itergittree.py b/datalad_next/iter_collections/tests/test_itergittree.py index ac6c044e..bc07b39b 100644 --- a/datalad_next/iter_collections/tests/test_itergittree.py +++ b/datalad_next/iter_collections/tests/test_itergittree.py @@ -4,7 +4,7 @@ import pytest -from datalad_next.tests.utils import rmtree +from datalad_next.utils import rmtree from ..gittree import ( GitTreeItem, diff --git a/datalad_next/iter_collections/tests/test_itergitworktree.py b/datalad_next/iter_collections/tests/test_itergitworktree.py index 26f168c2..ab4a7eb0 100644 --- a/datalad_next/iter_collections/tests/test_itergitworktree.py +++ b/datalad_next/iter_collections/tests/test_itergitworktree.py @@ -5,9 +5,10 @@ import pytest -from datalad_next.utils import check_symlink_capability - -from datalad_next.tests.utils import rmtree +from datalad_next.utils import ( + check_symlink_capability, + rmtree, +) from ..gitworktree import ( GitWorktreeItem, diff --git a/datalad_next/iter_collections/tests/test_itertar.py b/datalad_next/iter_collections/tests/test_itertar.py index d90ed33f..c01b46b0 100644 --- a/datalad_next/iter_collections/tests/test_itertar.py +++ b/datalad_next/iter_collections/tests/test_itertar.py @@ -3,7 +3,7 @@ from datalad.api import download -from datalad_next.tests.marker import skipif_no_network +from datalad_next.tests import skipif_no_network from ..tarfile import ( TarfileItem, diff --git a/datalad_next/iter_collections/tests/test_utils.py b/datalad_next/iter_collections/tests/test_utils.py index 1393431e..9d2fbcb1 100644 --- a/datalad_next/iter_collections/tests/test_utils.py +++ b/datalad_next/iter_collections/tests/test_utils.py @@ -1,4 +1,4 @@ -from datalad_next.tests.utils import skip_wo_symlink_capability +from datalad_next.tests import skip_wo_symlink_capability from ..utils import FileSystemItem diff --git a/datalad_next/patches/tests/test_cli_configoverrides.py b/datalad_next/patches/tests/test_cli_configoverrides.py index b1656e3c..d01f3bc6 100644 --- a/datalad_next/patches/tests/test_cli_configoverrides.py +++ b/datalad_next/patches/tests/test_cli_configoverrides.py @@ -1,5 +1,5 @@ from datalad_next.utils import chpwd -from datalad_next.tests.utils import run_main +from datalad_next.tests import run_main def test_cli_configoverrides(existing_dataset): diff --git a/datalad_next/patches/tests/test_configuration.py b/datalad_next/patches/tests/test_configuration.py index 66d46be6..e43e5cb0 100644 --- a/datalad_next/patches/tests/test_configuration.py +++ b/datalad_next/patches/tests/test_configuration.py @@ -1,8 +1,9 @@ -from datalad_next.tests.utils import ( +from datalad_next.tests import ( assert_in_results, assert_raises, - chpwd, ) +from datalad_next.utils import chpwd + from datalad.api import configuration from datalad_next.exceptions import IncompleteResultsError diff --git a/datalad_next/patches/tests/test_push.py b/datalad_next/patches/tests/test_push.py index a9fbb55b..aa6a5b02 100644 --- a/datalad_next/patches/tests/test_push.py +++ b/datalad_next/patches/tests/test_push.py @@ -1,4 +1,4 @@ -from datalad_next.tests.utils import ( +from datalad_next.tests import ( DEFAULT_REMOTE, assert_result_count, ) diff --git a/datalad_next/patches/tests/test_push_to_export_remote.py b/datalad_next/patches/tests/test_push_to_export_remote.py index d1d6730e..df6d3951 100644 --- a/datalad_next/patches/tests/test_push_to_export_remote.py +++ b/datalad_next/patches/tests/test_push_to_export_remote.py @@ -1,4 +1,5 @@ from pathlib import Path +import pytest from typing import Generator from unittest.mock import ( MagicMock, @@ -6,8 +7,7 @@ patch, ) -from datalad_next.tests.utils import ( - SkipTest, +from datalad_next.tests import ( assert_in, assert_in_results, eq_, @@ -230,7 +230,7 @@ def get_export_records(self): def test_is_valid_treeish(): - raise SkipTest( + pytest.skip( "this test is skipped until issue " "https://github.com/datalad/datalad-next/issues/39 is solved") diff --git a/datalad_next/patches/tests/test_run.py b/datalad_next/patches/tests/test_run.py index c1442022..19271828 100644 --- a/datalad_next/patches/tests/test_run.py +++ b/datalad_next/patches/tests/test_run.py @@ -1,10 +1,7 @@ import pytest from datalad_next.exceptions import IncompleteResultsError -from datalad_next.tests.utils import ( - SkipTest, - assert_result_count, -) +from datalad_next.tests import assert_result_count def test_substitution_config_default(existing_dataset, no_result_rendering): @@ -12,7 +9,7 @@ def test_substitution_config_default(existing_dataset, no_result_rendering): if ds.config.get('datalad.run.substitutions.python') is not None: # we want to test default handling when no config is set - raise SkipTest( + pytest.skip( 'Test assumptions conflict with effective configuration') # the {python} placeholder is not explicitly defined, but it has diff --git a/datalad_next/tests/__init__.py b/datalad_next/tests/__init__.py index e69de29b..a715e021 100644 --- a/datalad_next/tests/__init__.py +++ b/datalad_next/tests/__init__.py @@ -0,0 +1,55 @@ +"""Tooling for test implementations + +.. currentmodule:: datalad_next.tests +.. autosummary:: + :toctree: generated + + BasicGitTestRepo + DEFAULT_BRANCH + DEFAULT_REMOTE + assert_in + assert_in_results + assert_result_count + assert_status + create_tree + eq_ + get_deeply_nested_structure + ok_ + ok_good_symlink + ok_broken_symlink + run_main + skip_if_on_windows + skip_if_root + skip_wo_symlink_capability + swallow_logs + skipif_no_network +""" +# TODO `assert_raises` is excluded above to avoid syntax errors in the docstring +# rather than fixing those, we should replace it with `pytest.raises` entirely + +from .utils import ( + BasicGitTestRepo, + DEFAULT_BRANCH, + DEFAULT_REMOTE, + assert_in, + assert_in_results, + assert_raises, + assert_result_count, + assert_status, + create_tree, + eq_, + get_deeply_nested_structure, + ok_, + ok_good_symlink, + ok_broken_symlink, + run_main, + skip_if_on_windows, + skip_if_root, + skip_wo_symlink_capability, + swallow_logs, +) + + +from .marker import ( + skipif_no_network, +) diff --git a/datalad_next/tests/fixtures.py b/datalad_next/tests/fixtures.py index 8cb0d9f1..5dd66fe2 100644 --- a/datalad_next/tests/fixtures.py +++ b/datalad_next/tests/fixtures.py @@ -16,9 +16,8 @@ call_git_lines, call_git_success, ) -from datalad_next.tests.utils import ( +from .utils import ( HTTPPath, - SkipTest, WebDAVPath, assert_ssh_access, external_versions, @@ -167,7 +166,7 @@ def datalad_cfg(): here was only introduced with that version. """ if external_versions['cmd:git'] < "2.32": - raise SkipTest( + pytest.skip( "Git configuration redirect via GIT_CONFIG_GLOBAL " "only supported since Git v2.32" ) @@ -561,15 +560,15 @@ def httpbin(httpbin_service): in some cases it is simply not desirable to run a test. For example, the appveyor workers are more or less constantly unable to access the public service. This fixture is evaluated at function-scope and - raises ``SkipTest`` whenever any of these undesired conditions is + skips the test whenever any of these undesired conditions is detected. Otherwise it just relays ``httpbin_service``. """ if os.environ.get('DATALAD_TESTS_NONETWORK'): - raise SkipTest( + pytest.skip( 'Not running httpbin-based test: NONETWORK flag set' ) if 'APPVEYOR' in os.environ and 'DEPLOY_HTTPBIN_IMAGE' not in os.environ: - raise SkipTest( + pytest.skip( "Not running httpbin-based test on appveyor without " "docker-deployed instance -- too unreliable" ) @@ -591,7 +590,7 @@ def datalad_interactive_ui(monkeypatch): > assert ... datalad_interactive_ui.log """ from datalad_next.uis import ui_switcher - from datalad_next.tests.utils import InteractiveTestUI + from .utils import InteractiveTestUI with monkeypatch.context() as m: m.setattr(ui_switcher, '_ui', InteractiveTestUI()) @@ -611,7 +610,7 @@ def datalad_noninteractive_ui(monkeypatch): > assert ... datalad_interactive_ui.log """ from datalad_next.uis import ui_switcher - from datalad_next.tests.utils import TestUI + from .utils import TestUI with monkeypatch.context() as m: m.setattr(ui_switcher, '_ui', TestUI()) @@ -621,7 +620,7 @@ def datalad_noninteractive_ui(monkeypatch): @pytest.fixture(autouse=False, scope="session") def sshserver_setup(tmp_path_factory): if not os.environ.get('DATALAD_TESTS_SSH'): - raise SkipTest( + pytest.skip( "set DATALAD_TESTS_SSH=1 to enable") # query a bunch of recognized configuration environment variables, diff --git a/datalad_next/tests/utils.py b/datalad_next/tests/utils.py index 508f25a4..65d7d6aa 100644 --- a/datalad_next/tests/utils.py +++ b/datalad_next/tests/utils.py @@ -16,6 +16,7 @@ DEFAULT_BRANCH, DEFAULT_REMOTE, HTTPPath, + # TODO REMOVE FOR V2.0 SkipTest, assert_in, assert_in_results, @@ -30,6 +31,7 @@ ok_broken_symlink, ok_exists, ok_good_symlink, + # TODO REMOVE FOR V2.0 rmtree, skip_if_on_windows, skip_if_root, @@ -78,7 +80,7 @@ def __enter__(self): from cheroot import wsgi from wsgidav.wsgidav_app import WsgiDAVApp except ImportError as e: - raise SkipTest('No WSGI capabilities. Install cheroot and/or wsgidav') from e + pytest.skip(f'No WSGI capabilities. Install cheroot and/or wsgidav ({e!r})') if self.auth: auth = {self.auth[0]: {'password': self.auth[1]}} diff --git a/datalad_next/url_operations/tests/test_http.py b/datalad_next/url_operations/tests/test_http.py index 1878bfce..5eaa5255 100644 --- a/datalad_next/url_operations/tests/test_http.py +++ b/datalad_next/url_operations/tests/test_http.py @@ -4,7 +4,7 @@ import pytest import requests -from datalad_next.tests.marker import skipif_no_network +from datalad_next.tests import skipif_no_network from ..any import AnyUrlOperations from ..http import ( diff --git a/datalad_next/url_operations/tests/test_ssh.py b/datalad_next/url_operations/tests/test_ssh.py index 78905a6b..6c398d3b 100644 --- a/datalad_next/url_operations/tests/test_ssh.py +++ b/datalad_next/url_operations/tests/test_ssh.py @@ -3,7 +3,7 @@ import pytest -from datalad_next.tests.utils import ( +from datalad_next.tests import ( skip_if_on_windows, ) from ..ssh import ( diff --git a/docs/source/pyutils.rst b/docs/source/pyutils.rst index 410945fd..d6bc5c3c 100644 --- a/docs/source/pyutils.rst +++ b/docs/source/pyutils.rst @@ -26,6 +26,7 @@ packages. itertools iter_collections runners + tests tests.fixtures types uis