CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scalacheck--scalacheck-2-12

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.

Pending
Overview
Eval results
Files

properties.mddocs/

Property Framework

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.

Capabilities

Core Property Class

The fundamental property abstraction with logical combinators and execution methods.

abstract class Prop {
  def apply(prms: Gen.Parameters): Prop.Result
  def &&(p: => Prop): Prop
  def ||(p: => Prop): Prop
  def ++(p: => Prop): Prop
  def ==>(p: => Prop): Prop
  def ==(p: => Prop): Prop
  def check(): Unit
  def check(prms: Test.Parameters): Unit
  def check(paramFun: Test.Parameters => Test.Parameters): Unit
  def label(l: String): Prop
  def :|(l: String): Prop
  def |:(l: String): Prop
  def useSeed(seed: Seed): Prop
  def viewSeed(name: String): Prop
}

Usage Examples:

val prop1 = Prop.forAll { (x: Int) => x + 0 == x }
val prop2 = Prop.forAll { (x: Int) => x * 1 == x }
val combinedProp = prop1 && prop2
val conditionalProp = (prop1 ==> prop2).label("identity laws")

combinedProp.check()
conditionalProp.check(_.withMinSuccessfulTests(1000))

Property Constructors

Factory methods for creating properties from various sources.

object Prop {
  def apply(f: Gen.Parameters => Prop.Result): Prop
  def apply(r: Prop.Result): Prop
  def apply(b: Boolean): Prop
  
  val undecided: Prop
  val falsified: Prop
  val proved: Prop
  val passed: Prop
  val exception: Prop
}

Usage Examples:

val trueProp = Prop(true)
val falseProp = Prop(false)
val customProp = Prop { params =>
  if (params.size > 10) Prop.Result(Prop.Passed) 
  else Prop.Result(Prop.Undecided)
}

Universal Quantifiers (forAll)

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

// With explicit generators (1-8 parameters)
def forAll[T1, P](g1: Gen[T1])(f: T1 => P)(implicit pp: P => Prop): Prop
def forAll[T1, T2, P](g1: Gen[T1], g2: Gen[T2])(f: (T1, T2) => P)(implicit pp: P => Prop): Prop
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
// ... up to 8 parameters

// With implicit generators (1-8 parameters) 
def forAll[A1, P](f: A1 => P)(implicit a1: Arbitrary[A1], pp: P => Prop): Prop
def forAll[A1, A2, P](f: (A1, A2) => P)(implicit a1: Arbitrary[A1], a2: Arbitrary[A2], pp: P => Prop): Prop
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
// ... up to 8 parameters

// No-shrink variants
def forAllNoShrink[T1, P](g1: Gen[T1])(f: T1 => P)(implicit pp: P => Prop): Prop
// ... similar variants up to 8 parameters

Usage Examples:

// Implicit generators
val listReverseProp = forAll { (l: List[Int]) =>
  l.reverse.reverse == l
}

// Explicit generators
val smallIntProp = forAll(Gen.choose(1, 100)) { n =>
  n > 0 && n <= 100
}

// Multiple parameters
val additionProp = forAll(Gen.choose(1, 100), Gen.choose(1, 100)) { (a, b) =>
  a + b > a && a + b > b
}

// No shrinking for performance-sensitive tests
val noShrinkProp = forAllNoShrink(complexGen) { data =>
  expensiveProperty(data)
}

Existential Quantifiers

Properties that must hold for at least one generated input.

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

Usage Examples:

val existsPrime = exists { (n: Int) =>
  n > 1 && isPrime(n)
}

val existsEven = exists(Gen.choose(1, 100)) { n =>
  n % 2 == 0
}

Property Equality and Comparison

Specialized properties for testing equality relationships.

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

Usage Examples:

val equalityProp = forAll { (s: String) =>
  s.length ?= s.toList.length
}

val reverseEqualityProp = forAll { (l: List[Int]) =>
  l.size =? l.reverse.size  
}

Property Combinators

Combining and transforming properties with logical operators.

def all(ps: Prop*): Prop
def atLeastOne(ps: Prop*): Prop
def collect[T](t: T)(prop: Prop): Prop
def classify(c: => Boolean, ifTrue: Any)(prop: Prop): Prop
def classify(c: => Boolean, ifTrue: Any, ifFalse: Any)(prop: Prop): Prop

Usage Examples:

val allProps = all(
  forAll((x: Int) => x + 0 == x),
  forAll((x: Int) => x * 1 == x),
  forAll((x: Int) => x - x == 0)
)

val collectingProp = forAll { (l: List[Int]) =>
  collect(l.length) {
    l.reverse.reverse == l
  }
}

val classifyingProp = forAll { (l: List[Int]) =>
  classify(l.isEmpty, "empty list", "non-empty list") {
    l.reverse.length == l.length
  }
}

