---
title: "Test both states of every live flag · Agent Wranglers"
url: https://agentwranglers.se/playbook/testing/test-strategy/test-both-flag-states
id: TST-57
level: Recommended
updated: 2026-10-22
build: a2a6bdfed830
tokens: 920
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Test both states of every live flag

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Test strategy](https://agentwranglers.se/playbook/testing/test-strategy.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-22.

- ID: TST-57
- Level: Recommended
- Chapter: [Test strategy](https://agentwranglers.se/playbook/testing/test-strategy.md)
- Rule: Run the tests that a feature flag touches once with the flag on and once with it off, until the flag is removed.
- Check: For every flag in the register, the test report shows passing tests named with `on` and with `off`. Breaking the off path of a flag makes a test fail.
- How: A flag doubles the paths through the code. The path nobody runs in staging is the one that breaks on the day of the switch. Read flags through one provider that a test can set, never from global state, as [Pass state in instead of sharing globals](https://agentwranglers.se/playbook/architecture/coupling/no-global-state.md) says. Take the flags from the [flag register](https://agentwranglers.se/playbook/engineering/feature-flags/flag-register.md), and run each affected test once per state with the runner's [table of cases](https://agentwranglers.se/playbook/testing/unit-tests/decision-tables.md). A flag with more than two values needs a case for each value. Once a flag is on everywhere, delete it with its off cases, as [Remove flags that never change](https://agentwranglers.se/playbook/architecture/structure/remove-stale-flags.md) says.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
// Vitest: the same checks run with the flag on and off
describe.each(['on', 'off'])('new-shipping-rates %s', (state) => {
  test('a cart over 500 ships free', () => {
    const flags = fakeFlags({ 'new-shipping-rates': state === 'on' });
    expect(checkoutTotal({ subtotal: 520 }, flags).shipping).toBe(0);
  });
});
```

### Python example

```python
# pytest: one case per flag state, named in the report
@pytest.mark.parametrize("enabled", [True, False], ids=["on", "off"])
def test_a_cart_over_500_ships_free(enabled):
    flags = FakeFlags({"new-shipping-rates": enabled})
    assert checkout_total(Cart(subtotal=520), flags).shipping == 0
```

## Related rules

- ENG-45 [Keep every flag in one register](https://agentwranglers.se/playbook/engineering/feature-flags/flag-register.md) in Engineering
- ARC-38 [Pass state in instead of sharing globals](https://agentwranglers.se/playbook/architecture/coupling/no-global-state.md) in Clean code and architecture
- TST-11 [Test rules with several conditions as a table](https://agentwranglers.se/playbook/testing/unit-tests/decision-tables.md) in Testing
- ARC-60 [Remove flags that never change](https://agentwranglers.se/playbook/architecture/structure/remove-stale-flags.md) in Clean code and architecture

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/testing/test-strategy/test-both-flag-states">Agent Wranglers testing playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Ship tests in the same change](https://agentwranglers.se/playbook/testing/test-strategy/tests-with-the-change.md)
- [Test strategy](https://agentwranglers.se/playbook/testing/test-strategy.md)
