A unit test is a record of what its author thought could go wrong. The defect that reaches production is, by definition, the one they did not think of. More tests written the same way do not close that gap. They are the same imagination, applied again.
Stating the Rule Instead of the Example
Property-based testing changes what the engineer writes. Instead of "this input gives this output," they state a rule that must hold for every input, such as "a discount never exceeds the original price," and the framework supplies the inputs. In Kotest, the common choice for Kotlin, the volume is specific: "By default, Kotest will run the property test 1000 times" (Kotest).
The inputs are not only random. Kotest documents that its generators produce a hard-coded set of edge cases alongside random samples, with a split that "defaults to 2% edge cases" (Kotest). For integers those include zero, one, minus one and the largest and smallest values the type can hold. Those are the values example-based suites forget.
The Objection: Random Means Unrepeatable
The reasonable worry is a failure nobody can reproduce. The tooling answers it. "Whenever a property test fails, Kotest will output the seed that was used" (Kotest), and supplying that seed replays the identical run. A random test with a recorded seed is as repeatable as any other.
The Detail That Decides Whether It Pays Off
When a rule fails, a good framework shrinks the failing input to the simplest one that still fails. That is the difference between a 900-item list and a two-item list on the engineer's screen. It is not automatic for every generator. Kotest's documentation is direct: "Generators created with the arbitrary { } builder do not automatically compose shrinkers from inner arbitraries" (Kotest). Our own article on the subject had this wrong until this month, which is the argument for checking a claim against the source.
Where to Start
- Money and conversions first. Pricing, tax, currency and unit conversion have rules that fit in one sentence.
- Anything that saves and reloads. What goes in must come back out unchanged.
- Not the user interface. The input space is too large and the rule too vague.
-Rocky
#SoftwareQuality #TestAutomation #Kotlin #EngineeringDreams #StrategiaX
Originally published on ANDROID-ARCHITECT, the Android engineering blog of Strategia-X, with the code.