Exception and Safety Utilities

Testing exception behavior and protecting against unsafe operations.

def secure[P](p: => P)(implicit pp: P => Prop): Prop
def throws[T <: Throwable](c: Class[T])(x: => Any): Boolean
def within(maximumMs: Long)(wrappedProp: => Prop): Prop

Usage Examples:

val divisionProp = forAll { (a: Int, b: Int) =>
  secure {
    if (b != 0) a / b == a / b else throws(classOf[ArithmeticException])(a / b)
  }
}

val timeoutProp = forAll { (data: LargeDataSet) =>
  within(5000) { // 5 seconds max
    processData(data).size >= 0
  }
}

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

Lazy and Delayed Evaluation

Control over property evaluation timing and recursion.

def delay(p: => Prop): Prop
def lzy(p: => Prop): Prop  
def protect(p: => Prop): Prop
def sizedProp(f: Int => Prop): Prop

Usage Examples:

val lazyProp = lzy {
  // Expensive property that should be evaluated lazily
  forAll(expensiveGen)(expensiveTest)
}

val sizedProperty = sizedProp { size =>
  forAll(Gen.listOfN(size, Gen.choose(1, 100))) { l =>
    l.length == size
  }
}

val protectedProp = protect {
  // May throw during property construction
  forAll(riskyGen)(riskyTest)
}

Conditional Testing

Implication and conditional property evaluation.

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

Usage Examples:

val conditionalProp = forAll { (l: List[Int]) =>
  imply(l) {
    case list if list.nonEmpty => list.head == list.head
  }
}

val biconditionalProp = forAll { (n: Int) =>
  iff(n) {
    case num if num > 0 => num * num > 0
  }
}

Implicit Extensions

Automatic conversions and operator extensions for enhanced syntax.

implicit def propBoolean(b: Boolean): Prop
implicit def AnyOperators[T](x: => T): ExtendedAny[T]

class ExtendedAny[T](x: => T) {
  def imply(f: PartialFunction[T, Prop]): Prop
  def iff(f: PartialFunction[T, Prop]): Prop
  def ?=(y: T): Prop
  def =?(y: T): Prop
}

class ExtendedBoolean(b: => Boolean) {
  def ==>(p: => Prop): Prop
  def :|(l: String): Prop
}

Usage Examples:

// Boolean to Prop conversion
val boolProp: Prop = (5 > 3)

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

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

// Labels with operators
val labeledProp = (x > y) :| s"Expected $x > $y"

Types

Property Result Types

case class Prop.Result(
  status: Prop.Status,
  args: List[Prop.Arg[Any]],
  collected: Set[Any],
  labels: Set[String]
) {
  def success: Boolean
  def failure: Boolean
  def proved: Boolean
}

sealed trait Prop.Status
case object Prop.Proof extends Prop.Status
case object Prop.True extends Prop.Status  
case object Prop.False extends Prop.Status
case object Prop.Undecided extends Prop.Status
case class Prop.Exception(e: Throwable) extends Prop.Status

case class Prop.Arg[+T](
  label: String,
  arg: T,
  shrinks: Int,
  origArg: T,
  prettyArg: Pretty,
  prettyOrigArg: Pretty
)

Property Composition Patterns

Logical Combinations

val mathProps = 
  forAll((a: Int) => a + 0 == a) &&
  forAll((a: Int) => a * 1 == a) &&
  forAll((a: Int) => a - a == 0)

val anyProps = 
  forAll((x: Int) => x > 0) ||
  forAll((x: Int) => x == 0) ||
  forAll((x: Int) => x < 0)

Conditional Properties

val sortedListProp = forAll { (l: List[Int]) =>
  val sorted = l.sorted
  (l.nonEmpty ==> (sorted.head <= sorted.last)) &&
  (sorted.length ?= l.length)
}

Data Collection and Classification

val statisticalProp = forAll { (l: List[Int]) =>
  classify(l.isEmpty, "empty") {
    classify(l.length < 10, "small", "large") {
      collect(l.length) {
        l.reverse.reverse == l
      }
    }
  }
}

Property Hierarchies

object CollectionProperties extends Properties("Collections") {
  val listProps = all(
    forAll((l: List[Int]) => l.reverse.reverse == l),
    forAll((l: List[Int]) => l ++ Nil == l),
    forAll((l: List[Int]) => Nil ++ l == l)
  )
  
  val setProps = all(
    forAll((s: Set[Int]) => s union s == s),
    forAll((s: Set[Int]) => s intersect s == s)
  )
  
  property("lists") = listProps
  property("sets") = setProps
}

Install with Tessl CLI

npx tessl i tessl/maven-org-scalacheck--scalacheck-2-12

docs

arbitrary.md

cogen.md

generators.md

index.md

properties.md

property-collections.md

shrinking.md

stateful-testing.md

test-execution.md

tile.json