refactor(tests): extract shared HFLoadErrorTestsMixin (−247 LOC, +20 tests)#23
Conversation
…tests) Follow-up to fix/object-detection-error-messages. The four backend test files each hand-rolled a near-identical TestXBackendLoadErrors class (~180 lines for image_classification/object_detection, ~45 lines for grounding_dino/owlvit with only 3 of the 13 branches covered). Now that `hf_load_error_handler` is shared, the tests covering its branches should be shared too. - Add `HFLoadErrorTestsMixin` to `tests/_hf_test_utils.py` holding all 13 load-error test methods, parameterized by class attrs `backend_cls`, `processor_patch_target`, `model_patch_target`, `task_phrase`. - Replace four bespoke test classes with 5-line subclasses. As a side effect, `grounding_dino` and `owlvit` gain the 10 branches they were previously missing (ImportError allowlist, GatedRepo, HfHubHTTPError 401/non-401, Entry/LocalEntry, fallback, cause chain, model-side patch). - Strengthen two assertions that were flagged in review of #21: (a) `test_hf_hub_http_error_includes_repr` now passes `status_code=503` so label matches behavior, and asserts "503 Service Unavailable" appears in the message — catches any regression that drops `repr(e)`. (b) `test_local_entry_not_found_error_message` / `test_entry_not_found_error_message` assert the cache-specific substring "not found in cache" rather than just "cache", so a future reorder that routes LocalEntryNotFoundError through the `ValueError` branch (it inherits from both) would flip the tests red instead of silently passing. Net: +205 / −452 = −247 lines across 5 files. Load-error tests grow from 32 to 52 (4 backends × 13 branches). Full pytest run: 113 passed.
lucasmundim
left a comment
There was a problem hiding this comment.
Clean, well-executed DRY refactoring
The mixin pattern is correct (MRO ordering, no setUp/__init__, all parameterization via class attrs), the coverage gain is real (grounding-dino and owlvit jump from 3 to 13 branches), and the two assertion improvements are welcome:
test_hf_hub_http_error_includes_reprnow passesstatus_code=503instead of defaulting to 404 while the message said "503".- Entry/LocalEntry tests assert
"not found in cache"instead of just"cache", catching regressions where an entry might route through the wrong handler branch.
Import cleanup is correct across all four files. Net -247 lines, test count 32 to 52. A rare case where removing code increases coverage.
Three minor non-blocking observations inline.
|
|
||
| _CONFIG = {"model_id": "org/model", "revision": "abc123", "device": "cpu"} | ||
|
|
||
| backend_cls = None |
There was a problem hiding this comment.
Non-blocking: is a mutable class-level dict shared across all subclasses. No test mutates it today, so this is safe — but if a future test does it would leak across all subclasses. A defensive option:
Not urgent, just a prophylactic note.
| msg = str(ctx.exception) | ||
| self.assertIn("org/model", msg) | ||
| self.assertIn("not found", msg) | ||
|
|
There was a problem hiding this comment.
Non-blocking, just noting the shift: The old grounding-dino and owlvit each had an inline . The mixin drops that here and instead covers cause-chaining via the dedicated (ValueError path) and (model-side path). Since uses uniformly on all branches, the coverage is equivalent.
| with self._patch_processor(side_effect=original): | ||
| with self.assertRaises(RuntimeError) as ctx: | ||
| self._load_backend() | ||
| self.assertIs(ctx.exception.__cause__, original) |
There was a problem hiding this comment.
Non-blocking: No CI checks have run on this branch yet ( reports nothing). Worth verifying the full 113-pass run before merging.
Follow-up to #21. The four backend test files each hand-rolled a near-identical TestXBackendLoadErrors class (~180 lines for image_classification/object_detection, ~45 lines for grounding_dino/owlvit with only 3 of the 13 branches covered). Now that
hf_load_error_handleris shared, the tests covering its branches should be shared too.HFLoadErrorTestsMixintotests/_hf_test_utils.pyholding all 13 load-error test methods, parameterized by class attrsbackend_cls,processor_patch_target,model_patch_target,task_phrase.grounding_dinoandowlvitgain the 10 branches they were previously missing (ImportError allowlist, GatedRepo, HfHubHTTPError 401/non-401, Entry/LocalEntry, fallback, cause chain, model-side patch).test_hf_hub_http_error_includes_reprnow passesstatus_code=503so label matches behavior, and asserts "503 Service Unavailable" appears in the message — catches any regression that dropsrepr(e). (b)test_local_entry_not_found_error_message/test_entry_not_found_error_messageassert the cache-specific substring "not found in cache" rather than just "cache", so a future reorder that routes LocalEntryNotFoundError through theValueErrorbranch (it inherits from both) would flip the tests red instead of silently passing.Net: +205 / −452 = −247 lines across 5 files. Load-error tests grow from 32 to 52 (4 backends × 13 branches). Full pytest run: 113 passed.