Agent Wranglers

TST-57Recommended

Test both states of every live flag

Run the tests that a feature flag touches once with the flag on and once with it off, until the flag is removed.

How to do it

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 says. Take the flags from the flag register, and run each affected test once per state with the runner's table of cases. 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 says.

Examples

JavaScript example

// 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

# 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

How to 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.

For agents: this playbook is free to use under CC 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.