or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

arbitrary.mdcogen.mdgenerators.mdindex.mdproperties.mdproperty-collections.mdshrinking.mdstateful-testing.mdtest-execution.md

properties.mddocs/

0

# Property Framework

1

2

The ScalaCheck property framework enables expressing testable assertions about program behavior. Properties can be combined with logical operators, parameterized with generators, and executed with comprehensive reporting capabilities.

3

4

## Capabilities

5

6

### Core Property Class

7

8

The fundamental property abstraction with logical combinators and execution methods.

9

10

```scala { .api }

11

abstract class Prop {

12

def apply(prms: Gen.Parameters): Prop.Result

13

def &&(p: => Prop): Prop

14

def ||(p: => Prop): Prop

15

def ++(p: => Prop): Prop

16

def ==>(p: => Prop): Prop

17

def ==(p: => Prop): Prop

18

def check(): Unit

19

def check(prms: Test.Parameters): Unit

20

def check(paramFun: Test.Parameters => Test.Parameters): Unit

21

def label(l: String): Prop

22

def :|(l: String): Prop

23

def |:(l: String): Prop

24

def useSeed(seed: Seed): Prop

25

def viewSeed(name: String): Prop

26

}

27

```

28

29

**Usage Examples:**

30

```scala

31

val prop1 = Prop.forAll { (x: Int) => x + 0 == x }

32

val prop2 = Prop.forAll { (x: Int) => x * 1 == x }

33

val combinedProp = prop1 && prop2

34

val conditionalProp = (prop1 ==> prop2).label("identity laws")

35

36

combinedProp.check()

37

conditionalProp.check(_.withMinSuccessfulTests(1000))

38

```

39

40

### Property Constructors

41

42

Factory methods for creating properties from various sources.

43

44

```scala { .api }

45

object Prop {

46

def apply(f: Gen.Parameters => Prop.Result): Prop

47

def apply(r: Prop.Result): Prop

48

def apply(b: Boolean): Prop

49

50

val undecided: Prop

51

val falsified: Prop

52

val proved: Prop

53

val passed: Prop

54

val exception: Prop

55

}

56

```

57

58

**Usage Examples:**

59

```scala

60

val trueProp = Prop(true)

61

val falseProp = Prop(false)

62

val customProp = Prop { params =>

63

if (params.size > 10) Prop.Result(Prop.Passed)

64

else Prop.Result(Prop.Undecided)

65

}

66

```

67

68

### Universal Quantifiers (forAll)

69

70

Properties that must hold for all generated inputs, with support for explicit and implicit generators.

71

72

```scala { .api }

73

// With explicit generators (1-8 parameters)

74

def forAll[T1, P](g1: Gen[T1])(f: T1 => P)(implicit pp: P => Prop): Prop

75

def forAll[T1, T2, P](g1: Gen[T1], g2: Gen[T2])(f: (T1, T2) => P)(implicit pp: P => Prop): Prop

76

def forAll[T1, T2, T3, P](g1: Gen[T1], g2: Gen[T2], g3: Gen[T3])(f: (T1, T2, T3) => P)(implicit pp: P => Prop): Prop

77

// ... up to 8 parameters

78

79

// With implicit generators (1-8 parameters)

80

def forAll[A1, P](f: A1 => P)(implicit a1: Arbitrary[A1], pp: P => Prop): Prop

81

def forAll[A1, A2, P](f: (A1, A2) => P)(implicit a1: Arbitrary[A1], a2: Arbitrary[A2], pp: P => Prop): Prop

82

def forAll[A1, A2, A3, P](f: (A1, A2, A3) => P)(implicit a1: Arbitrary[A1], a2: Arbitrary[A2], a3: Arbitrary[A3], pp: P => Prop): Prop

83

// ... up to 8 parameters

84

85

// No-shrink variants

86

def forAllNoShrink[T1, P](g1: Gen[T1])(f: T1 => P)(implicit pp: P => Prop): Prop

87

// ... similar variants up to 8 parameters

88

```

89

90

**Usage Examples:**

91

```scala

92

// Implicit generators

93

val listReverseProp = forAll { (l: List[Int]) =>

94

l.reverse.reverse == l

95

}

96

97

// Explicit generators

98

val smallIntProp = forAll(Gen.choose(1, 100)) { n =>

99

n > 0 && n <= 100

100

}

101

102

// Multiple parameters

103

val additionProp = forAll(Gen.choose(1, 100), Gen.choose(1, 100)) { (a, b) =>

104

a + b > a && a + b > b

105

}

106

107

// No shrinking for performance-sensitive tests

108

val noShrinkProp = forAllNoShrink(complexGen) { data =>

109

expensiveProperty(data)

110

}

111

```

