【问题标题】:ScalaTest: Is there a flaw defining Test Suites as object rather than class?ScalaTest:将测试套件定义为对象而不是类是否存在缺陷?
【发布时间】:2017-01-20 21:47:52
【问题描述】:

我有一个非常具体的用例,为了减少测试套件的实例化时间,我将它们定义为一个对象而不是一个类,例如

import org.scalatest._
import scala.collection.mutable.Stack

object StackSuite extends FunSuite with Matchers {
    test("stackShouldPopValuesIinLastInFirstOutOrder") {
        val stack = new Stack[Int]
        stack.push(1)
        stack.push(2)
        stack.pop() should equal(2)
        stack.pop() should equal(1)
     }
}

这可行,但这样做是否存在根本问题或缺陷?如果每个测试单独执行,并且在套件级别具有可修改状态的不幸情况下,应该与多线程问题分开。

更新:当我说“减少实例化时间”时,我的意思是整体,例如考虑对象/类中的重量级夹具数据,而不仅仅是纯 Suite 类实例化时间。由于 object 是一个单例,因此它将是一个查找而不是一个新类的实例化。

我需要这样做以便在计算机网格中分发数百万个测试。有些测试是标准的,有些测试是评估一组输入参数的排列,因此需要减少套件实例化的启动时间。

顺便说一句,我这样做是为了在集群机器中执行每个测试:

import scala.reflect.runtime.universe

// I receive the suite and test names as input   
val suite = "com.mycomp.StackSuite"
val test = "stackShouldPopValuesIinLastInFirstOutOrder"

val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val module = runtimeMirror.staticModule(suite)
val obj = runtimeMirror.reflectModule(module)
val status = obj.asInstanceOf[TestSuite].execute(test)

【问题讨论】:

  • 查看我的更新答案。

标签: scala scalatest


【解决方案1】:

为了减少测试套件的实例化时间,我将它们定义为对象而不是类

我快速浏览了org.scalatest.tools.Runner(和DiscoverySuite)的实现,我认为这不会减少实例化时间。

记住how objects are actually compiled on JVM:你有一个class StackSuite$,它扩展了Suite,并且有一个公共的无参数构造函数(因为它必须从StackSuite的静态初始化器中调用)。它的查找和处理方式与 class StackSuite 完全一样。

编辑:如果您找到该套件并以这种方式自己运行它,而不是使用 ScalaTest 自己的 API,那么是的,您将获得查找而不是实例化。假设没有并发问题,应该没有问题:execute 本身就是线程安全的。

【讨论】:

    【解决方案2】:

    如果你觉得不需要通过继承来模块化你的测试,那么使用 Object 而不是类是没有问题的。其他类可以帮助您分离不同类型的测试。

    来自ScalaTest docs

    我们建议您为项目创建抽象基类,将您最常使用的功能混合在一起,而不是通过重复混合相同的特征来复制代码。例如,您可以为单元测试创​​建一个 UnitSpec 类(不是 trait,用于更快的编译),如下所示:

    package com.mycompany.myproject
    
    import org.scalatest._
    
    abstract class UnitSpec extends FlatSpec with Matchers with
    OptionValues with Inside with Inspectors
    

    然后您可以使用自定义基类为您的项目编写单元测试,如下所示:

    package com.mycompany.myproject
    
    import org.scalatest._
    
    class MySpec extends UnitSpec {
      // Your tests here
    }
    

    【讨论】:

      猜你喜欢
      • 2011-02-07
      相关资源
      最近更新 更多