Skip to content

Commit

Permalink
Make apply-mocks fixture usable by all tests. Start hooks and fixture…
Browse files Browse the repository at this point in the history
…s modules for pytest, loaded using conftest.py in the script tests directory.
  • Loading branch information
AlexVCaron committed Dec 19, 2022
1 parent 31d34ca commit 7566bcf
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 29 deletions.
9 changes: 8 additions & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,11 @@ filterwarnings =
once:::statsmodels
once:::dmri-commit
once:::cvxpy
once:::dmri-amico
once:::dmri-amico

usefixtures =
apply_mocks

required_plugins =
pytest_console_scripts
pytest-mock
1 change: 1 addition & 0 deletions scilpy/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

15 changes: 15 additions & 0 deletions scilpy/tests/checks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import numpy as np


def assert_images_close(img1, img2):
dtype = img1.header.get_data_dtype()

assert np.allclose(img1.affine, img2.affine), "Images affines don't match"

assert np.allclose(
img1.get_fdata(dtype=dtype), img2.get_fdata(dtype=dtype)), \
"Images data don't match. MSE : {} | max SE : {}".format(
np.mean((img1.get_fdata(dtype=dtype) -
img2.get_fdata(dtype=dtype)) ** 2.),
np.max((img1.get_fdata(dtype=dtype) -
img2.get_fdata(dtype=dtype)) ** 2.))
6 changes: 6 additions & 0 deletions scilpy/tests/fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import pytest


@pytest.fixture(scope="session")
def apply_mocks(request):
return request.config.getoption("--apply-mocks")
10 changes: 10 additions & 0 deletions scilpy/tests/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import pytest


def pytest_addoption(parser):
parser.addoption(
"--apply-mocks",
action="store_true",
help="Apply mocks to accelerate tests and "
"prevent testing external dependencies"
)
6 changes: 6 additions & 0 deletions scripts/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import pytest

pytest_plugins = [
"scilpy.tests.fixtures",
"scilpy.tests.hooks"
]
77 changes: 49 additions & 28 deletions scripts/tests/test_execute_angle_aware_bilateral_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import os
import pytest
import tempfile
from shutil import copyfile

from scilpy.io.fetcher import get_testing_files_dict, fetch_data, get_home
from scilpy.tests.checks import assert_images_close


# If they already exist, this only takes 5 seconds (check md5sum)
Expand All @@ -16,16 +18,20 @@
tmp_dir = tempfile.TemporaryDirectory()


@pytest.fixture
def mock_filtering(mocker, out_fodf):
def _mock(*args, **kwargs):
img = nib.load(out_fodf)
return img.get_fdata().astype(np.float32)
@pytest.fixture(scope='function')
def filter_mock(mocker, apply_mocks, out_fodf):
if apply_mocks:
def _mock_side_effect(*args, **kwargs):
img = nib.load(out_fodf)
return img.get_fdata(dtype=np.float32)

script = 'scil_execute_angle_aware_bilateral_filtering'
filtering_fn = "angle_aware_bilateral_filtering"
return mocker.patch("scripts.{}.{}".format(script, filtering_fn),
side_effect=_mock, create=True)
return mocker.patch(
"{}.{}".format(
"scripts.scil_execute_angle_aware_bilateral_filtering",
"angle_aware_bilateral_filtering"),
side_effect=_mock_side_effect, create=True)

return None


def test_help_option(script_runner):
Expand All @@ -36,8 +42,10 @@ def test_help_option(script_runner):

@pytest.mark.parametrize("in_fodf,out_fodf",
[[os.path.join(data_path, 'fodf_descoteaux07_sub.nii.gz'),
os.path.join(data_path, 'fodf_descoteaux07_sub_full.nii.gz')]])
def test_asym_basis_output(script_runner, mock_filtering, in_fodf, out_fodf):
os.path.join(data_path, 'fodf_descoteaux07_sub_full.nii.gz')]],
scope='function')
def test_asym_basis_output(
script_runner, filter_mock, apply_mocks, in_fodf, out_fodf):
os.chdir(os.path.expanduser(tmp_dir.name))

ret = script_runner.run('scil_execute_angle_aware_bilateral_filtering.py',
Expand All @@ -52,19 +60,23 @@ def test_asym_basis_output(script_runner, mock_filtering, in_fodf, out_fodf):
print_result=True, shell=True)

