8

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.

4 Answers 4

10

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)
  }
}
Sign up to request clarification or add additional context in comments.

2 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
8

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

Comments

2

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 

Comments

0

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>
<!-- ... -->

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.