diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 0645c3d..7fe1e69 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -48,7 +48,11 @@ jobs: - name: Install dependencies run: | - pip install pytest pytest-cov + # pip install pytest pytest-cov + # Waiting pip supports `--only-deps=test`, explicitly extract the test dependencies + # See https://github.com/pypa/pip/issues/11440 + pip install yq + tomlq -r '.project."optional-dependencies".test[]' pyproject.toml | xargs -d '\n' pip install - uses: actions/download-artifact@v4 with: diff --git a/pyproject.toml b/pyproject.toml index ec16de7..fa665e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ dependencies = [] [project.optional-dependencies] test = [ + "importlib_metadata>=2.0; python_version<'3.10'", "pytest >=6", "pytest-cov >=3", ] @@ -116,6 +117,9 @@ module = "dcmqi.*" disallow_untyped_defs = true disallow_incomplete_defs = true +[[tool.mypy.overrides]] +module = "tests.*" +ignore_errors = true [tool.ruff] src = ["src"] diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..681931a --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +import sys +from contextlib import contextmanager + + +@contextmanager +def push_argv(argv): + old_argv = sys.argv + sys.argv = argv + yield + sys.argv = old_argv \ No newline at end of file diff --git a/tests/test_executable.py b/tests/test_executable.py new file mode 100644 index 0000000..fcdbc94 --- /dev/null +++ b/tests/test_executable.py @@ -0,0 +1,60 @@ +import subprocess +import sys +import sysconfig +from pathlib import Path + +import pytest + +if sys.version_info < (3, 10): + from importlib_metadata import distribution +else: + from importlib.metadata import distribution + +import dcmqi + +from . import push_argv + +all_tools_version = pytest.mark.parametrize("tool,expected_version", [ + ("itkimage2segimage", "1.0"), + ("segimage2itkimage", "1.0"), + ("tid1500writer", "1.0"), + ("tid1500reader", "1.0"), + ("itkimage2paramap", "1.0"), + ("paramap2itkimage", "1.0")] +) + +def _get_scripts(): + dist = distribution("dcmqi") + scripts_paths = [ + Path(sysconfig.get_path("scripts", scheme)).resolve() + for scheme in sysconfig.get_scheme_names() + ] + scripts = [] + for file in dist.files: + if file.locate().parent.resolve(strict=True) in scripts_paths: + scripts.append(file.locate().resolve(strict=True)) + return scripts + + +@all_tools_version +def test_package_script(tool, expected_version): + """ + Example of the output for tid1500writer (analogous for the other tools): + + tid1500writer --version + dcmqi repository URL: https://github.com/QIICR/dcmqi revision: 1922a09 tag: v1.3.1 + + /home/leonard/miniconda3/envs/dcmqi_pypi_test/lib/python3.8/site-packages/dcmqi/bin/tid1500writer version: 1.0 + """ + scripts = [script for script in _get_scripts() if script.stem == tool] + assert len(scripts) == 1 + output = subprocess.check_output([str(scripts[0]), "--version"]).decode("ascii") + assert output.splitlines()[2].split(" ")[1] == f"version: {expected_version}" + +@all_tools_version +def test_module(tool, expected_version): + func = getattr(dcmqi, tool) + args = [f"{tool}.py", "--version"] + with push_argv(args), pytest.raises(SystemExit) as excinfo: + func() + assert excinfo.value.code == 0 diff --git a/tests/test_package.py b/tests/test_package.py index 4aef4e6..6a3bbb7 100644 --- a/tests/test_package.py +++ b/tests/test_package.py @@ -2,46 +2,8 @@ import importlib.metadata -import pytest - import dcmqi as m def test_version(): assert importlib.metadata.version("dcmqi") == m.__version__ - - -def test_itkimage2segimage(): - with pytest.raises(SystemExit) as e: - m.itkimage2segimage() - assert e.value.code == 1 - - -def test_segimage2itkimage(): - with pytest.raises(SystemExit) as e: - m.segimage2itkimage() - assert e.value.code == 1 - - -def test_tid1500writer(): - with pytest.raises(SystemExit) as e: - m.tid1500writer() - assert e.value.code == 1 - - -def test_tid1500reader(): - with pytest.raises(SystemExit) as e: - m.tid1500reader() - assert e.value.code == 1 - - -def test_itkimage2paramap(): - with pytest.raises(SystemExit) as e: - m.itkimage2paramap() - assert e.value.code == 1 - - -def test_paramap2itkimage(): - with pytest.raises(SystemExit) as e: - m.paramap2itkimage() - assert e.value.code == 1