assert ret.success
mock_filtering.assert_called_once()

ret_fodf = nib.load("out_fodf1.nii.gz")
test_fodf = nib.load(out_fodf)
assert np.allclose(ret_fodf.get_fdata(), test_fodf.get_fdata())
if apply_mocks:
filter_mock.assert_called_once()

copyfile(in_fodf, "/mnt/d/in_fodf1.nii.gz")
copyfile("out_fodf1.nii.gz", "/mnt/d/out_fodf1.nii.gz")
copyfile(out_fodf, "/mnt/d/out_fodf1_cmp.nii.gz")
assert_images_close(nib.load(out_fodf), nib.load("out_fodf1.nii.gz"))


@pytest.mark.parametrize("in_fodf,out_fodf,sym_fodf",
[[os.path.join(data_path, "fodf_descoteaux07_sub.nii.gz"),
os.path.join(data_path, "fodf_descoteaux07_sub_full.nii.gz"),
os.path.join(data_path, "fodf_descoteaux07_sub_sym.nii.gz")]])
os.path.join(data_path, "fodf_descoteaux07_sub_sym.nii.gz")]],
scope='function')
def test_sym_basis_output(
script_runner, mock_filtering, in_fodf, out_fodf, sym_fodf):
script_runner, filter_mock, apply_mocks, in_fodf, out_fodf, sym_fodf):
os.chdir(os.path.expanduser(tmp_dir.name))

ret = script_runner.run('scil_execute_angle_aware_bilateral_filtering.py',
Expand All @@ -80,17 +92,23 @@ def test_sym_basis_output(
print_result=True, shell=True)

assert ret.success
mock_filtering.assert_called_once()

ret_sym_fodf = nib.load("out_sym.nii.gz")
test_sym_fodf = nib.load(sym_fodf)
assert np.allclose(ret_sym_fodf.get_fdata(), test_sym_fodf.get_fdata())
if apply_mocks:
filter_mock.assert_called_once()

copyfile(in_fodf, "/mnt/d/in_fodf2.nii.gz")
copyfile("out_fodf2.nii.gz", "/mnt/d/out_fodf2.nii.gz")
copyfile(out_fodf, "/mnt/d/out_fodf2_cmp.nii.gz")
copyfile("out_sym.nii.gz", "/mnt/d/out_sym.nii.gz")
copyfile(sym_fodf, "/mnt/d/out_sym_cmp.nii.gz")
assert_images_close(nib.load(sym_fodf), nib.load("out_sym.nii.gz"))


@pytest.mark.parametrize("in_fodf,out_fodf",
[[os.path.join(data_path, "fodf_descoteaux07_sub_full.nii.gz"),
os.path.join(data_path, "fodf_descoteaux07_sub_twice.nii.gz")]])
def test_asym_input(script_runner, mock_filtering, in_fodf, out_fodf):
os.path.join(data_path, "fodf_descoteaux07_sub_twice.nii.gz")]],
scope='function')
def test_asym_input(script_runner, filter_mock, apply_mocks, in_fodf, out_fodf):
os.chdir(os.path.expanduser(tmp_dir.name))

ret = script_runner.run('scil_execute_angle_aware_bilateral_filtering.py',
Expand All @@ -105,8 +123,11 @@ def test_asym_input(script_runner, mock_filtering, in_fodf, out_fodf):
print_result=True, shell=True)

assert ret.success
mock_filtering.assert_called_once()

ret_fodf = nib.load("out_fodf3.nii.gz")
test_fodf = nib.load(out_fodf)
assert np.allclose(ret_fodf.get_fdata(), test_fodf.get_fdata())

if apply_mocks:
filter_mock.assert_called_once()

copyfile(in_fodf, "/mnt/d/in_fodf3.nii.gz")
copyfile("out_fodf3.nii.gz", "/mnt/d/out_fodf3.nii.gz")
copyfile(out_fodf, "/mnt/d/out_fodf3_cmp.nii.gz")
assert_images_close(nib.load(out_fodf), nib.load("out_fodf3.nii.gz"))

0 comments on commit 7566bcf

Please sign in to comment.