How to run Scala project tests with SBT and ScalaTest

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 18.3, “How to run Scala tests with SBT and ScalaTest.”

Problem

You want to set up an SBT project with ScalaTest, and run the tests with SBT.

Solution

Create a new SBT project directory structure as shown in Recipe 18.1, and then add the ScalaTest library dependency to your build.sbt file, as shown here:

name := "BasicProjectWithScalaTest"

version := "1.0"

scalaVersion := "2.10.0"

libraryDependencies += "org.scalatest" % "scalatest_2.10" % "1.9.1" % "test"

Add your Scala source code under the src/main/scala folder, add your tests under the src/test/scala folder, and then run the tests with the SBT test command:

$ sbt test

Discussion

The libraryDependencies tag in the build.sbt file shows the standard way of adding new dependencies to an SBT project:

libraryDependencies += "org.scalatest" % "scalatest_2.10" % "1.9.1" % "test"

You can write that line as shown, or this way:

libraryDependencies += "org.scalatest" %% "scalatest" % "1.9.1" % "test"

In the second example, I used the %% method to automatically append the project’s Scala version (2.10) to the end of the artifact name (scalatest). These two options are explained more in Recipe 18.4, “Managing Scala Dependencies with SBT”, but hopefully the way they work is clear from those examples.

To demonstrate how ScalaTest integrates seamlessly with SBT, create a source file named Hello.scala with the following contents in the src/main/scala directory of your project:

package com.alvinalexander.testproject

object Hello extends App {
  val p = Person("Alvin Alexander")
  println("Hello from " + p.name)
}

case class Person(var name: String)

Then create a test file named HelloTests.scala in the src/test/scala directory of your project with these contents:

package com.alvinalexander.testproject

import org.scalatest.FunSuite

class HelloTests extends FunSuite {
    test("the name is set correctly in constructor") {
        val p = Person("Barney Rubble")
        assert(p.name == "Barney Rubble")
    }
    test("a Person's name can be changed") {
        val p = Person("Chad Johnson")
        p.name = "Ochocinco"
        assert(p.name == "Ochocinco")
    }
}

Next, run your tests from your project’s root directory with SBT:

$ sbt test
[info] Loading global plugins from /Users/Al/.sbt/plugins
[info] Set current project to BasicProjectWithScalaTest (in build
       file:/Users/Al/Projects/BasicProjectWithScalaTest/)
[info] HelloTests:

[info] - the name is set correctly in constructor
[info] - a Person's name can be changed
[info] Passed: : Total 2, Failed 0, Errors 0, Passed 2, Skipped 0
[success] Total time: 0 s

This output shows that the two tests in the HelloTests test class were run.

As shown in these examples, there’s nothing special you have to do to make ScalaTest work with SBT, other than adding it as a dependency in the build.sbt file; it just works.

If you reused an existing SBT project folder to test this recipe, you may need to issue the SBT reload command. As described in Table 18-1, this command tells SBT to reload the project definition files, including the build.sbt file.

See Also