【问题标题】:Passing additional arguments to tests with ScalaTest使用 ScalaTest 向测试传递附加参数
【发布时间】:2016-05-27 18:26:51
【问题描述】:

目前我正在使用 IntelliJ Idea 15 和 Scalatest 框架进行一些单元测试。而且我需要将自己的参数传递给测试,并以某种方式从代码中读取它们。例如: 假设我有这样的课程

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

为了使用参数运行测试,我想做一些类似的事情

test -arg_name=blabla

所以,问题是如何传递这个参数以及如何获取它。

【问题讨论】:

    标签: scala testing scalatest


    【解决方案1】:

    我发现了有趣的特征 BeforeAndAfterAllConfigMap。这个有 beforeAll 方法,带有一个参数 configMap:ConfigMap。所以这是我的解决方案:

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

    【讨论】:

    • 应该是BeforeAndAfterAllConfigMap。常规的BeforeAndAfterAll 不需要 ConfigMap
    • 如何传递带空格或 \n 等的参数?它没有逃跑
    【解决方案2】:

    scalatest中,我们可以使用configMap来传递命令参数。

    有一个使用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")))
      }
    }
    

    我们也可以使用命令行参数运行测试:

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

    scalatest runner ConfigMapFixture Test

    【讨论】:

      【解决方案3】:

      如果您已经使用 FunSpec、FunSuite 或 FlatSpec,我发现 BeforeAndAfterAllConfigMap 很容易合并到现有的 scalatest 中。您所要做的就是使用 BeforeAndAfterAllConfigMap 导入和扩展您的测试。

      您可以将参数传递给 scalatest 的一种方法是:

      1. 从命令行传递参数 系统或项目属性
      2. 在 build.gradle 文件中检索 [system|project] 属性
      3. 将步骤 2 中检索到的属性传递给 测试运行时。

      这是 FlatSpec 中的一个完整示例,但在 FunSuite 中也很容易应用:

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

      从命令行运行测试:

      ./gradlew -q spec -Pfoo=bar
      

      结果:

      $ ./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 
      

      【讨论】:

        【解决方案4】:

        我最近必须将功能标志传递给 scalatest 测试,以便我可以测试同一 API 的两个实现。我为此使用了一个环境变量。它适用于 sbt 和 maven。变量的内容将以configMap 结尾。如何处理configMap可以查看其他帖子(或the post I base this answer on)。

        您可以按如下方式传递参数“ABC”:

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

        sbt 设置:

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

        maven 设置(使用 scalatest maven 插件):

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

        【讨论】:

          猜你喜欢
          • 2014-08-15
          • 1970-01-01
          • 2017-12-08
          • 2013-04-03
          • 2011-05-13
          • 1970-01-01
          • 1970-01-01
          • 2010-12-18
          • 2013-01-13
          相关资源
          最近更新 更多