<!--
title: Meaningful Tests For Guards
domain: orchestration
topic: Testing
language: Python
source: celery/celery
updated: 2026-04-22
url: https://awesomereviewers.com/reviewers/celery-meaningful-tests-for-guards/
-->

When adding tests for new behavior, deprecations, or environment-dependent code paths, ensure the test actually exercises the intended branch (avoid vacuous passing) and assert the concrete observable effect.

Apply this checklist:
1) Force the guard conditions
- If production code checks for installed modules / feature flags / config presence, your test must set up that environment.
- Example pattern for module presence guards:

```python
from unittest.mock import MagicMock, patch

with patch.dict(
    sys.modules,
    {
        'gevent': MagicMock(),
        # add 'eventlet' similarly if needed
    },
    clear=False,
):
    worker.on_start()
    # assert warning/log behavior here
```

2) Test the user-visible outcome (not just “no crash”)
- For deprecations: assert the warning is emitted and the method returns/behaves as expected.
- For behavioral changes: add a targeted unit test for the changed logic and update PR documentation/changelog as requested.

3) Choose the right level to avoid flakiness
- If correctness depends on wall-clock/timezone transitions (DST folds, etc.), prefer deterministic unit tests that control inputs.
- If you must do integration, keep it minimal and prefer existing smoke-test infrastructure over bespoke environment control.

4) Assert precisely
- Tighten assertions to the expected contract (e.g., exact routing key matching) and, for logging, assert on the presence/absence of specific messages.

Following these rules prevents tests that “pass vacuously,” improves regression protection for behavior changes/deprecations, and keeps higher-level tests from becoming brittle.
