How to use JUnit with Scala

Problem: You want to test your Scala code using JUnit.

Solution

Include the JUnit library in your project, and use it in the same way you’ve used it in Java projects, with a few minor changes.

Assuming you’re using SBT on your project, include JUnit into the project by adding this dependency line to your build.sbt file:

libraryDependencies += "com.novocode" % "junit-interface" % "0.8" % "test->default"

According to the SBT testing documentation, “support for JUnit is provided by junit-interface,” so you add it as a dependency here.

Next, if you’re also using Eclipse, generate your Eclipse project files:

$ sbt eclipse

Then start Eclipse and import your project as usual.

In your project, create these simple model classes in a file named Pizza.scala under the src/main/scala directory:

package com.acme.pizza

import scala.collection.mutable.ArrayBuffer

case class Topping(name: String)

class Pizza {
  
  private var toppings = new ArrayBuffer[Topping]
  
  def addTopping (t: Topping) { toppings += t}
  def removeTopping (t: Topping) { toppings -= t}
  def getToppings = toppings.toList

}

(Any directory under src/main/scala is fine. Unlike Java, Scala package names don’t have to match the directory structure.)

Next, create a JUnit test class as usual. Put the following code in a file named PizzaTests.scala under the src/test/scala directory:

package com.acme.pizza

import org.junit.Test
import junit.framework.TestCase
import org.junit.Assert._

class PizzaTests extends TestCase {

  var pizza: Pizza = _

  override def setUp {
    pizza = new Pizza
  }

  def testOneTopping {
    pizza.addTopping(Topping("green olives"))
    assertEquals(pizza.getToppings.size, 1)
  }

  def testAddingAndRemovingToppings {
    pizza.addTopping(Topping("green olives"))
    pizza.removeTopping(Topping("green olives"))
    assertEquals(pizza.getToppings.size, 0)
  }

}

If you’re using Eclipse, run the tests from the Eclipse menu system. Choose Run > Run As... > JUnit Test, and you should see your tests run successfully.

To run the tests using SBT, run the sbt test command from your operating system’s command line, in the root directory of your SBT project:

$ sbt test

The output shows that the tests passed:

[info] Passed: : Total 2, Failed 0, Errors 0, Passed 2, Skipped 0
[success] Total time: 1 s

Discussion

Beyond running a single, simple JUnit test class, you can also create additional test classes, and then a TestSuite. To demonstrate this, first create a new test class named ToppingTests.scala in the src/test/scala directory:

package com.acme.pizza

import org.junit.Test
import junit.framework.TestCase
import org.junit.Assert._

class ToppingTests {

  @Test
  def foo {
    val t1 = Topping("cheese")
    val t2 = Topping("cheese")
    assertEquals(t1, t2)
  }

}

Then create a TestSuite class named PizzaTestSuite and save it in a file named PizzaTestSuite.scala in the src/test/scala directory:

package com.acme.pizza

import org.junit.runner.RunWith
import org.junit.runners.Suite

@RunWith(classOf[Suite])
@Suite.SuiteClasses(Array(classOf[PizzaTests], classOf[ToppingTests]))
class PizzaTestSuite

If you’re using Eclipse, with this class in the editor, choose Run > Run As > JUnit Test, and you should see both your PizzaTests and ToppingTests run successfully.

If you’re using SBT, just run sbt test again.

As you’ve seen in these examples, it’s simple to use Scala with JUnit. The following lines show the major differences between using Scala instead of Java:

@RunWith(classOf[Suite])
@Suite.SuiteClasses(Array(classOf[PizzaTests], classOf[ToppingTests]))

In the first line, classOf[Suite] is used because Scala uses this syntax instead of Suite.class, which is the syntax Java uses. You do the same thing in the second line, and also replace the Java curly brackets array syntax with an Array declaration. Everything else is a straightforward port from Java to Scala.

JUnit has some advantages compared to ScalaTest or specs2. One advantage is that test execution is generally faster with JUnit. Also, you can use JUnit if you want to, and import the ScalaTest or the specs2 matchers inside your test cases if you want more expressivity for your assertions.

That being said, if you’re going to code in Scala, I recommend using ScalaTest or specs2 for testing. As a friend likes to say, when we moved from C to Java, we didn’t attempt to bring make along with us; we switched to Ant or Maven, so I’m a firm believer in using native Scala tools like SBT, ScalaTest, and specs2.

See Also