alex
alex

Reputation: 970

Passing additional arguments to tests with ScalaTest

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.

Upvotes: 8

Views: 9813

Answers (4)

contramao
contramao

Reputation: 61

I recently had to pass a feature flag to scalatest tests so I could test two implementations of the same API. I used an environment variable for this. It works for sbt & maven. The content of the variable will end up in the configMap. How to deal with the configMap you can check at other posts (or at the post I base this answer on).

You can pass the argument "ABC" as follows:

FEATURE_FLAG="ABC" sbt test
# or 
FEATURE_FLAG="ABC" mvn test

sbt setup:

// build.sbt
val featureFlagArg = sys.env.get("FEATURE_FLAG")
  .map(ff => s"-DfeatureFlag=$ff")
  .map(Tests.Argument(TestFrameworks.ScalaTest, _))
Test / testOptions ++= featureFlagArg

maven setup (using the scalatest maven plugin):

<!-- pom.xml -->
<!-- ... -->
<plugin>
  <groupId>org.scalatest</groupId>
  <artifactId>scalatest-maven-plugin</artifactId>
  <version>1.0</version>
  <configuration>
    <config>featureFlag=${env.FEATURE_FLAG}</config>
  </configuration>
  <executions>
    <execution>
      <id>test</id>
      <goals>
        <goal>test</goal>
      </goals>
    </execution>
  </executions>
</plugin>
<!-- ... -->

Upvotes: 0

yantaq
yantaq

Reputation: 4038

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 

Upvotes: 2

alex
alex

Reputation: 970

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)
  }
}

Upvotes: 10

chengpohi
chengpohi

Reputation: 14217

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

Upvotes: 8

Related Questions