Passing additional arguments to tests with ScalaTest

scalatest multiple test cases
scala unit test examples
scalatest args
scalatest cleanup
scalatest before one test
scala sample test
scala unit test intellij
maven run scala tests

Currently I'm using IntelliJ Idea 15 and Scalatest framework to make some unit tests. And I need to pass my own arguments into test and somehow read them from code. For instance: Suppose I have such class

class Test extends FunSuite {
   test("Some test") {
       val arg = // here I want to get an argument which I want to pass. Something like args("arg_name")
       println(arg)
       assert(2 == 2)
   }
}

And to run the test with argument I want to do something like

test -arg_name=blabla

So, the question is how to pass this an argument and how to obtain it.

In scalatest, we can use configMap to pass command parameters.

There is an example with using configMap:

import org.scalatest.{ConfigMap, fixture}

class TestSuite extends fixture.Suite with fixture.ConfigMapFixture{
  def testConfigMap(configMap: Map[String, Any]) {
    println(configMap.get("foo"))
    assert(configMap.get("foo").isDefined)
  }
}

object Test {
  def main(args: Array[String]): Unit = {
    (new TestSuite).execute(configMap = ConfigMap.apply(("foo","bar")))
  }
}

also we can run test with command line parameters:

scala -classpath scalatest-<version>.jar org.scalatest.tools.Runner -R compiled_tests -Dfoo=bar

scalatest runner ConfigMapFixture Test

Passing parameter to scala test, which are executed via sbt, getOrElse("defaultValue"). Unfortunately this solution doesn't fit any more. Are there any simple solutions like this, but without using SBT_OPTS? Thanks. share. You can pass arguments to ScalaTest by using testOptions and Tests.Argument in your sbt build file: testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-oD") The -oD argument above will be pass to ScalaTest for all test runs, you can also pass arguments for individual runs by using test-only and placing them after -- , like this:

I found interesting trait BeforeAndAfterAllConfigMap. This one has beforeAll method with a parameter configMap: ConfigMap. So here is my solution:

class Test extends FunSuite with BeforeAndAfterAllConfigMap {

  override def beforeAll(configMap: ConfigMap) = {
    //here will be some stuff and all args are available in configMap
  }

  test("Some test") {
    val arg = // here I want to get an argument which I want to pass. Something like args("arg_name")
    println(arg)
    assert(2 == 2)
  }
}

org.scalatest.Args, Arguments bundle passed to four of ScalaTest's lifecycle methods: run def run(​testName: Option[String], args: Args) def runNestedSuites(args: Args) def a ConfigMap of key-value pairs that can be used by the executing Suite of tests. ScalaTest 3.1.1 - org.scalatest.Args. Arguments bundle passed to four of ScalaTest's lifecycle methods: run, runNestedSuites, runTests, and runTest. The signatures of these methods, defined in trait Suite, are:

I found BeforeAndAfterAllConfigMap incorporates into existing scalatest easily if you have already using FunSpec, FunSuite or FlatSpec. all you have to do is import & extend your test with BeforeAndAfterAllConfigMap.

One of the ways you can pass argument to scalatest is:

  1. Pass the argument from command line as either system or project property
  2. In build.gradle file retrieve the [system|project] property
  3. Pass property retrieved in step 2 to test runtime.

Here is a complete example in FlatSpec but easily applicable in FunSuite as well:

package com.passarg.test
import org.scalatest.{BeforeAndAfterAllConfigMap, ConfigMap, FlatSpec}

class PassArgsToScala extends FlatSpec with BeforeAndAfterAllConfigMap { 

  var foo = ""

  override def beforeAll(configMap: ConfigMap) = {
      // foo=bar is expected to be passed as argument
      if (configMap.get("foo").isDefined) {
          foo = configMap.get("foo").fold("")(_.toString)
      }
      println("foo=" + foo)
  }

  "Arg passed" must "be bar" in {
      assert(foo === "bar")
      info("passing arg seem to work ==> " + "foo=" + foo)
  }
}

build.gradle

apply plugin: 'scala'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.scala-lang:scala-library:2.11.8'
    testCompile 'org.scalatest:scalatest_2.11:3.0.0'
}

task spec(dependsOn: ['testClasses']) {
    javaexec {
        main = 'org.scalatest.tools.Runner'
        args = ['-R', 'build/classes/test', '-o']
        args += '-m'
        args += 'com.passarg.test'
        if (project.hasProperty("foo")) {
            args += "-Dfoo=" + project.foo
        }
        classpath = sourceSets.test.runtimeClasspath
   }
}

Running the test from command-line:

./gradlew -q spec -Pfoo=bar

Result:

$ ./gradlew -q spec -Pfoo=bar
...
Run starting. Expected test count is: 1
PassArgsToScala:
Arg passed
- must be bar
   + passing arg seem to work ==> foo=bar 

Invoking execute, If you provide a value for the configMap parameter, this method will pass it to run For more information on how to use a config map to configure your test suites,  Problem: You want to use test-driven development (TDD) style unit tests in your Scala applications, and need to see examples of how to write them. Solution. Have your test classes extend the ScalaTest FunSuite, and then write your tests.

Sharing tests, To accomplish this in a FlatSpec , you first place shared tests in behavior functions. function, into which you pass the stack fixture to use when running the tests. complaining that multiple tests are being registered with the same test name. To specify test framework arguments as part of the build, add options constructed by Tests.Argument: Test / testOptions += Tests.Argument("-verbosity", "1") To specify them for a specific test framework only: Test / testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "1") Setup and Cleanup

use the Runner, If you just want to run a suite of tests from the command line and see results on the standard The arguments Runner accepts are described in the following table: Multiple appearances of -f and -C result in multiple reporters unless the specified <filename> or Runner will pass the dispatch reporter to executed suites. In any Scala program, you can write assertions by invoking assert and passing in a Boolean expression, such as: val left = 2 val right = 1 assert(left == right) If the passed expression is true, assert will return normally. If false, assert will complete abruptly with an AssertionError.

Using ScalaTest with sbt, By default, sbt buffers log output for each suite until all tests for that suite complete and list of fully qualified names and globs to further reduce the tests selected. You can pass arguments to ScalaTest by using testOptions and Tests​. ScalaTest 112: How to run ScalaTest unit tests in Eclipse As mentioned, these tips and tutorials come from the Scala Cookbook . If you like these simple tips, I think you’ll like the book, which covers Scala collections, actors, concurrency, functional programming, traits, SBT, idioms, and much more.

Comments
  • That should be BeforeAndAfterAllConfigMap. Regular BeforeAndAfterAll doesn't take a ConfigMap
  • how to I pass arguments with space or \n etc? It isnt escaping