---
id: index
title: Property-based Testing
slug: property-based-testing.html
sidebar_label: Introduction
---


import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

Kotest is split into several subprojects which can be used independently. One of these subprojects is the property test framework.
You do **not** need to be using Kotest as your test framework (although you should!) to benefit from the property test support.

[![version badge](https://img.shields.io/maven-central/v/io.kotest/kotest-property.svg?label=release)](https://search.maven.org/search?q=g:io.kotest)
[![version badge](https://img.shields.io/nexus/s/https/oss.sonatype.org/io.kotest/kotest-framework-engine.svg?label=snapshot)](https://oss.sonatype.org/content/repositories/snapshots/io/kotest/)


## What is Property Testing?

Developers typically write example-based tests. These are your garden variety unit tests you know and love.
You provide some inputs, and some expected results, and a test framework like Kotest or JUnit checks that the actual
results meet the expectations.

One problem with this approach is that it is very easy to miss errors due to edge cases that the developer didn't think about,
or lack of coverage in the chosen inputs. Instead, with property testing, hundreds or thousands of values are fed into the same test,
and the values are (usually) randomly generated by your property test framework.

For example, a good property test framework will include values like negative infinity, empty lists, strings with non-ascii characters, and so on.
Things we often forget about when writing example based tests.

Property tests were originally conceived in frameworks like Quickcheck with the notion of testing a _property_ on some object,
ie. something that should hold true for all inputs. An invariant in other words.  An example of an invariant is given two strings,
a and b, then _length(a + b)_ should always be equal to _length(a) + length(b)_.

That is where the term _property testing_ originates.

However, you do not have to use property tests to only test things like monad laws or basic numeric functions. Any test that
would benefit from a wide array of input values is a good candidate. For example, we might have a function that validates usernames, and we want to test that valid emails are accepted. A property test would be useful here in generating 1000s of combinations to help harden our validation logic.


## Getting Started

The property test framework is supported on all targets.

<Tabs
defaultValue="JVM/Gradle"
values={[
{label: 'JVM/Gradle', value: 'JVM/Gradle'},
{label: 'JVM/Maven', value: 'JVM/Maven'},
{label: 'Multiplatform', value: 'Multiplatform'},
]}>

<TabItem value="JVM/Gradle">

Add the following dependency to your build:

```kotlin
dependencies {
   testImplementation("io.kotest:kotest-property:$version")
}
```

</TabItem>

<TabItem value="JVM/Maven">

Add the following dependency to your build.

```xml
<dependency>
   <groupId>io.kotest</groupId>
   <artifactId>kotest-property-jvm</artifactId>
   <version>${version}</version>
   <scope>test</scope>
</dependency>
```

</TabItem>
<TabItem value="Multiplatform">

   Add the following dependency to your `commonTest` sourceset:

```kotlin
kotlin {
  sourceSets {
    val commonTest by getting {
      dependencies {
        implementation("io.kotest:kotest-property:$version")
      }
    }
  }
}
```

Alternatively, add the dependency to a specific target.
   For example, we could add to the Javascript target only be using the `jsTest` sourceset.

```kotlin
kotlin {
   targets {
      js {
         browser()
         nodejs()
      }
   }
   sourceSets {
      val jsTest by getting {
         dependencies {
            implementation("io.kotest:kotest-property:$version")
         }
      }
   }
}
```

</TabItem>
</Tabs>



## Next Steps

To create input values for tests, Kotest uses the term _generator_. One generator per input argument is passed to a _test function_,
and the test will execute for a set number of _iterations_.

Read more about

* How [test functions](test_functions.md) are used.
* The different types of [generators](gens.md) and [operations](genops.md) on them.
* How to write a [custom generator](customgens.md).
* How to specify [config](config.md) for a test, including the seed.
