Write properties about your function that should hold true for all inputs, instead of enumerating expected inputs and outputs. Tests written this way are concise and powerful.
Property-based tests make statements about the output of your code based on the input, and these statements are verified for many different possible inputs.
Property-based testing encourages a high level approach to testing in the form of abstract invariants functions should satisfy universally, with the actual test data generated for the programmer by the testing library. In this way code can be hammered with thousands of tests that would be infeasible to write by hand, often uncovering subtle corner cases that wouldn’t be found otherwise.