A test comparing the full response against a recorded fixture, breaking on an added field that no consumer reads.
// too strict: any addition is a failure
self::assertSame($expected, $response->json());
// the contract is what consumers depend on
self::assertArraySubset([
'id' => 8814,
'status' => 'paid',
'total' => ['amount' => 4900, 'currency' => 'GBP'],
], $response->json());
// plus, separately, an assertion that REMOVED fields fail
Additive changes are compatible and a test that fails on them trains people to update fixtures without reading them, which is how a genuine break gets waved through. The asymmetry is the design: adding a field must pass, removing or retyping one must fail. Deriving the expectation from the published schema rather than from a recording is the version that stays honest as the API grows.