jestjs / jest

Delightful JavaScript Testing.
https://jestjs.io
MIT License
43.86k stars 6.39k forks source link

[Feature]: Predicate matching on snapshot values #15081

Open dwjohnston opened 1 month ago

dwjohnston commented 1 month ago

πŸš€ Feature Proposal

Extend toMatchSnapshot functionality to allow providing a predicate to determine whether a test value matches the snapshot value.

Motivation

For something like a performance tests we want to see that the test value is less than or equal to the snapshot value, exact equality is not necessary, but some comparison is required (eg. less than)

Example

const testValue = { foo: 1, bar: "abcde" }; 

expect(testValue).toMatchSnapshot({
    // Test will pass if testValue.foo is less than the stored snapshot, 
    foo: expect.snapshotPredicate((oldValue, newValue) => newValue <= oldValue)   
    // bar is not provided in the snapshot options, so exact matching will be used
}); 

The predicate function might also want to determine whether snapshot should be updated with the test value.

In some scenarios you might not want to update the snapshot (eg. in a performance test there may be some amount of noise, so only significant improvements in performance should update the snapshot). Suggest that by default if using snapshot predicates, values are not automatically updated, and will only be updated if a second predicate function is provided that determines whether the update should occur.

expect(testValue).toMatchSnapshot({
    // Test passes if newValue is less than the snapshot value, update the snapshot if the newValue is 10% lower than the old value. 
    foo: expect.snapshotPredicate((oldValue, newValue) => newValue <= oldValue, (oldValue, newValue) => (newValue/oldValue) < 0.9)   
    // bar is not provided in the snapshot options, so exact matching will be used
}); 

Pitch

Opens a lot of possibilities for testing, performance tests come to mind, but presumably there are other scenarios where flexibility with snapshot tests is valuable.

github-actions[bot] commented 2 weeks ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.