From ffee6511675cf5d61019247eaece39a008f1b191 Mon Sep 17 00:00:00 2001 From: sfmig <33267254+sfmig@users.noreply.github.com> Date: Thu, 11 Jan 2024 11:41:37 +0000 Subject: [PATCH] Workflow tests caching (#62) * pass all parameters to cellfinder_run * changed required, optional and internal fields. read_config passes. add method to config class (WIP) * add signal and background data from local * add missing data config fixtures * mark GIN download data test as slow * refactor config class methods and remove setup_workflow * tests pass with default config * remove unused fixtures * update entry point * change cellfinder-core to cellfinder in pyproject * update cellfinder to cellfinder_core * renaming cellfinder script workflow to cellfinder_core. fix entrypoint test. * docstrings for class config * fix entry point * skip add input paths test * split tests with and without CLI inputs * all tests passing with default config * all tests passing with default option * make all paths input strings. move methods to class. make some fixtures dict. simplify other fixtures * refactor setup_workflow * cosmetic changes to fixtures * remove spurious monkeypatched cwd from merge * add skips that were removed in merge * move fixtures to code where they are used * bring back default_input_config_cellfinder fixture * finalise adding local config as parameter in test_read_cellfinder_config * add local config to remaining unit tests * add local config and GIN config to test main * monkeypatched home in integration tests (only works in main) * skip tests that use subprocess for now * monkeypatch pooch.retrieve when forcing download * make config local fixture copy downloaded GIN data (rather than re-download again) * fix output dir definition * docstrings and remove merge artifact * fill in docstrings * add GIN default location as a fixture * remove commented out GIN default location * remove tests for running script (monkeypatched home function not passed to subprocess, and all subsequent steps already tested) * replace entry point test for smoketest * fixes from rebase * fix ruff --- .../cellfinder_core/cellfinder_core.py | 4 +- brainglobe_workflows/utils.py | 23 +- pyproject.toml | 2 +- tests/cellfinder_core/conftest.py | 240 +++++++++++- .../test_integration/test_cellfinder.py | 88 ++--- tests/cellfinder_core/test_unit/conftest.py | 4 +- .../test_unit/test_cellfinder.py | 349 ++++++++++++------ tests/cellfinder_core/test_unit/test_utils.py | 7 + 8 files changed, 514 insertions(+), 203 deletions(-) diff --git a/brainglobe_workflows/cellfinder_core/cellfinder_core.py b/brainglobe_workflows/cellfinder_core/cellfinder_core.py index d16e958c..65a94257 100644 --- a/brainglobe_workflows/cellfinder_core/cellfinder_core.py +++ b/brainglobe_workflows/cellfinder_core/cellfinder_core.py @@ -10,9 +10,9 @@ Example usage: - to pass a custom configuration, run (from the cellfinder_main.py parent directory): - python cellfinder_main.py --config path/to/input/config.json + python cellfinder_core.py --config path/to/input/config.json - to use the default configuration, run - python cellfinder_main.py + python cellfinder_core.py """ diff --git a/brainglobe_workflows/utils.py b/brainglobe_workflows/utils.py index 4b3bdac3..9f1eb8d5 100644 --- a/brainglobe_workflows/utils.py +++ b/brainglobe_workflows/utils.py @@ -70,14 +70,23 @@ def config_parser( # initialise argument parser parser = argparse.ArgumentParser( description=( - "To launch the workflow with " - "a specific set of input parameters, run: " - "`python brainglobe_workflows/cellfinder.py " - "--config path/to/config.json`" - "where path/to/input/config.json is the json file " - "containing the workflow parameters." - ) + """ + To launch the cellfinder workflow with default parameters, run: + `cellfinder-workflow`. + The default parameters are those specifed in brainglobe_workflows/ + cellfinder_core/configs/cellfinder.json. + + + To launch the cellfinder workflow with a specific set of input + parameters, run: + `cellfinder-workflow --config path/to/config.json`, + where `path/to/input/config.json` is the json file with the + desired parameters. + """ + ), + formatter_class=argparse.RawTextHelpFormatter, ) + # add arguments parser.add_argument( "-c", diff --git a/pyproject.toml b/pyproject.toml index 6ba3d3ce..809eed3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ "Topic :: Scientific/Engineering :: Image Recognition", ] -# Below the dependenciess for brainmapper (the cellfinder CLI tool) only +# Below the dependencies for brainmapper (the cellfinder CLI tool) only # (i.e., only what users will need for brainmapper) dependencies = [ "brainglobe>=1.0.0", diff --git a/tests/cellfinder_core/conftest.py b/tests/cellfinder_core/conftest.py index 127a4483..f683d617 100644 --- a/tests/cellfinder_core/conftest.py +++ b/tests/cellfinder_core/conftest.py @@ -1,13 +1,47 @@ """Pytest fixtures shared across unit and integration tests""" + +import json from pathlib import Path +import pooch import pytest +@pytest.fixture(autouse=True) +def mock_home_directory(monkeypatch: pytest.MonkeyPatch): + """ + Monkeypatch pathlib.Path.home() + + Instead of returning the usual home path, the + monkeypatched version returns the path to + Path.home() / ".brainglobe-tests" + + Parameters + ---------- + monkeypatch : pytest.MonkeyPatch + a monkeypatch fixture + """ + # define mock home path + home_path = Path.home() # actual home path + mock_home_path = home_path / ".brainglobe-tests" + + # create mock home directory if it doesn't exist + if not mock_home_path.exists(): + mock_home_path.mkdir() + + # monkeypatch Path.home() to point to the mock home + def mock_home(): + return mock_home_path + + monkeypatch.setattr(Path, "home", mock_home) + + @pytest.fixture() def default_input_config_cellfinder() -> Path: - """Return path to default input config for cellfinder workflow + """ + Fixture for the path to the default input + configuration file for the cellfinder workflow Returns ------- @@ -20,18 +54,198 @@ def default_input_config_cellfinder() -> Path: return DEFAULT_JSON_CONFIG_PATH_CELLFINDER -@pytest.fixture(autouse=True) -def mock_home_directory(monkeypatch: pytest.MonkeyPatch): - # define mock home path - home_path = Path.home() # actual home path - mock_home_path = home_path / ".brainglobe-tests" # tmp_path # +@pytest.fixture(scope="session") +def cellfinder_GIN_data() -> dict: + """ + Fixture for the location of the test data in the GIN repository - # create dir if it doesn't exist - if not mock_home_path.exists(): - mock_home_path.mkdir() + Returns + ------- + dict + URL and hash of the GIN repository with the cellfinder test data + """ + return { + "url": "https://gin.g-node.org/BrainGlobe/test-data/raw/master/cellfinder/cellfinder-test-data.zip", + "hash": "b0ef53b1530e4fa3128fcc0a752d0751909eab129d701f384fc0ea5f138c5914", # noqa + } - # monkeypatch Path.home() to point to the mock home - def mock_home(): - return mock_home_path - monkeypatch.setattr(Path, "home", mock_home) +@pytest.fixture() +def GIN_default_location() -> Path: + """A fixture returning a path to the default location + where GIN data is downloaded. + + Returns + ------- + Path + path to the default location where to download GIN data + """ + + return ( + Path.home() + / ".brainglobe" + / "workflows" + / "cellfinder_core" + / "cellfinder_test_data" + ) + + +@pytest.fixture() +def config_GIN_dict( + cellfinder_GIN_data: dict, + default_input_config_cellfinder: Path, + GIN_default_location: Path, +) -> dict: + """ + Fixture that returns a config as a dictionary, pointing to the location + where the GIN data would be by default, and download the data there. + + If the file exists in the given path and the hash matches, pooch.retrieve() + will not download the file and instead its path is returned. + + Parameters + ---------- + cellfinder_GIN_data : dict + dictionary with the location of the test data in the GIN repository + default_input_config_cellfinder : Path + path to the default input configuration file for the cellfinder + workflow + GIN_default_location : Path + path to the default location where to download GIN data + + Returns + ------- + dict + dictionary with the config for a workflow that uses the downloaded + GIN data + """ + + # read default config as a dictionary + with open(default_input_config_cellfinder) as cfg: + config_dict = json.load(cfg) + + # modify the default config: + # - add url + # - add data hash + # - remove input_data_dir if present + config_dict["data_url"] = cellfinder_GIN_data["url"] + config_dict["data_hash"] = cellfinder_GIN_data["hash"] + if "input_data_dir" in config_dict.keys(): + del config_dict["input_data_dir"] + + # download GIN data to default location for GIN + # if the file exists in the given path and the hash matches, + # it will not be downloaded and the absolute path to the file is returned. + pooch.retrieve( + url=cellfinder_GIN_data["url"], + known_hash=cellfinder_GIN_data["hash"], + path=GIN_default_location.parent, # path to download zip to + progressbar=True, + processor=pooch.Unzip(extract_dir=GIN_default_location.stem), + ) + + return config_dict + + +@pytest.fixture() +def config_local_dict( + config_GIN_dict: dict, + GIN_default_location: Path, +) -> dict: + """ + Fixture that returns a config as a dictionary, pointing to a local dataset. + + The data is copied to the local directory from the + default location used in the config_GIN_dict fixture. + + Parameters + ---------- + config_GIN_dict : dict + dictionary with the config for a workflow that uses the downloaded + GIN data + GIN_default_location : Path + path to the default location where to download GIN data\ + + Returns + ------- + dict + dictionary with the config for a workflow that uses local data + """ + import shutil + + # copy GIN config as a dictionary + config_dict = config_GIN_dict.copy() + + # modify the GIN config: + # - remove url + # - remove data hash + # - set input data directory to a local directory under home + config_dict["data_url"] = None + config_dict["data_hash"] = None + config_dict["input_data_dir"] = str(Path.home() / "local_cellfinder_data") + + # copy data from default GIN location to the local location + shutil.copytree( + GIN_default_location, + config_dict["input_data_dir"], + dirs_exist_ok=True, + ) + + return config_dict + + +@pytest.fixture() +def config_GIN_json(config_GIN_dict: dict, tmp_path: Path) -> Path: + """ + Fixture that returns a config as a JSON file path, that points to GIN + downloaded data as input + + Parameters + ---------- + config_GIN_dict : dict + dictionary with the config for a workflow that uses the downloaded + GIN data + tmp_path : Path + Pytest fixture providing a temporary path + + Returns + ------- + Path + path to a cellfinder config JSON file + """ + # define location of input config file + config_file_path = tmp_path / "input_config.json" + + # write config dict to that location + with open(config_file_path, "w") as js: + json.dump(config_GIN_dict, js) + + return config_file_path + + +@pytest.fixture() +def config_local_json(config_local_dict: dict, tmp_path: Path) -> Path: + """ + Fixture that returns config as a JSON file path, that points to local data + as input + + Parameters + ---------- + config_local_dict : dict + _description_ + tmp_path : Path + Pytest fixture providing a temporary path + + Returns + ------- + Path + path to a cellfinder config JSON file + """ + # define location of input config file + config_file_path = tmp_path / "input_config.json" + + # write config dict to that location + with open(config_file_path, "w") as js: + json.dump(config_local_dict, js) + + return config_file_path diff --git a/tests/cellfinder_core/test_integration/test_cellfinder.py b/tests/cellfinder_core/test_integration/test_cellfinder.py index 26f22ec8..9af0c0b0 100644 --- a/tests/cellfinder_core/test_integration/test_cellfinder.py +++ b/tests/cellfinder_core/test_integration/test_cellfinder.py @@ -1,24 +1,18 @@ import subprocess -import sys from pathlib import Path +from typing import Optional -from brainglobe_workflows.cellfinder_core.cellfinder_core import main +import pytest def test_main(): - """Test main function for setting up and running cellfinder workflow - - Parameters - ---------- - input_config : Optional[str] - Path to input config json file - monkeypatch : pytest.MonkeyPatch - Pytest fixture to use monkeypatching utils - tmp_path : Path - Pytest fixture providing a temporary path for each test - request : pytest.FixtureRequest - Pytest fixture to enable requesting fixtures by name """ + Test main function for setting up and running cellfinder workflow + with no inputs + """ + # import inside the test function so that required functions are + # monkeypatched first + from brainglobe_workflows.cellfinder_core.cellfinder_core import main # run main cfg = main() @@ -27,61 +21,47 @@ def test_main(): assert Path(cfg._detected_cells_path).is_file() -def test_script(): - """Test running the cellfinder worklfow from the command line +@pytest.mark.parametrize( + "input_config", + [ + "config_local_json", + "config_GIN_json", + ], +) +def test_main_w_inputs( + input_config: Optional[str], + request: pytest.FixtureRequest, +): + """ + Test main function for setting up and running cellfinder workflow + with inputs Parameters ---------- input_config : Optional[str] - Path to input config json file - monkeypatch : pytest.MonkeyPatch - Pytest fixture to use monkeypatching utils - tmp_path : Path - Pytest fixture providing a temporary path for each test + Path to input config JSON file request : pytest.FixtureRequest Pytest fixture to enable requesting fixtures by name """ + from brainglobe_workflows.cellfinder_core.cellfinder_core import main - # define CLI input - script_path = ( - Path(__file__).resolve().parents[3] - / "brainglobe_workflows" - / "cellfinder_core" - / "cellfinder_core.py" - ) - subprocess_input = [ - sys.executable, - str(script_path), - ] - - # run workflow script from the CLI - subprocess_output = subprocess.run( - subprocess_input, - ) - - # check returncode - assert subprocess_output.returncode == 0 + # run main + cfg = main(str(request.getfixturevalue(input_config))) + # check output files exist + assert Path(cfg._detected_cells_path).is_file() -def test_entry_point(): - """Test running the cellfinder workflow via the predefined entry point - Parameters - ---------- - input_config : Optional[str] - Path to input config json file - monkeypatch : pytest.MonkeyPatch - Pytest fixture to use monkeypatching utils - tmp_path : Path - Pytest fixture providing a temporary path for each test - request : pytest.FixtureRequest - Pytest fixture to enable requesting fixtures by name +def test_entry_point_help(): + """ + Smoke test the cellfinder workflow entry point by checking + help is printed out successfully """ # define CLI input - subprocess_input = ["cellfinder-workflow"] + subprocess_input = ["cellfinder-workflow", "--help"] - # run workflow with no CLI arguments, + # run workflow subprocess_output = subprocess.run( subprocess_input, ) diff --git a/tests/cellfinder_core/test_unit/conftest.py b/tests/cellfinder_core/test_unit/conftest.py index 57492be5..ae85bc53 100644 --- a/tests/cellfinder_core/test_unit/conftest.py +++ b/tests/cellfinder_core/test_unit/conftest.py @@ -10,8 +10,6 @@ def custom_logger_name() -> str: str Name of custom logger """ - from brainglobe_workflows.utils import ( - __name__ as logger_name, - ) + from brainglobe_workflows.utils import __name__ as logger_name return logger_name diff --git a/tests/cellfinder_core/test_unit/test_cellfinder.py b/tests/cellfinder_core/test_unit/test_cellfinder.py index d31cfb91..e300c743 100644 --- a/tests/cellfinder_core/test_unit/test_cellfinder.py +++ b/tests/cellfinder_core/test_unit/test_cellfinder.py @@ -3,85 +3,247 @@ import re from pathlib import Path -import pooch import pytest from brainglobe_workflows.utils import setup_logger -@pytest.fixture(scope="session") -def cellfinder_GIN_data() -> dict: - """Return the URL and hash to the GIN repository with the input data +@pytest.fixture() +def config_force_GIN_dict( + config_GIN_dict: dict, + tmp_path: Path, + GIN_default_location: Path, + monkeypatch: pytest.MonkeyPatch, +) -> dict: + """ + Fixture returning a config as a dictionary, which has a + Pytest-generated temporary directory as input data location, + and that monkeypatches pooch.retrieve() + + Since there is no data at the input_data_dir location, the GIN download + will be triggered, but the monkeypatched pooch.retrieve() will copy the + files rather than download them. + + Parameters + ---------- + config_GIN_dict : dict + dictionary with the config for a workflow that uses the downloaded + GIN data + tmp_path : Path + path to pytest-generated temporary directory + GIN_default_location : Path + path to the default location where to download GIN data + monkeypatch : pytest.MonkeyPatch + a monkeypatch fixture Returns ------- dict - URL and hash of the GIN repository with the cellfinder test data + dictionary with the config for a workflow that triggers the downloaded + GIN data """ - return { - "url": "https://gin.g-node.org/BrainGlobe/test-data/raw/master/cellfinder/cellfinder-test-data.zip", - "hash": "b0ef53b1530e4fa3128fcc0a752d0751909eab129d701f384fc0ea5f138c5914", # noqa - } + + import shutil + + import pooch + + # read GIN config as dict + config_dict = config_GIN_dict.copy() + + # point to a temporary directory in input_data_dir + config_dict["input_data_dir"] = str(tmp_path) + + # monkeypatch pooch.retrieve() + # when called copy GIN downloaded data, instead of downloading it + def mock_pooch_download( + url="", known_hash="", path="", progressbar="", processor="" + ): + # Copy destination + GIN_copy_destination = tmp_path + + # copy only relevant subdirectories + for subdir in ["signal", "background"]: + shutil.copytree( + GIN_default_location / subdir, # src + GIN_copy_destination / subdir, # dest + dirs_exist_ok=True, + ) + + # List of files in destination + list_of_files = [ + str(f) for f in GIN_copy_destination.glob("**/*") if f.is_file() + ] + list_of_files.sort() + + return list_of_files + + # monkeypatch pooch.retreive with mock_pooch_download() + monkeypatch.setattr(pooch, "retrieve", mock_pooch_download) + + return config_dict @pytest.fixture() -def config_local(cellfinder_GIN_data, default_input_config_cellfinder): - """ """ +def config_missing_signal_dict(config_local_dict: dict) -> dict: + """ + Fixture that returns a config as a dictionary, pointing to a local dataset, + whose signal directory does not exist - from brainglobe_workflows.cellfinder_core.cellfinder_core import ( - CellfinderConfig, - ) + Parameters + ---------- + config_local_dict : _type_ + dictionary with the config for a workflow that uses local data - # read default config as dict - # as dict because some paths are computed derived from input_data_dir - with open(default_input_config_cellfinder) as cfg: - config_dict = json.load(cfg) + Returns + ------- + dict + dictionary with the config for a workflow that uses local data, but + whose signal directory does not exist. + """ + config_dict = config_local_dict.copy() + config_dict["signal_subdir"] = "_" + + return config_dict + + +@pytest.fixture() +def config_missing_background_dict(config_local_dict: dict) -> dict: + """ + Fixture that returns a config as a dictionary, pointing to a local dataset, + whose background directory does not exist + + Parameters + ---------- + config_local_dict : dict + dictionary with the config for a workflow that uses local data + + Returns + ------- + dict + dictionary with the config for a workflow that uses local data, but + whose background directory does not exist. + """ + config_dict = config_local_dict.copy() + config_dict["background_subdir"] = "_" + + return config_dict + + +@pytest.fixture() +def config_not_GIN_nor_local_dict(config_local_dict: dict) -> dict: + """ + Fixture that returns a config as a dictionary, whose input_data_dir + directory does not exist and with no references to a GIN dataset. + + Parameters + ---------- + config_local_dict : dict + dictionary with the config for a workflow that uses local data + + Returns + ------- + dict + dictionary with the config for a workflow that uses local data, but + whose input_data_dir directory does not exist and with no references + to a GIN dataset. + """ + config_dict = config_local_dict.copy() + config_dict["input_data_dir"] = "_" - # modify config: - # - remove url - # - remove data hash - # - add input_data_dir config_dict["data_url"] = None config_dict["data_hash"] = None - config_dict["input_data_dir"] = Path.home() / "local_cellfinder_data" - - # instantiate object - config = CellfinderConfig(**config_dict) - - # fetch data from GIN and download locally to local location? - pooch.retrieve( - url=cellfinder_GIN_data["url"], - known_hash=cellfinder_GIN_data["hash"], - path=Path(config.input_data_dir).parent, # path to download zip to - progressbar=True, - processor=pooch.Unzip( - extract_dir=Path(config.input_data_dir).stem - # path to unzipped dir, *relative* to 'path' + + return config_dict + + +@pytest.mark.parametrize( + "input_config_dict, message_pattern", + [ + ( + "config_force_GIN_dict", + "Fetching input data from the provided GIN repository", + ), + ( + "config_local_dict", + "Fetching input data from the local directories", + ), + ( + "config_missing_signal_dict", + "The directory .+ does not exist$", ), + ("config_missing_background_dict", "The directory .+ does not exist$"), + ( + "config_not_GIN_nor_local_dict", + "Input data not found locally, and URL/hash to " + "GIN repository not provided", + ), + ], +) +def test_add_input_paths( + caplog: pytest.LogCaptureFixture, + input_config_dict: dict, + message_pattern: str, + request: pytest.FixtureRequest, +): + """ + Test the addition of signal and background files to the cellfinder config + + Parameters + ---------- + caplog : pytest.LogCaptureFixture + Pytest fixture to capture the logs during testing + input_config_dict : dict + input config as a dict + message_pattern : str + Expected pattern in the log + request : pytest.FixtureRequest + Pytest fixture to enable requesting fixtures by name + """ + + from brainglobe_workflows.cellfinder_core.cellfinder_core import ( + CellfinderConfig, ) - return config + + # instantiate custom logger + _ = setup_logger() + + # instantiate config object + _ = CellfinderConfig(**request.getfixturevalue(input_config_dict)) + + # check log messages + assert len(caplog.messages) > 0 + out = re.fullmatch(message_pattern, caplog.messages[-1]) + assert out is not None + assert out.group() is not None @pytest.mark.parametrize( - "input_config, message", + "input_config_path, message", [ ("default_input_config_cellfinder", "Using default config file"), + ("config_local_json", "Input config read from"), ], ) def test_read_cellfinder_config( - input_config: str, + input_config_path: str, message: str, caplog: pytest.LogCaptureFixture, request: pytest.FixtureRequest, ): - """Test for reading a cellfinder config file + """ + Test reading a cellfinder config Parameters ---------- - input_config : str - Name of input config json file - input_configs_dir : Path - Test data directory path + input_config_path : str + path to input config file + message : str + Expected message in the log + caplog : pytest.LogCaptureFixture + Pytest fixture to capture the logs during testing + request : pytest.FixtureRequest + Pytest fixture to enable requesting fixtures by name + """ from brainglobe_workflows.cellfinder_core.cellfinder_core import ( read_cellfinder_config, @@ -90,13 +252,13 @@ def test_read_cellfinder_config( # instantiate custom logger _ = setup_logger() - input_config_path = request.getfixturevalue(input_config) - - # read json as Cellfinder config - config = read_cellfinder_config(input_config_path, log_on=True) + # read Cellfinder config + config = read_cellfinder_config( + request.getfixturevalue(input_config_path), log_on=True + ) # read json as dict - with open(input_config_path) as cfg: + with open(request.getfixturevalue(input_config_path)) as cfg: config_dict = json.load(cfg) # check keys of dictionary are a subset of Cellfinder config attributes @@ -133,66 +295,19 @@ def test_read_cellfinder_config( ) -@pytest.mark.skip(reason="focus of PR62") -@pytest.mark.parametrize( - "input_config, message_pattern", - [ - ( - "config_local", - "Fetching input data from the local directories", - ), - ], -) -def test_add_input_paths( - caplog: pytest.LogCaptureFixture, - input_config: str, - message_pattern: str, - request: pytest.FixtureRequest, -): - """Test signal and background files addition to the cellfinder config - - Parameters - ---------- - caplog : pytest.LogCaptureFixture - Pytest fixture to capture the logs during testing - cellfinder_GIN_data : dict - Dict holding the URL and hash of the cellfinder test data in GIN - input_configs_dir : Path - Test data directory path - input_config : str - Name of input config json file - message_pattern : str - Expected pattern in the log - """ - - # instantiate custom logger - _ = setup_logger() - - # read json as Cellfinder config - _ = request.getfixturevalue(input_config) - - # check log messages - assert len(caplog.messages) > 0 - out = re.fullmatch(message_pattern, caplog.messages[-1]) - assert out is not None - assert out.group() is not None - - @pytest.mark.parametrize( "input_config", [ "default_input_config_cellfinder", + "config_local_json", + "config_GIN_json", ], ) def test_setup( - input_config: str, - custom_logger_name: str, - monkeypatch: pytest.MonkeyPatch, - tmp_path: Path, - request: pytest.FixtureRequest, + input_config: str, custom_logger_name: str, request: pytest.FixtureRequest ): - """Test full setup for cellfinder workflow, using the default config - and passing a specific config file. + """ + Test the full setup for the cellfinder workflow. Parameters ---------- @@ -200,10 +315,6 @@ def test_setup( Path to input config file custom_logger_name : str Name of custom logger - monkeypatch : MonkeyPatch - Pytest fixture to use monkeypatching utils - tmp_path : Path - Pytest fixture providing a temporary path for each test request : pytest.FixtureRequest Pytest fixture to enable requesting fixtures by name """ @@ -211,16 +322,11 @@ def test_setup( CellfinderConfig, ) from brainglobe_workflows.cellfinder_core.cellfinder_core import ( - setup as setup_full, + setup as setup_workflow, ) - # Monkeypatch to change current directory to - # pytest temporary directory - # (cellfinder cache directory is created in cwd) - monkeypatch.chdir(tmp_path) - # run setup on default configuration - cfg = setup_full(request.getfixturevalue(input_config)) + cfg = setup_workflow(str(request.getfixturevalue(input_config))) # check logger exists logger = logging.getLogger(custom_logger_name) @@ -235,23 +341,20 @@ def test_setup( "input_config", [ "default_input_config_cellfinder", + "config_local_json", + "config_GIN_json", ], ) def test_run_workflow_from_cellfinder_run( - input_config: str, - request: pytest.FixtureRequest, + input_config: str, request: pytest.FixtureRequest ): - """Test running cellfinder workflow with default input config - (fetches data from GIN) and local input config + """ + Test running cellfinder workflow Parameters ---------- input_config : str Path to input config json file - monkeypatch : MonkeyPatch - Pytest fixture to use monkeypatching utils - tmp_path : Path - Pytest fixture providing a temporary path for each test request : pytest.FixtureRequest Pytest fixture to enable requesting fixtures by name """ @@ -259,14 +362,14 @@ def test_run_workflow_from_cellfinder_run( run_workflow_from_cellfinder_run, ) from brainglobe_workflows.cellfinder_core.cellfinder_core import ( - setup as setup_full, + setup as setup_workflow, ) # run setup - cfg = setup_full(str(request.getfixturevalue(input_config))) + cfg = setup_workflow(str(request.getfixturevalue(input_config))) # run workflow run_workflow_from_cellfinder_run(cfg) - # check output files are those expected? + # check output files exist assert Path(cfg._detected_cells_path).is_file() diff --git a/tests/cellfinder_core/test_unit/test_utils.py b/tests/cellfinder_core/test_unit/test_utils.py index 2ec8d19e..f857912f 100644 --- a/tests/cellfinder_core/test_unit/test_utils.py +++ b/tests/cellfinder_core/test_unit/test_utils.py @@ -31,6 +31,13 @@ def test_setup_logger(custom_logger_name: str): [[], ["--config", str(DEFAULT_JSON_CONFIG_PATH_CELLFINDER)]], ) def test_config_parser(list_input_args: List[str]): + """Test parser for config argument + + Parameters + ---------- + list_input_args : List[str] + a list with the command-line input arguments + """ args = config_parser( list_input_args, str(DEFAULT_JSON_CONFIG_PATH_CELLFINDER),