Getting started with TestNG in Scala

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

import org.scalatest.Assertions
import scala.collection.mutable.ListBuffer
import org.testng.Assert._
import org.testng.annotations.Test
import org.testng.annotations.BeforeMethod

class ExampleSuite extends Assertions {

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

  @BeforeMethod def initialize() {
    sb = new StringBuilder("ScalaTest is ")
    lb = new ListBuffer[String]
  }

  @Test def verifyEasy() { // Uses TestNG-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)
    }
  }
}

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

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

Here's one way to run it using TestNG:

$ export RUNCLASSPATH=.:$CLASSPATH:scala-xml.jar:jcommander.jar:slf4j-api.jar
$ scala -cp $RUNCLASSPATH org.testng.TestNG -testclass ExampleSuite
[Parser] Running:
  Command line suite


===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

If you wish to give yourself the option of running with either TestNG or ScalaTest, mix in org.scalatestplus.testng.TestNGSuite. Trait TestNGSuite already mixes in Assertions:

import org.scalatestplus.testng.TestNGSuite
import scala.collection.mutable.ListBuffer
import org.testng.Assert._
import org.testng.annotations.Test
import org.testng.annotations.BeforeMethod

class ExampleSuite extends TestNGSuite {

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

  @BeforeMethod def initialize() {
    sb = new StringBuilder("ScalaTest is ")
    lb = new ListBuffer[String]
  }

  @Test def verifyEasy() { // Uses TestNG-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 TestNG test class, it can still be run with TestNG:

$ scala -cp $RUNCLASSPATH org.testng.TestNG -testclass ExampleSuite
[Parser] Running:
  Command line suite


===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

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

$ scala -cp $RUNCLASSPATH org.scalatest.run ExampleSuite
Run starting. Expected test count is: 2
ExampleSuite:
[Parser] Running:
  Command line suite

- verifyEasy
- verifyFun

===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

Run completed in 315 milliseconds.
Total number of tests run: 2
Suites: completed 2, 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"). Here's an example:

import org.scalatestplus.testng.TestNGSuite
import org.scalatest.matchers.should.Matchers
import scala.collection.mutable.ListBuffer
import org.testng.Assert._
import org.testng.annotations.Test
import org.testng.annotations.BeforeMethod

class ExampleSuite extends TestNGSuite with Matchers {

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

  @BeforeMethod  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"
    intercept[StringIndexOutOfBoundsException] {
      "concise".charAt(-1)
    }
  }
}

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

$ scala -cp $RUNCLASSPATH org.testng.TestNG -testclass ExampleSuite
[Parser] Running:
  Command line suite


===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

$ scala -cp $RUNCLASSPATH org.scalatest.run ExampleSuite
Run starting. Expected test count is: 2
ExampleSuite:
[Parser] Running:
  Command line suite


- verifyEasy
- verifyFun

===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

Run completed in 315 milliseconds.
Total number of tests run: 2
Suites: completed 2, 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-2024 Artima, Inc. All Rights Reserved.

artima