If you want to write JUnit 4 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.scalatestplus.junit.AssertionsForJUnit
into your test class:
import org.scalatestplus.junit.AssertionsForJUnit import scala.collection.mutable.ListBuffer import org.junit.Assert._ import org.junit.Test import org.junit.Before class ExampleSuite extends AssertionsForJUnit { var sb: StringBuilder = _ var lb: ListBuffer[String] = _ @Before def initialize() { sb = new StringBuilder("ScalaTest is ") lb = new ListBuffer[String] } @Test def verifyEasy() { // 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 } } @Test def verifyFun() { // Uses ScalaTest assertions sb.append("fun!") assert(sb.toString === "ScalaTest is fun!") assert(lb.isEmpty) lb += "sweeter" intercept[StringIndexOutOfBoundsException] { "concise".charAt(-1) } } }
Note: JUnit traditionally differentiated between exceptions resulting from assertions, which it called failures,
and unexpected exceptions, which it called errors. Although this JUnit 3 distinction was dropped from JUnit 4, many tools
that integrate JUnit 4 still observe the distinction.
By mixing in org.scalatestplus.junit.AssertionsForJUnit
, you ensure JUnit tools will report failures of ScalaTest assertions
as failures not errors.
You can see the difference in conciseness between the JUnit assertions used by verifyEasy
and the ScalaTest assertions
used by verifyFun
. 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 org.junit.runner.JUnitCore ExampleSuite JUnit version x.y.z .. Time: 0.046 OK (2 tests)
If you wish to give yourself the option of running with either JUnit or ScalaTest, mix in org.scalatestplus.junit.JUnitSuite
. Trait
JUnitSuite
already mixes in AssertionsForJUnit
:
import org.scalatestplus.junit.JUnitSuite import scala.collection.mutable.ListBuffer import org.junit.Assert._ import org.junit.Test import org.junit.Before class ExampleSuite extends JUnitSuite { var sb: StringBuilder = _ var lb: ListBuffer[String] = _ @Before def initialize() { sb = new StringBuilder("ScalaTest is ") lb = new ListBuffer[String] } @Test def verifyEasy() { // 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 } } @Test def verifyFun() { // 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 valid JUnit test class, it can still be run with JUnit:
$ export CLASSPATH=.:scala-xml.jar:scalatest-app.jar:scalatest-plus-junit.jar:junit.jar $ scala -cp $CLASSPATH org.junit.runner.JUnitCore ExampleSuite JUnit version x.y.z .. Time: 0.121 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: - verifyFun - verifyEasy Run completed in 190 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.JUnitSuite import org.scalatestplus.junit.AssertionsForJUnit import org.scalatest.matchers.should.Matchers import scala.collection.mutable.ListBuffer import org.junit.Test import org.junit.Before class ExampleSuite extends JUnitSuite with Matchers with AssertionsForJUnit { var sb: StringBuilder = _ var lb: ListBuffer[String] = _ @Before def initialize() { sb = new StringBuilder("ScalaTest is ") lb = new ListBuffer[String] } @Test def verifyEasy() { // Uses ScalaTest assertions sb.append("easy!") assert(sb.toString === "ScalaTest is easy!") assert(lb.isEmpty) lb += "sweet" intercept[StringIndexOutOfBoundsException] { "concise".charAt(-1) } } @Test def verifyFun() { // Uses ScalaTest matchers sb.append("fun!") sb.toString should be ("ScalaTest is fun!") lb should be ('empty) lb += "sweet" evaluating { "concise".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 org.junit.runner.JUnitCore ExampleSuite JUnit version x.y.z .. Time: 0.136 OK (2 tests) $ scala -cp $CLASSPATH org.scalatest.runner ExampleSuite Run starting. Expected test count is: 2 ExampleSuite: - verifyFun - verifyEasy Run completed in 182 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.