Writes property-based tests using Kotest's kotest-property module. Identifies testable properties, designs generators, and configures PBT for Kotlin/JVM projects. Use when writing property-based tests, creating custom Arb generators, choosing property patterns (roundtrip, invariant, idempotence, oracle), debugging shrunk counterexamples, or integrating PBT into a Kotlin test suite alongside example-based tests.
decode(encode(x)) == x. For serialize/parse/compress pairs.sort preserves size and elements).f(f(x)) == f(x). For trim, distinct, upsert, PUT.Arb for random+edge-case generation (default),
Exhaustive for small finite domains. Constrain generators at construction
— don't rely on filter() or assume() (keep discard rate under 10%).
For domain types, compose with arbitrary { ... } using .bind().checkAll with Kotest matchers (preferred over
forAll with booleans). Default: 1,000 iterations.// build.gradle.kts
dependencies {
testImplementation("io.kotest:kotest-property:$kotestVersion")
}
checkAll vs forAll: Use checkAll — richer error messages via matchers.Arb vs Exhaustive: Use Arb unless the domain is small and finite (enums, boolean).Bounded(1000). Use Unbounded only when debugging..bind() inside arbitrary {}, never kotlin.random.Random.Float→Double). Verify losslessness or test a weaker property.assume() only when the constraint can't be expressed in the generator. Prefer restructuring (e.g., val (larger, smaller) = if (a > b) a to b else b to a).checkAll/forAll, Arb vs Exhaustivearbitrary {}, domain compositionassume()PropTestConfig, global settings, common mistakes