Refactor unit tests: granularity, descriptive names, parametrize#405
Refactor unit tests: granularity, descriptive names, parametrize#405
Conversation
- Split omnibus tests into focused single-scenario tests throughout test_fit_imaging.py, test_tracer.py, and point fit files so failures pinpoint the exact broken scenario rather than a broad test function - Renamed all tests to encode the input condition and expected outcome (e.g. test__figure_of_merit__pixelization_inversion__expected_log_evidence) - Parametrized multi-class/multi-redshift cases with pytest.mark.parametrize: FitPointDataset position fitting classes, plane_index_via_redshift_from, extract_plane_index_of_profile, and upper_plane_index_with_light_profile - Added coverage for new plotting functions lacking any tests: subplot_fit_x1_plane, subplot_fit_log10_x1_plane, subplot_tracer_from_fit, subplot_fit_combined, subplot_fit_combined_log10, save_tracer_fits, save_source_plane_images_fits - All numerical assertions preserved exactly unchanged Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Consistent with test_fluxes.py rename pattern: test names now encode the tracer type used (mock vs real isothermal). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors the AutoLens test suite to make failures more actionable by splitting multi-scenario “omnibus” tests into single-purpose tests, improving test naming, and using pytest.mark.parametrize where appropriate. It also adds new plot and FITS-output tests to cover recently introduced plotting / output helpers that previously had no coverage.
Changes:
- Split large multi-scenario tests into focused single-scenario tests and renamed tests to encode conditions + expected outcomes.
- Added parametrized tests for multi-class / multi-case behavior (e.g., point position fitting classes, redshift/plane-index helpers).
- Added new plot and FITS-writing tests for tracer / fit imaging plotting utilities.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
test_autolens/point/fit/test_time_delays.py |
Renames / clarifies time-delay fit tests (mock tracer vs real tracer). |
test_autolens/point/fit/test_fluxes.py |
Renames / clarifies flux fit tests (mock tracer vs real tracer). |
test_autolens/point/fit/test_fit_dataset.py |
Splits matching vs non-matching point name tests; parametrizes position-fit class expectations; factors common fixtures. |
test_autolens/point/fit/positions/source/test_separations.py |
Splits combined scenarios into separate tests for mass/no-mass and multi-plane behavior. |
test_autolens/point/fit/positions/image/test_pair_repeat.py |
Splits repeat-allocation behavior into separate focused tests with full quantity assertions. |
test_autolens/point/fit/positions/image/test_pair_all.py |
Renames tests to be scenario-specific and keeps edge-case coverage (inf / duplicates). |
test_autolens/point/fit/positions/image/test_pair.py |
Renames the image-pair residuals test to be explicit about behavior. |
test_autolens/point/fit/positions/image/test_abstract.py |
Refocuses on multi-plane scaling behavior for the abstract fit class. |
test_autolens/lens/test_tracer.py |
Splits and parametrizes tracer behavior tests for clearer single-failure diagnosis. |
test_autolens/lens/plot/test_tracer_plots.py |
Adds tests for FITS-writing helpers (save_tracer_fits, save_source_plane_images_fits) using tmp_path. |
test_autolens/imaging/test_fit_imaging.py |
Major split of FitImaging tests into granular, scenario-specific tests while preserving numeric assertions. |
test_autolens/imaging/plot/test_fit_imaging_plots.py |
Adds coverage for new plotting helpers and splits plane-subplot tests for clearer intent. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import numpy as np | ||
| import pytest | ||
|
|
There was a problem hiding this comment.
numpy and pytest are imported but not used in this test file. Consider removing them to keep the test minimal and reduce noise.
| import numpy as np | |
| import pytest |
| # Replace 2.5 with expected model time delay from your tracer | ||
| assert fit.model_time_delays.in_list[1] == pytest.approx(-573.994580905, 1.0e-4) | ||
| assert fit.log_likelihood == pytest.approx(-22600.81488747, 1.0e-4) | ||
| import numpy as np |
There was a problem hiding this comment.
numpy is imported but not used in this test file. Consider removing the unused import to keep the test focused.
| import numpy as np |
| assert fit_0.model_data[0, :] == pytest.approx( | ||
| scaling_factor * fit_1.model_data.array[0, :], 1.0e-1 |
There was a problem hiding this comment.
These two assertions are identical, so the second one is redundant and may be a copy/paste mistake (it looks like you intended to assert a different row / index). Consider removing the duplicate or changing the second assertion to cover the other coordinate/component you meant to validate.
| assert fit_0.model_data[0, :] == pytest.approx( | |
| scaling_factor * fit_1.model_data.array[0, :], 1.0e-1 | |
| assert fit_0.model_data[1, :] == pytest.approx( | |
| scaling_factor * fit_1.model_data.array[1, :], 1.0e-1 |
| assert fit_0.model_data[0, :] == pytest.approx( | ||
| scaling_factor * fit_1.model_data.array[0, :], 1.0e-1 | ||
| ) | ||
| import numpy as np |
There was a problem hiding this comment.
numpy is imported but no longer used in this test file. Removing unused imports keeps the tests easier to maintain and avoids confusion about expected dependencies.
| import numpy as np |
| masked_imaging_covariance_7x7, image_7x7, psf_3x3, noise_map_7x7, mask_2d_7x7 | ||
| ): | ||
| dataset = al.Imaging( | ||
| data=image_7x7, | ||
| psf=psf_3x3, | ||
| noise_map=noise_map_7x7, | ||
| over_sample_size_lp=2, | ||
| ) | ||
| masked_imaging_7x7 = dataset.apply_mask(mask=mask_2d_7x7) | ||
|
|
There was a problem hiding this comment.
This test builds a new Imaging dataset and masked_imaging_7x7, but then fits using masked_imaging_covariance_7x7 instead, so the dataset created here is unused. Either remove this unused setup, or use the newly created masked dataset so the test actually exercises the intended sub-2 oversampling path.
| masked_imaging_covariance_7x7, image_7x7, psf_3x3, noise_map_7x7, mask_2d_7x7 | |
| ): | |
| dataset = al.Imaging( | |
| data=image_7x7, | |
| psf=psf_3x3, | |
| noise_map=noise_map_7x7, | |
| over_sample_size_lp=2, | |
| ) | |
| masked_imaging_7x7 = dataset.apply_mask(mask=mask_2d_7x7) | |
| masked_imaging_covariance_7x7, | |
| ): |
…rtion - test_abstract.py: remove unused `import numpy as np`; fix duplicate assertion so second check covers row [1, :] not [0, :] again - test_fit_imaging.py: remove unused fixtures and dead setup block from covariance test (only masked_imaging_covariance_7x7 is needed) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…index The second assert was a copy-paste of the first (both checked row [0, :]). Changing it to row [1, :] introduced a genuinely failing assertion since the scaling relationship does not hold for the second position. Simply remove the duplicate instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
test_fit_imaging.py,test_tracer.py, and all point-source fit files — each test now covers exactly one scenario so a failure immediately identifies the broken casetest__figure_of_merit__pixelization_inversion__expected_log_evidenceinstead oftest__fit_figure_of_merit)pytest.mark.parametrizeapplied to multi-class/multi-case tests:FitPointDatasetposition fitting classes,plane_index_via_redshift_from,extract_plane_index_of_profile, upper plane index with light profilefit_imaging_plots.pyandtracer_plots.pythat had zero coverage:subplot_fit_x1_plane,subplot_fit_log10_x1_plane,subplot_tracer_from_fit,subplot_fit_combined,subplot_fit_combined_log10,save_tracer_fits,save_source_plane_images_fitsFiles changed
test_autolens/imaging/test_fit_imaging.pytest__fit_figure_of_merit(10+ scenarios) + sub_2 variants into individual tests; split dict and subtracted image teststest_autolens/lens/test_tracer.pytest__has, plane/galaxy sorting tests, convergence/potential/deflection tests; parametrize redshift lookups and extract_plane_indextest_autolens/imaging/plot/test_fit_imaging_plots.pytest__subplot_of_planestest_autolens/lens/plot/test_tracer_plots.pysave_tracer_fits/save_source_plane_images_fitsusingtmp_pathtest_autolens/point/fit/test_fit_dataset.pytest_autolens/point/fit/test_fluxes.pytest_autolens/point/fit/positions/image/test_pair*.pytest_autolens/point/fit/positions/image/test_abstract.pytest_autolens/point/fit/positions/source/test_separations.pyTest plan
python -m pytest test_autolens/imaging/test_fit_imaging.py -vpython -m pytest test_autolens/lens/test_tracer.py -vpython -m pytest test_autolens/imaging/plot/ -vpython -m pytest test_autolens/lens/plot/ -vpython -m pytest test_autolens/point/fit/ -v🤖 Generated with Claude Code