112

113

### Existential Quantifiers

114

115

Properties that must hold for at least one generated input.

116

117

```scala { .api }

118

def exists[A, P](f: A => P)(implicit a: Arbitrary[A], pp: P => Prop): Prop

119

def exists[A, P](g: Gen[A])(f: A => P)(implicit pp: P => Prop): Prop

120

```

121

122

**Usage Examples:**

123

```scala

124

val existsPrime = exists { (n: Int) =>

125

n > 1 && isPrime(n)

126

}

127

128

val existsEven = exists(Gen.choose(1, 100)) { n =>

129

n % 2 == 0

130

}

131

```

132

133

### Property Equality and Comparison

134

135

Specialized properties for testing equality relationships.

136

137

```scala { .api }

138

def ?=[T](x: T, y: T): Prop

139

def =?[T](x: T, y: T): Prop

140

```

141

142

**Usage Examples:**

143

```scala

144

val equalityProp = forAll { (s: String) =>

145

s.length ?= s.toList.length

146

}

147

148

val reverseEqualityProp = forAll { (l: List[Int]) =>

149

l.size =? l.reverse.size

150

}

151

```

152

153

### Property Combinators

154

155

Combining and transforming properties with logical operators.

156

157

```scala { .api }

158

def all(ps: Prop*): Prop

159

def atLeastOne(ps: Prop*): Prop

160

def collect[T](t: T)(prop: Prop): Prop

161

def classify(c: => Boolean, ifTrue: Any)(prop: Prop): Prop

162

def classify(c: => Boolean, ifTrue: Any, ifFalse: Any)(prop: Prop): Prop

163

```

164

165

**Usage Examples:**

166

```scala

167

val allProps = all(

168

forAll((x: Int) => x + 0 == x),

169

forAll((x: Int) => x * 1 == x),

170

forAll((x: Int) => x - x == 0)

171

)

172

173

val collectingProp = forAll { (l: List[Int]) =>

174

collect(l.length) {

175

l.reverse.reverse == l

176

}

177

}

178

179

val classifyingProp = forAll { (l: List[Int]) =>

180

classify(l.isEmpty, "empty list", "non-empty list") {

181

l.reverse.length == l.length

182

}

183

}

184

```

185

186

### Exception and Safety Utilities

187

188

Testing exception behavior and protecting against unsafe operations.

189

190

```scala { .api }

191

def secure[P](p: => P)(implicit pp: P => Prop): Prop

192

def throws[T <: Throwable](c: Class[T])(x: => Any): Boolean

193

def within(maximumMs: Long)(wrappedProp: => Prop): Prop

194

```

195

196

**Usage Examples:**

197

```scala

198

val divisionProp = forAll { (a: Int, b: Int) =>

199

secure {

200

if (b != 0) a / b == a / b else throws(classOf[ArithmeticException])(a / b)

201

}

202

}

203

204

val timeoutProp = forAll { (data: LargeDataSet) =>

205

within(5000) { // 5 seconds max

206

processData(data).size >= 0

207

}

208

}

209

210

val exceptionProp = Prop(throws(classOf[IllegalArgumentException])(processInvalidInput()))

211

```

212

213

### Lazy and Delayed Evaluation

214

215

Control over property evaluation timing and recursion.

216

217

```scala { .api }

218

def delay(p: => Prop): Prop

219

def lzy(p: => Prop): Prop

220

def protect(p: => Prop): Prop

221

def sizedProp(f: Int => Prop): Prop

222

```

223

224

**Usage Examples:**

225

```scala

226

val lazyProp = lzy {

227

// Expensive property that should be evaluated lazily

228

forAll(expensiveGen)(expensiveTest)

229

}

230

231

val sizedProperty = sizedProp { size =>

232

forAll(Gen.listOfN(size, Gen.choose(1, 100))) { l =>

233

l.length == size

234

}

235

}

236

237

val protectedProp = protect {

238

// May throw during property construction

239

forAll(riskyGen)(riskyTest)

240

}

241

```

242

243

### Conditional Testing

244

245

