Back to directory
typelevel avatar

cats-effect-testing

Integration between cats-effect and test frameworks. Read more below about its uses, features, and usage.

Clone repository

git clone https://github.com/typelevel/cats-effect-testing.git

194

Stars

43

Forks

12

Watchers

Apache-2.0

License

cats-effect-testing

A quickie little utility which makes it easier to write tests using specs2 (mutable or functional), scalatest, µTest or minitest where the examples are effectful within cats.effect.IO.

Specs2

import cats.effect.IO
import cats.effect.testing.specs2.CatsEffect
import org.specs2.mutable.Specification

// for some reason, only class works here; object will not be detected by sbt
class ExampleSpec extends Specification with CatsEffect {
  "examples" should {
    "do the things" in IO {
      true must beTrue
    }
  }
}

The above compiles and runs exactly as you would expect.

By default, tests run with a 10 second timeout. If you wish to override this, simply override the inherited Timeout val:

override val Timeout = 5.seconds

If you need an ExecutionContext, one is available in the executionContext val.

And if you need to share Cats Effect's Resource between test examples you can extend CatsResource, like so:

import cats.effect.{IO, Ref, Resource}
import org.specs2.mutable.SpecificationLike

class CatsResourceSpecs extends CatsResource[IO, Ref[IO, Int]] with SpecificationLike {
  sequential

  val resource: Resource[IO, Ref[IO, Int]] =
    Resource.make(Ref[IO].of(0))(_.set(Int.MinValue))

  "cats resource support" should {
    "run a resource modification" in withResource { ref =>
      ref.modify{ a =>
        (a + 1, a)
      }.map(
        _ must_=== 0
      )
    }

    "be shared between tests" in withResource { ref =>
      ref.modify{ a =>
        (a + 1, a)
      }.map(
        _ must_=== 1
      )
    }
  }
}

The Resource is acquired before the tests are run and released afterwards. A more realistic example would be to share a Resource that takes a long time to start up.

Usage

libraryDependencies += "org.typelevel" %% "cats-effect-testing-specs2" % "<version>" % Test

Published for Scala 3.1+, 2.13, 2.12, as well as ScalaJS 1.7+. Depends on Cats Effect 3.1+ and Specs2 4.13.x. Specs2 5.0 is not yet supported.

Early versions (0.x.y) were published under the com.codecommit groupId.

ScalaTest

import cats.effect._
import cats.effect.testing.scalatest.AsyncIOSpec
import org.scalatest.matchers.should.Matchers
import org.scalatest.freespec.AsyncFreeSpec

class MySpec extends AsyncFreeSpec with AsyncIOSpec with Matchers {

  "My Code " - {
    "works" in {
      IO(1).asserting(_ shouldBe 1)
    }
}

Usage

libraryDependencies += "org.typelevel" %% "cats-effect-testing-scalatest" % "<version>" % Test

Published for Scala 3.1+, 2.13, 2.12, as well as ScalaJS 1.7.x. Depends on Cats Effect 3.1+ and scalatest 3.2.6.

Early versions (0.x.y) were published under the com.codecommit groupId.

µTest

import scala.concurrent.duration._
import utest._
import cats.syntax.all._
import cats.effect.IO
import cats.effect.testing.utest.IOTestSuite

object SimpleSuite extends IOTestSuite {
  override val timeout = 1.second // Default timeout is 10 seconds

  val tests = Tests {
    test("do the thing") {
      IO(assert(true))
    }
  }
}

Usage

libraryDependencies += "org.typelevel" %% "cats-effect-testing-utest" % "<version>" % Test

Published for Scala 3.1+, 2.13, 2.12, as well as ScalaJS 1.7.x. Depends on Cats Effect 3.1+ and µTest 0.7.9.

Early versions (0.x.y) were published under the com.codecommit groupId.

Minitest

Minitest is very similar to uTest, but being strongly typed, there's no need to support non-IO tests

import scala.concurrent.duration._
import cats.syntax.all._
import cats.effect.IO
import cats.effect.testing.minitest.IOTestSuite

object SimpleSuite extends IOTestSuite {
  override val timeout = 1.second // Default timeout is 10 seconds

  test("do the thing") {
    IO(assert(true))
  }
}

Usage

libraryDependencies += "org.typelevel" %% "cats-effect-testing-minitest" % "<version>" % Test

Published for Scala 3.1+, 2.13, 2.12, as well as ScalaJS 1.7.x. Depends on Cats Effect 3.1+ and minitest 2.9.5.

Early versions (0.x.y) were published under the com.codecommit groupId.

Similar projects

munit-cats-effect

munit-cats-effect is a very similar library to this one, but specifically targeted at munit.

scalacheck-effect

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[_].

Releases

This release updates to Scala Native 0.5 (and correspondingly, Cats Effect 3.7), meaning that it cannot be used with Scala Native 0.4. What's Changed

Update sbt-typelevel to 0.8.1 in series/1.x by @t...

Sep 17, 2025

Download .zip

Enhancements

Report resource acquisition errors in ScalaTest CatsResource by @bpholt in #635 Abstract over Specs2 test result kind to enable more consistent support for ScalaCheck by @bpholt in #616...

Fixes

Limit ScalaTest dependency to its core library by @kaharlichenko in #418 Tweak Specs2 CatsResource to rethrow exceptions raised during resource acquisition by @bpholt in #608

New Contributors...

Nov 14, 2022

Download .zip

User-Facing Pull Requests

#390 – Updated Scala and Cats Effect versions (@djspiewak) #358 – Add assertions to assertThrows (@custommonkey) #377 – Cross-build for Native (@armanbilge) #360 – Replace s...

Nov 28, 2021

Download .zip

The primary change in this release is the upgrade to Cats Effect 3.3.0, which brings with it some major changes within the cats-effect-testkit artifact. In particular, TestContext has been changed and...