Add unit tests for planner.py - #133
Conversation
for more information, see https://pre-commit.ci
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #133 +/- ##
=======================================
Coverage 87.42% 87.42%
=======================================
Files 5 5
Lines 326 326
=======================================
Hits 285 285
Misses 41 41 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Thanks a lot for your contribution @iliasmahboub
I've managed to have a first look and have raised a few questions. I like the range of things you test in this PR.
On a general level: I'm not sure the complexity added by the mocking (which makes the test code harder to read) is worth the improvement in test speed (which IIUC is your rationale?) but I am open to being convinced otherwise. Apologies if I misunderstood!
| @patch("brainglobe_heatmap.planner.Heatmap.__init__", return_value=None) | ||
| @patch("brainglobe_heatmap.planner.print_plane") | ||
| def test_plan_converts_region_list_to_dict(mock_print, mock_init): | ||
| mock_init.return_value = None |
There was a problem hiding this comment.
Should the return value of mock_init not be set to None already in line 72, without you having to set it manually in line 75? Same in other test functions. But maybe I am misunderstanding the code?
|
|
||
|
|
||
| class FakePlane: | ||
| """Minimal stand-in for Plane with the attributes print_plane reads.""" |
There was a problem hiding this comment.
Could we not use an actual Plane object here, so we don't have to remember to change this code if we change the attributes of Plane (e.g. hypothetically we rename self.u to self.vector_u or something)?
|
|
||
|
|
||
| @patch("brainglobe_heatmap.planner.Heatmap.__init__", return_value=None) | ||
| @patch("brainglobe_heatmap.planner.print_plane") |
There was a problem hiding this comment.
Why do we mock print_plane here? It doesn't seem to be used?
There was a problem hiding this comment.
@alessandrofelder Hi Alessandro! apologies for the slow reply; I've had final exams and project deadlines this past week and only just caught this in my inbox. Thank you for the detailed review! You're right on all three points:
- The redundant
return_value = Noneassignments are unnecessary since it's already set in the decorator. I'll remove them. FakePlaneis a liability ifPlane's interface changes; I'll swap in realPlaneobjects.- The unused
print_planemock was a copy-paste artifact and I'll drop it.
On the broader mocking question: the intent was to avoid triggering the actualHeatmapinitialization, which depends on atlas data, rather than purely a speed concern. That said, I'm happy to restructure the tests to use real objects if that fits better with how the rest of the suite is written.
I'll push a fix shortly! Have a nice day!
There was a problem hiding this comment.
@alessandrofelder also, to elaborate, I mentioned the 2.5s runtime in the PR description which was a side effect, not the main reason. My main line of thought was isolation: Heatmap.init creates a real brainrender.Scene and brainrender.Atlas, loads atlas metadata, adds meshes, and instantiates a Slicer. Since plan.init calls super().init() directly, running these tests unmocked without a local atlas cache fails before any planner logic runs. The mock keeps this as a unit test of the planner's own behavior, independent of atlas availability.
The fair caveats that it doesn't cover the end to end path with real atlas data, which belongs in an integration test. But for testing the planner's argument handling in isolation, I think the mock is pretty justified imo. Happy to remove it if you think otherwise though!
|
@alessandrofelder I pushed a follow-up commit addressing the planner test review comments: removed the redundant init return_value assignments, replaced the FakePlane test helper with real Plane instances, and removed unused print_plane patch decorators where the mock was not asserted.\n\nI also reran the targeted planner tests and ruff locally: pytest tests\test_unit\test_planner.py -q --no-cov, and ruff check tests\test_unit\test_planner.py. |
Closes #122.
Adds 13 unit tests covering
print_plane()and theplanclass.Heavy dependencies (brainrender, vedo) are mocked so tests run in
~2.5s without GPU or atlas download. planner.py coverage: 0% -> 100%.
Tests cover: plane output formatting and rounding, region list-to-dict
conversion, 3D format enforcement, arrow scale defaults, slicer plane
printing, kwarg forwarding to Heatmap, show() return value and root
mesh alpha.
How to test