Implication and conditional property evaluation.

246

247

```scala { .api }

248

def imply[T](x: T, f: PartialFunction[T, Prop]): Prop

249

def iff[T](x: T, f: PartialFunction[T, Prop]): Prop

250

```

251

252

**Usage Examples:**

253

```scala

254

val conditionalProp = forAll { (l: List[Int]) =>

255

imply(l) {

256

case list if list.nonEmpty => list.head == list.head

257

}

258

}

259

260

val biconditionalProp = forAll { (n: Int) =>

261

iff(n) {

262

case num if num > 0 => num * num > 0

263

}

264

}

265

```

266

267

### Implicit Extensions

268

269

Automatic conversions and operator extensions for enhanced syntax.

270

271

```scala { .api }

272

implicit def propBoolean(b: Boolean): Prop

273

implicit def AnyOperators[T](x: => T): ExtendedAny[T]

274

275

class ExtendedAny[T](x: => T) {

276

def imply(f: PartialFunction[T, Prop]): Prop

277

def iff(f: PartialFunction[T, Prop]): Prop

278

def ?=(y: T): Prop

279

def =?(y: T): Prop

280

}

281

282

class ExtendedBoolean(b: => Boolean) {

283

def ==>(p: => Prop): Prop

284

def :|(l: String): Prop

285

}

286

```

287

288

**Usage Examples:**

289

```scala

290

// Boolean to Prop conversion

291

val boolProp: Prop = (5 > 3)

292

293

// Extended operators

294

val impliedProp = (someCondition: Boolean) ==> forAll { (x: Int) => x >= 0 }

295

296

val equalityProp = forAll { (a: Int, b: Int) =>

297

(a + b) ?= (b + a)

298

}

299

300

// Labels with operators

301

val labeledProp = (x > y) :| s"Expected $x > $y"

302

```

303

304

## Types

305

306

### Property Result Types

307

308

```scala { .api }

309

case class Prop.Result(

310

status: Prop.Status,

311

args: List[Prop.Arg[Any]],

312

collected: Set[Any],

313

labels: Set[String]

314

) {

315

def success: Boolean

316

def failure: Boolean

317

def proved: Boolean

318

}

319

320

sealed trait Prop.Status

321

case object Prop.Proof extends Prop.Status

322

case object Prop.True extends Prop.Status

323

case object Prop.False extends Prop.Status

324

case object Prop.Undecided extends Prop.Status

325

case class Prop.Exception(e: Throwable) extends Prop.Status

326

327

case class Prop.Arg[+T](

328

label: String,

329

arg: T,

330

shrinks: Int,

331

origArg: T,

332

prettyArg: Pretty,

333

prettyOrigArg: Pretty

334

)

335

```

336

337

## Property Composition Patterns

338

339

### Logical Combinations

340

341

```scala

342

val mathProps =

343

forAll((a: Int) => a + 0 == a) &&

344

forAll((a: Int) => a * 1 == a) &&

345

forAll((a: Int) => a - a == 0)

346

347

val anyProps =

348

forAll((x: Int) => x > 0) ||

349

forAll((x: Int) => x == 0) ||

350

forAll((x: Int) => x < 0)

351

```

352

353

### Conditional Properties

354

355

```scala

356

val sortedListProp = forAll { (l: List[Int]) =>

357

val sorted = l.sorted

358

(l.nonEmpty ==> (sorted.head <= sorted.last)) &&

359

(sorted.length ?= l.length)

360

}

361

```

362

363

### Data Collection and Classification

364

365

```scala

366

val statisticalProp = forAll { (l: List[Int]) =>

367

classify(l.isEmpty, "empty") {

368

classify(l.length < 10, "small", "large") {

369

collect(l.length) {

370

l.reverse.reverse == l

371

}

372

}

373

}

374

}

375

```

376

377

### Property Hierarchies

378

379

```scala

380

object CollectionProperties extends Properties("Collections") {

381

val listProps = all(

382

forAll((l: List[Int]) => l.reverse.reverse == l),

383

forAll((l: List[Int]) => l ++ Nil == l),

384

forAll((l: List[Int]) => Nil ++ l == l)

385

)

386

387

val setProps = all(

388

forAll((s: Set[Int]) => s union s == s),

389

forAll((s: Set[Int]) => s intersect s == s)

390

)

391

392

property("lists") = listProps

393

property("sets") = setProps

394

}

395

```