A comprehensive property-based testing library for Scala and Java applications that enables developers to specify program properties as testable assertions and automatically generates test cases to verify these properties.
npx @tessl/cli install tessl/maven-org-scalacheck--scalacheck-2-12@1.18.00
# ScalaCheck
1
2
ScalaCheck is a comprehensive property-based testing library for Scala and Java applications that enables developers to specify program properties as testable assertions and automatically generates test cases to verify these properties. The library provides sophisticated data generators for creating test inputs, property combinators for building complex test scenarios, and automatic shrinking capabilities that minimize failing test cases to their essential components.
3
4
## Package Information
5
6
- **Package Name**: scalacheck
7
- **Package Type**: maven (Scala)
8
- **Language**: Scala (cross-compiled for JVM, JavaScript, Native)
9
- **Installation**: `libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.18.1" % Test`
10
11
## Core Imports
12
13
```scala
14
import org.scalacheck._
15
import org.scalacheck.Prop._
16
import org.scalacheck.Gen._
17
```
18
19
For specific functionality:
20
21
```scala
22
import org.scalacheck.{Gen, Prop, Arbitrary, Test}
23
import org.scalacheck.Prop.forAll
24
```
25
26
## Basic Usage
27
28
```scala
29
import org.scalacheck._
30
import org.scalacheck.Prop._
31
32
// Define a simple property
33
val propReverseReverse = forAll { (l: List[Int]) =>
34
l.reverse.reverse == l
35
}
36
37
// Check the property
38
propReverseReverse.check()
39
40
// Define a property with explicit generator
41
val smallInts = Gen.choose(0, 100)
42
val propSmallInts = forAll(smallInts) { n =>
43
n >= 0 && n <= 100
44
}
45
46
// Create a property collection
47
object StringProps extends Properties("String") {
48
property("concatenation") = forAll { (s1: String, s2: String) =>
49
(s1 + s2).length >= s1.length && (s1 + s2).length >= s2.length
50
}
51
52
property("reverse") = forAll { (s: String) =>
53
s.reverse.reverse == s
54
}
55
}
56
57
// Run all properties
58
StringProps.check()
59
```
60
61
## Architecture
62
63
ScalaCheck is built around several key components:
64
65
- **Gen**: Generator framework for producing test data with combinators for complex data generation
66
- **Prop**: Property framework for expressing testable assertions with logical combinators
67
- **Arbitrary**: Type class providing implicit generators for automatic property parameterization
68
- **Test**: Execution framework with configurable parameters and parallel testing support
69
- **Shrink**: Automatic test case minimization when properties fail
70
- **Cogen**: Co-generators enabling function generation for higher-order property testing
71
- **Properties**: Collections framework for organizing and batch-testing related properties
72
73
This modular design enables everything from simple property definitions to complex stateful testing scenarios, making ScalaCheck suitable for unit testing, integration testing, and specification-based development.
74
75
## Capabilities
76
77
### Generator Framework
78
79
Comprehensive data generation system with primitive generators, collection builders, distribution support, and powerful combinators for creating custom test data.
80
81
```scala { .api }
82
abstract class Gen[+T] {
83
def map[U](f: T => U): Gen[U]
84
def flatMap[U](f: T => Gen[U]): Gen[U]
85
def filter(p: T => Boolean): Gen[T]
86
def sample: Option[T]
87
}
88
89
object Gen {
90
def const[T](x: T): Gen[T]
91
def choose[T](min: T, max: T)(implicit num: Choose[T]): Gen[T]
92
def oneOf[T](xs: T*): Gen[T]
93
def listOf[T](g: Gen[T]): Gen[List[T]]
94
def frequency[T](gs: (Int, Gen[T])*): Gen[T]
95
}
96
```
97
98
[Generator Framework](./generators.md)
99
100
### Property Framework
101
102
Property definition and testing system with universal/existential quantifiers, logical combinators, and comprehensive assertion capabilities.
103
104
```scala { .api }
105
abstract class Prop {
106
def &&(p: => Prop): Prop
107
def ||(p: => Prop): Prop
108
def ==>(p: => Prop): Prop
109
def check(): Unit
110
def check(params: Test.Parameters): Unit
111
}
112
113
object Prop {
114
def forAll[T, P](f: T => P)(implicit a: Arbitrary[T], pp: P => Prop): Prop
115
def forAll[T, P](g: Gen[T])(f: T => P)(implicit pp: P => Prop): Prop
116
def exists[T, P](f: T => P)(implicit a: Arbitrary[T], pp: P => Prop): Prop
117
def ?=[T](x: T, y: T): Prop
118
}
119
```
120
121
[Property Framework](./properties.md)
122
123
### Test Execution
124
125
Configurable test execution with parallel processing, custom reporting, seed control, and comprehensive result analysis.
126
127
```scala { .api }
128
object Test {
129
sealed abstract class Parameters {
130
val minSuccessfulTests: Int
131
val workers: Int
132
val testCallback: TestCallback
133
def withMinSuccessfulTests(n: Int): Parameters
134
def withWorkers(w: Int): Parameters
135
}
136
137
def check(params: Parameters, prop: Prop): Result
138
def checkProperties(params: Parameters, props: Properties): Seq[(String, Result)]
139
}
140
```
141
142
[Test Execution](./test-execution.md)
143
144
### Automatic Value Generation
145
146
Type-directed generator instances for automatic property parameterization, supporting primitive types, collections, and custom data structures.
147
148
```scala { .api }
149
abstract class Arbitrary[T] {
150
def arbitrary: Gen[T]
151
}
152
153
object Arbitrary {
154
def apply[T](g: => Gen[T]): Arbitrary[T]
155
def arbitrary[T](implicit a: Arbitrary[T]): Gen[T]
156
157
implicit val arbInt: Arbitrary[Int]
158
implicit val arbString: Arbitrary[String]
159
implicit def arbList[T: Arbitrary]: Arbitrary[List[T]]
160
implicit def arbOption[T: Arbitrary]: Arbitrary[Option[T]]
161
}
162
```
163
164
[Automatic Value Generation](./arbitrary.md)
165
166
### Test Case Shrinking
167
168
Automatic minimization of failing test cases to find the smallest counterexample, with configurable shrinking strategies for all data types.
169
170
```scala { .api }
171
abstract class Shrink[T] {
172
def shrink(x: T): Stream[T]
173
def suchThat(f: T => Boolean): Shrink[T]
174
}
175
176
object Shrink {
177
def apply[T](s: T => Stream[T]): Shrink[T]
178
def shrink[T](x: T)(implicit s: Shrink[T]): Stream[T]
179
180
implicit def shrinkContainer[C[_], T: Shrink]: Shrink[C[T]]
181
implicit val shrinkString: Shrink[String]
182
}
183
```
184
185
[Test Case Shrinking](./shrinking.md)
186
187
### Function Generation
188
189
Co-generator framework enabling the generation of functions for testing higher-order functions and functional programming patterns.
190
191
```scala { .api }
192
trait Cogen[T] {
193
def perturb(seed: Seed, t: T): Seed
194
def contramap[S](f: S => T): Cogen[S]
195
}
196
197
object Cogen {
198
def apply[T](f: T => Long): Cogen[T]
199
implicit val cogenInt: Cogen[Int]
200
implicit val cogenString: Cogen[String]
201
implicit def cogenList[T: Cogen]: Cogen[List[T]]
202
}
203
```
204
205
[Function Generation](./cogen.md)
206
207
### Property Collections
208
209
Framework for organizing related properties into testable suites with command-line runners and batch execution support.
210
211
```scala { .api }
212
abstract class Properties(name: String) {
213
def check(params: Test.Parameters = Test.Parameters.default): Unit
214
def main(args: Array[String]): Unit
215
def include(ps: Properties): Unit
216
217
val property: PropertySpecifier
218
}
219
220
class PropertySpecifier {
221
def update(propName: String, p: => Prop): Unit
222
}
223
```
224
225
[Property Collections](./property-collections.md)
226
227
### Stateful Testing
228
229
Advanced testing framework for stateful systems using command sequences, state machines, and concurrent execution scenarios.
230
231
```scala { .api }
232
trait Commands {
233
type State
234
type Sut
235
236
def canCreateNewSut(newState: State, initSuts: Traversable[State], runningSuts: Traversable[Sut]): Boolean
237
def newSut(state: State): Sut
238
def genInitialState: Gen[State]
239
def genCommand(state: State): Gen[Command]
240
241
trait Command {
242
type Result
243
def run(sut: Sut): Result
244
def nextState(state: State): State
245
def preCondition(state: State): Boolean
246
def postCondition(state: State, result: Try[Result]): Prop
247
}
248
}
249
```
250
251
[Stateful Testing](./stateful-testing.md)
252
253
## Types
254
255
### Core Types
256
257
```scala { .api }
258
// Generator parameters for controlling test data generation
259
sealed abstract class Gen.Parameters {
260
val size: Int
261
val initialSeed: Option[Seed]
262
val useLegacyShrinking: Boolean
263
}
264
265
// Property evaluation result
266
case class Prop.Result(
267
status: Prop.Status,
268
args: List[Prop.Arg[Any]],
269
collected: Set[Any],
270
labels: Set[String]
271
)
272
273
// Property status types
274
sealed trait Prop.Status
275
case object Prop.Proof extends Prop.Status
276
case object Prop.True extends Prop.Status
277
case object Prop.False extends Prop.Status
278
case object Prop.Undecided extends Prop.Status
279
case class Prop.Exception(e: Throwable) extends Prop.Status
280
281
// Test execution result
282
case class Test.Result(
283
status: Test.Status,
284
succeeded: Int,
285
discarded: Int,
286
freqMap: FreqMap[Set[Any]],
287
time: Long
288
)
289
290
// Random number generator seed
291
abstract class Seed {
292
def next: Seed
293
def reseed(n: Long): Seed
294
def toBase64: String
295
}
296
```