Distinguish shutter types in existing tests#1068
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1068 +/- ##
=======================================
Coverage 97.75% 97.75%
=======================================
Files 170 170
Lines 6849 6851 +2
=======================================
+ Hits 6695 6697 +2
Misses 154 154 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
DominicOram
left a comment
There was a problem hiding this comment.
Looks good, thanks! Mostly minor points. As discussed, I think these should also be in test_hutch_conditional_shutter.py.
| fake_prefix = "I74" | ||
| shutter_name = "GrandOldShutter" | ||
| hcs = HutchConditionalShutter(fake_prefix, hutch_controlling_shutter, shutter_name) | ||
| test_case = TestCase() | ||
| test_case.assertIsInstance(hcs, HutchConditionalShutter) |
There was a problem hiding this comment.
Should: We use pytest rather than unittest. pytest sort of uses the assert keyword instead so the way to do this in pytest is:
| fake_prefix = "I74" | |
| shutter_name = "GrandOldShutter" | |
| hcs = HutchConditionalShutter(fake_prefix, hutch_controlling_shutter, shutter_name) | |
| test_case = TestCase() | |
| test_case.assertIsInstance(hcs, HutchConditionalShutter) | |
| fake_prefix = "I74" | |
| shutter_name = "GrandOldShutter" | |
| hcs = HutchConditionalShutter(fake_prefix, hutch_controlling_shutter, shutter_name) | |
| assert isinstance(hcs, HutchConditionalShutter) |
| async def test_shutter_created_for_eh_one_without_raising_errors(): | ||
| hutch_from_which_shutter_is_controlled = HutchState.EH1 | ||
| await unit_test_shutter_created_without_raising_errors( | ||
| hutch_from_which_shutter_is_controlled | ||
| ) | ||
|
|
||
|
|
||
| async def test_shutter_created_for_eh_two_without_raising_errors(): | ||
| hutch_from_which_shutter_is_controlled = HutchState.EH2 | ||
| await unit_test_shutter_created_without_raising_errors( | ||
| hutch_from_which_shutter_is_controlled | ||
| ) |
There was a problem hiding this comment.
Could: You can use @pytest.mark.parametrize to do this for you:
| async def test_shutter_created_for_eh_one_without_raising_errors(): | |
| hutch_from_which_shutter_is_controlled = HutchState.EH1 | |
| await unit_test_shutter_created_without_raising_errors( | |
| hutch_from_which_shutter_is_controlled | |
| ) | |
| async def test_shutter_created_for_eh_two_without_raising_errors(): | |
| hutch_from_which_shutter_is_controlled = HutchState.EH2 | |
| await unit_test_shutter_created_without_raising_errors( | |
| hutch_from_which_shutter_is_controlled | |
| ) | |
| @pytest.mark.parametrize( | |
| "hutch_from_which_shutter_is_controlled", [HutchState.EH1, HutchState.EH2] | |
| ) | |
| async def test_shutter_created_without_raising_errors( | |
| hutch_from_which_shutter_is_controlled, | |
| ): | |
| await unit_test_shutter_created_without_raising_errors( | |
| hutch_from_which_shutter_is_controlled | |
| ) |
This will create two tests called test_shutter_created_without_raising_errors[EH1] and test_shutter_created_without_raising_errors[EH2].
In the case of just having the two options it's neither here nor there but when there's like 3 or 4 it tidies up a lot of the copy/paste.
| ) | ||
|
|
||
|
|
||
| async def unit_test_shutter_created_without_raising_errors( |
There was a problem hiding this comment.
Could: This actually need not be an async function. To a first approximation an async function is only needed if you are calling other async functions from it. The constructor of HutchConditionalShutter is synchronous and so this isn't needed. If you were calling the set here it would be needed. Does no harm though so not the end of the world to leave it in.
| with pytest.raises(HutchInvalidError): | ||
| await unit_test_shutter_created_without_raising_errors(not_a_hutch) |
There was a problem hiding this comment.
Nit: It's a little odd that you're calling a function called unit_test_shutter_created_without_raising_errors and expecting to actually raise the error. But not the end of the world.
DominicOram
left a comment
There was a problem hiding this comment.
Great, thank you! Snake_case is the only comment I really care about, happy for you to take/leave the others.
| @pytest.fixture | ||
| async def eh1_shutter(RE: RunEngine) -> HutchConditionalShutter: | ||
| shutter = HutchConditionalShutter("", HutchState.EH1, name="mock_shutter") | ||
| await shutter.connect(mock=True) | ||
|
|
||
| def set_status(value: ShutterDemand, *args, **kwargs): | ||
| value_sta = ShutterState.OPEN if value == "Open" else ShutterState.CLOSED | ||
| set_mock_value(shutter.shutter.status, value_sta) | ||
|
|
||
| callback_on_mock_put(shutter.shutter.control, set_status) | ||
|
|
||
| return shutter | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| async def eh2_shutter(RE: RunEngine) -> HutchConditionalShutter: | ||
| shutter = HutchConditionalShutter("", HutchState.EH2, name="mock_shutter") | ||
| await shutter.connect(mock=True) | ||
|
|
||
| def set_status(value: ShutterDemand, *args, **kwargs): | ||
| value_sta = ShutterState.OPEN if value == "Open" else ShutterState.CLOSED | ||
| set_mock_value(shutter.shutter.status, value_sta) | ||
|
|
||
| callback_on_mock_put(shutter.shutter.control, set_status) | ||
|
|
||
| return shutter |
There was a problem hiding this comment.
Could: I would combine the common bits here:
async def make_mock_shutter(hutch: HutchState) -> HutchConditionalShutter:
shutter = HutchConditionalShutter("", hutch, name="mock_shutter")
await shutter.connect(mock=True)
def set_status(value: ShutterDemand, *args, **kwargs):
value_sta = ShutterState.OPEN if value == "Open" else ShutterState.CLOSED
set_mock_value(shutter.shutter.status, value_sta)
callback_on_mock_put(shutter.shutter.control, set_status)
return shutter
@pytest.fixture
async def eh1_shutter(RE: RunEngine) -> HutchConditionalShutter:
return await make_mock_shutter(HutchState.EH1)
@pytest.fixture
async def eh2_shutter(RE: RunEngine) -> HutchConditionalShutter:
return await make_mock_shutter(HutchState.EH2)| def assertIsInstance(an_instance, expected_type): | ||
| assert isinstance(an_instance, expected_type) |
There was a problem hiding this comment.
Should: This should be snake case as a python function
| def assertIsInstance(an_instance, expected_type): | |
| assert isinstance(an_instance, expected_type) | |
| def assert_is_instance(an_instance, expected_type): | |
| assert isinstance(an_instance, expected_type) |
There was a problem hiding this comment.
Could: I would also personally argue that assert_is_instance(x, y) is no more readable than assert isinstance(x, y) and so feel this function is redundant but I don't feel that strongly.
There was a problem hiding this comment.
Might well be "no more readable" but it is more ophiomorphic ( Greek ophis = snake )
* Renames ambiguously named "shutter tests" according
to their specific shutter type
Examples (of renaming) covered here:
shutter -> zebra_shutter
shutter -> hutch_shutter
* i19 specific tests cover a HutchConditionalShutter * Therefore the test script has been renamed to account for this specificity in the shutter type
* First round of tests check instantiation against all enum types in HutchState ( EH1, EH2 and Invalid ) * Required code changes to HutchConditionalShutter class to make constructor raise error if instantiated with HutchState.INVALID as the requesting hutch from which the shutter is being controlled ** N.B. This might spark a philosophical debate on the nature of HutchState enum and whether it is the correct type to pass in here through the constructor
* Merges all tests into one hutch test file
( since "unit" tests were not unit level after all )
* Adds comments throughout test file
- to label test types Constructor, Functional etc
- to separate and delineate happy / unhappy path tests
- to label auxiliary functions
* Removes unittest assertIsInstance
- local version rolled in test file
- this is to comply with not using unittest
assertions ( avoidance being a local de facto standard )
* Replaces spuriously named functions
* Adds tests to complete symmetry of EH1 / EH2
* Assertion method (auxiliary to i19 hutch shutter tests) is now rendered in snake case
f99287a to
37cb4bc
Compare
Fixes ambiguous names ( side work for Issue #1066 )
Instructions to reviewer on how to test:
Checks for reviewer
dodal connect ${BEAMLINE}