ScalaCheck Effect is a library that extends the functionality of ScalaCheck to support "effectful" properties. An effectful property is one that evaluates each sample in some type constructor F[_]. For example:
import org.scalacheck.effect.PropF import org.scalacheck.Test import cats.effect.{ExitCode, IO, IOApp} object Example extends IOApp { def run(args: List[String]): IO[ExitCode] = { val p: PropF[IO] = PropF.forAllF { (x: Int) => IO(x).map(res => assert(res == x)) } val result: IO[Test.Result] = p.check() result.flatMap(r => IO(println(r))).as(ExitCode.Success) } }Running this program results in the output: Result(Passed,100,0,Map(),0).
This library provides the org.scalacheck.effect.PropF type, which is the effectul analog to org.scalacheck.Prop. In this example, we use PropF.forAllF to write a property of the shape Int => IO[Unit]. This example uses cats.effect.IO as the type constructor, but any effect F[_] with an instance of MonadError[F, Throwable] can be used, including scala.concurrent.Future.
The key idea here is using the PropF.{forAllF, forAllNoShrinkF} methods to create PropF[F] instances. The check() method on PropF converts a PropF[F] to a F[Test.Result].
libraryDependencies += "org.typelevel" %% "scalacheck-effect" % scalacheckEffectVersionThis project also provides support for checking PropF values from within MUnit based test suites. To use scalacheck-effect with munit, add the following dependency to your build:
libraryDependencies += "org.typelevel" %% "scalacheck-effect-munit" % scalacheckEffectVersion % Testimport munit.{CatsEffectSuite, ScalaCheckEffectSuite} import org.scalacheck.effect.PropF // Example uses https://github.com/typelevel/munit-cats-effect class ExampleSuite extends CatsEffectSuite with ScalaCheckEffectSuite { test("first PropF test") { PropF.forAllF { (x: Int) => IO(x).start.flatMap(_.join).map(res => assert(res == x)) } } }- Support effectful properties without blocking.
- Compatibility with
Gen/Cogen/Arbitrary. - Parity with
Propfeatures, including shrinking. - Follow same style as ScalaCheck and use ScalaCheck reporting.
- Integrate well with popular test frameworks.
- Non-goal: provide direct support for checking effectful properties directly from SBT or from standalone app.
Calling Await.result, unsafeRunSync() or a similar blocking operation is not possible on Scala.js.
This library builds heavily on the ideas in ScalaCheck. It grew out of the FS2 AsyncPropertySuite, which only implemented a handful of features. The Weaver Test framework also has similar support for effectful properties. Finally, the Scala Hedgehog library has a prototype of similar functionality.