Configures and runs ScalaTest - Scala-native test framework with multiple specification styles (FlatSpec, FunSuite, WordSpec, FreeSpec, AsyncFlatSpec for async); Matchers DSL (`should equal`, `should contain`, `shouldBe a [Class]`); integrates with ScalaCheck for property-based testing; sbt + Maven + Gradle support; tagged-test selective execution. Use when working with Scala codebases.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Per scalatest.org:
ScalaTest is the de facto Scala testing framework. Like Kotest, it offers multiple specification styles to match team preference.
For Java/Kotlin projects, junit5-tests
or kotest-tests are more idiomatic.
ScalaTest is the right pick for Scala-primary or Scala-only projects.
scalatest (+ scalatestplus for ScalaCheck) to build.sbt as Test deps (Step 1).Matchers (Step 2).should equal, should contain, shouldBe a [Class] (references/matchers-dsl.md, Step 3).Future[Assertion] from AsyncFlatSpec bodies for async code (Step 4).forAll invariants via ScalaCheck and lifecycle hooks / loan-fixtures for setup (Steps 5-6).-n / -l (Step 7).sbt clean coverage test coverageReport in CI (Step 8).build.sbt:
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % Test
libraryDependencies += "org.scalatestplus" %% "scalacheck-1-17" % "3.2.18.0" % TestTest files live under src/test/scala/.
Per scalatest.org/user_guide/selecting_a_style:
8+ styles. Common picks:
FlatSpec (BDD-style):
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
class CalculatorSpec extends AnyFlatSpec with Matchers {
"Calculator" should "add two numbers" in {
Calculator.add(1, 2) should equal(3)
}
it should "throw on overflow" in {
an [ArithmeticException] should be thrownBy {
Calculator.add(Int.MaxValue, 1)
}
}
}FunSuite (xUnit-style):
import org.scalatest.funsuite.AnyFunSuite
class CalculatorSuite extends AnyFunSuite {
test("add two numbers") {
assert(Calculator.add(1, 2) == 3)
}
}WordSpec (deeply-nested BDD):
import org.scalatest.wordspec.AnyWordSpec
class UserServiceSpec extends AnyWordSpec with Matchers {
"A UserService" when {
"creating a user" should {
"set default role" in {
UserService.create("alice").role shouldBe "user"
}
}
}
}Pick one style per project + stick with it.
Assert with the Matchers DSL - equality (should equal / shouldBe / shouldEqual), size + membership (have size / contain / contain only / contain inOrder), map keys/values, string ops, type checks (shouldBe a [Class]), and numeric ordering + float tolerance. Full example set in references/matchers-dsl.md.
import org.scalatest.flatspec.AsyncFlatSpec
import scala.concurrent.Future
class AsyncSpec extends AsyncFlatSpec with Matchers {
"fetchUser" should "return user data" in {
fetchUser(1) map { user =>
user.id shouldBe 1
}
}
}AsyncFlatSpec test bodies return Future[Assertion] - ScalaTest
handles the async lifecycle.
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import org.scalacheck.Gen
class PropertyCheckSpec extends AnyFlatSpec with Matchers
with ScalaCheckPropertyChecks {
"addition" should "be commutative" in {
forAll { (a: Int, b: Int) =>
a + b shouldBe b + a
}
}
"concatenation length" should "be sum of lengths" in {
forAll(Gen.alphaStr, Gen.alphaStr) { (a, b) =>
(a + b).length shouldBe a.length + b.length
}
}
}Cross-ref quickcheck-testing (in the qa-property-based plugin)
for the property-based discipline (covers QuickCheck + ScalaCheck).
class WithFixturesSpec extends AnyFlatSpec with BeforeAndAfterAll
with BeforeAndAfter with Matchers {
override def beforeAll(): Unit = {
// once before all tests
}
override def afterAll(): Unit = {
// once after all tests
}
before {
// before each test
}
after {
// after each test
}
}Or use the loan-fixture pattern (functional style):
def withDatabase(test: Database => Unit): Unit = {
val db = createTestDb()
try test(db)
finally db.close()
}
"createUser" should "persist to db" in withDatabase { db =>
val user = userService.create("alice", db)
user.id should not be None
}import org.scalatest.Tag
object Slow extends Tag("Slow")
object Integration extends Tag("Integration")
class TaggedSpec extends AnyFlatSpec {
"fast operation" should "work" in {
// runs by default
}
"slow operation" should "work" taggedAs Slow in {
// skipped unless -n Slow flag
}
}Selective run: sbt 'testOnly * -- -n Slow' or
-l Slow to exclude Slow.
- run: sbt clean coverage test coverageReportCoverage via sbt-scoverage plugin (Scala-native; not JaCoCo).
Testing Calculator.add with FlatSpec + ScalaCheck:
"org.scalatest" %% "scalatest" % "3.2.19" % Test and "org.scalatestplus" %% "scalacheck-1-17" % "3.2.18.0" % Test.class CalculatorSpec extends AnyFlatSpec with Matchers with "Calculator" should "add two numbers" in { Calculator.add(1, 2) should equal(3) }.ScalaCheckPropertyChecks: forAll { (a: Int, b: Int) => a + b shouldBe b + a }.sbt test: the example passes; forAll shrinks to a minimal counterexample if commutativity breaks.sbt coverage test coverageReport for the scoverage HTML report.| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Mix specification styles in one project | Reader confusion | Pick one (Step 2) |
assert(x == y) instead of Matchers DSL | Loses diff in failure | Use x should equal(y) (Step 3) |
| Sync test bodies for async code | Future never resolves; test passes wrongly | Use AsyncFlatSpec (Step 4) |
| Skip ScalaCheck for invariants | Misses edge cases that fixed-input tests don't catch | Use forAll (Step 5) |
junit5-tests,
kotest-tests,
spock-tests,
testng-tests - sister toolsquickcheck-testing - Haskell + Scala property-basedtest-code-conventions