Getting started with JUnit 3 in Scala

If you want to write JUnit 3 tests in Scala that you run with JUnit, you can enjoy more concise code by using ScalaTest's assertions and/or matchers. To use assertions, mix org.scalatest.junit.AssertionsForJUnit into your TestCase:

import junit.framework.TestCase
import org.scalatestplus.junit.AssertionsForJUnit
import scala.collection.mutable.ListBuffer
import junit.framework.Assert._

class ExampleSuite extends TestCase with AssertionsForJUnit {

  var sb: StringBuilder = _
  var lb: ListBuffer[String] = _

  override def setUp() {
    sb = new StringBuilder("ScalaTest is ")
    lb = new ListBuffer[String]
  }

  def testEasy() { // Uses JUnit-style assertions
    sb.append("easy!")
    assertEquals("ScalaTest is easy!", sb.toString)
    assertTrue(lb.isEmpty)
    lb += "sweet"
    try {
      "verbose".charAt(-1)
      fail()
    }
    catch {
      case e: StringIndexOutOfBoundsException => // Expected
    }
  }

  def testFun() { // Uses ScalaTest assertions
    sb.append("fun!")
    assert(sb.toString === "ScalaTest is fun!")
    assert(lb.isEmpty)
    lb += "sweeter"
    intercept[StringIndexOutOfBoundsException] {
      "concise".charAt(-1)
    }
  }
}
Note: JUnit differentiates between exceptions resulting from assertions, which it calls failures, and unexpected exceptions, which it calls errors. By mixing in org.scalatestplus.junit.AssertionsForJUnit, you ensure JUnit will report failures of ScalaTest assertions as failures not errors.

You can see the difference in conciseness between the JUnit assertions used by testEasy and the ScalaTest assertions used by testFun. If you compile this class with the Scala compiler, JUnit will happily run the resulting class file. Here's how you compile it:

$ export CLASSPATH=scalatest-app.jar:scalatest-plus-junit.jar:junit.jar  
$ scalac -cp $CLASSPATH ExampleSuite.scala

Here's one way to run it using JUnit:

$ export CLASSPATH=.:scala-xml.jar:scalatest-app.jar:scalatest-plus-junit.jar:junit.jar  
$ scala -cp $CLASSPATH junit.textui.TestRunner ExampleSuite
..
Time: 0.032

OK (2 tests)

If you wish to give yourself the option of running with either JUnit or ScalaTest, mix in org.scalatestplus.junit.JUnit3Suite. Trait JUnit3Suite is already a junit.framework.TestCase and already mixes in AssertionsForJUnit:

import org.scalatestplus.junit.JUnit3Suite
import scala.collection.mutable.ListBuffer
import junit.framework.Assert._

class ExampleSuite extends JUnit3Suite {

  var sb: StringBuilder = _
  var lb: ListBuffer[String] = _

  override def setUp() {
    sb = new StringBuilder("ScalaTest is ")
    lb = new ListBuffer[String]
  }

  def testEasy() { // Uses JUnit-style assertions
    sb.append("easy!")
    assertEquals("ScalaTest is easy!", sb.toString)
    assertTrue(lb.isEmpty)
    lb += "sweet"
    try {
      "verbose".charAt(-1)
      fail()
    }
    catch {
      case e: StringIndexOutOfBoundsException => // Expected
    }
  }

  def testFun() { // Uses ScalaTest assertions
    sb.append("fun!")
    assert(sb.toString === "ScalaTest is fun!")
    assert(lb.isEmpty)
    lb += "sweeter"
    intercept[StringIndexOutOfBoundsException] {
      "concise".charAt(-1)
    }
  }
}

Because ExampleSuite is still a JUnit TestCase, it can still be run with JUnit:

$ export CLASSPATH=.:scala-xml.jar:scalatest-app.jar:scalatest-plus-junit.jar:junit.jar  
$ scala -cp $CLASSPATH junit.textui.TestRunner ExampleSuite
..
Time: 0.032

OK (2 tests)

But because it is also a ScalaTest Suite, you can now also run it with ScalaTest:

$ export CLASSPATH=.:scala-xml.jar:scalatest-app.jar:scalatest-plus-junit.jar:junit.jar  
$ scala -cp $CLASSPATH org.scalatest.run ExampleSuite
Run starting. Expected test count is: 2
ExampleSuite:
- testFun(ExampleSuite)
- testEasy(ExampleSuite)
Run completed in 189 milliseconds.
Total number of tests run: 2
Suites: completed 1, aborted 0
Tests: succeeded 2, failed 0, ignored 0, pending 0
All tests passed.

One final variation you may wish to try is to use ScalaTest's matchers DSL. Simply mix in org.scalatest.matchers.should.Matchers (or org.scalatest.matchers.must.Matchers if you prefer "must" to "should") and AssertionsForJUnit. Here's an example:

import org.scalatestplus.junit.JUnit3Suite
import org.scalatestplus.junit.AssertionsForJUnit
import org.scalatest.matchers.should.Matchers
import scala.collection.mutable.ListBuffer
import junit.framework.Assert._

class ExampleSuite extends JUnit3Suite  with Matchers with AssertionsForJUnit {

  var sb: StringBuilder = _
  var lb: ListBuffer[String] = _

  override def setUp() {
    sb = new StringBuilder("ScalaTest is ")
    lb = new ListBuffer[String]
  }

  def testEasy() { // Uses ScalaTest assertions
    sb.append("easy!")
    assert(sb.toString === "ScalaTest is easy!")
    assert(lb.isEmpty)
    lb += "sweet"
    intercept[StringIndexOutOfBoundsException] {
      "concise".charAt(-1)
    }
  }

  def testFun() { // Uses ScalaTest matchers
    sb.append("fun!")
    sb.toString should be ("ScalaTest is fun!")
    lb should be ('empty)
    lb += "sweeter"
    evaluating { "clear".charAt(-1) } should produce [StringIndexOutOfBoundsException]
  }
}

As before, you can run this class with either JUnit or ScalaTest:

$ export CLASSPATH=.:scala-xml.jar:scalatest-app.jar:scalatest-plus-junit.jar:junit.jar  
$ scala -cp $CLASSPATH junit.textui.TestRunner ExampleSuite
..
Time: 0.082

OK (2 tests)

$ scala -cp $CLASSPATH org.scalatest.run ExampleSuite
Run starting. Expected test count is: 2
ExampleSuite:
- testFun(ExampleSuite)
- testEasy(ExampleSuite)
Run completed in 116 milliseconds.
Total number of tests run: 2
Suites: completed 1, aborted 0
Tests: succeeded 2, failed 0, ignored 0, pending 0
All tests passed.

ScalaTest is brought to you by Bill Venners and Artima.
ScalaTest is free, open-source software released under the Apache 2.0 license.

If your company loves ScalaTest, please consider sponsoring the project.

Copyright © 2009-2025 Artima, Inc. All Rights Reserved.

artima