ScalaTest:是否存在将测试套件定义为对象而不是 class 的缺陷?
ScalaTest: Is there a flaw defining Test Suites as object rather than class?
我有一个非常具体的用例,为了减少测试套件的实例化时间,我将它们定义为对象而不是 class,例如
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)
}
}
这是可行的,但这样做是否存在根本问题或缺陷?如果每个测试单独执行,并且在套件级别具有可修改状态的不幸情况下,则应与多线程问题分开。
更新:当我说 "reduce instantiation time" 时,我的意思是整体,例如考虑 object/class 内的重量级夹具数据,而不仅仅是纯 Suite class 实例化时间。由于对象是单例,因此它将是查找而不是新 class.
的实例化
我需要这样做才能在计算机网格中分发数百万个测试。一些测试是标准的 scalatest 其他测试正在评估一组输入参数的排列,因此需要减少套件实例化的启动时间。
顺便说一句,我这样做是为了在集群机器上执行每个测试:
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)
如果您觉得不需要使用继承来模块化您的测试,那么使用对象而不是 class 没有问题。否则 classes 可以帮助您区分不同类型的测试。
来自ScalaTest docs :
Instead of duplicating code by mixing the same traits together repeatedly, we recommend you create abstract base classes for your project that mix together the features you use the most. For example, you might create a UnitSpec class (not trait, for speedier compiles) for unit tests that looks like:
package com.mycompany.myproject
import org.scalatest._
abstract class UnitSpec extends FlatSpec with Matchers with
OptionValues with Inside with Inspectors
You can then write unit tests for your project using the custom base class, like this:
package com.mycompany.myproject
import org.scalatest._
class MySpec extends UnitSpec {
// Your tests here
}
in order to reduce instantiation time for the test suites I define them as an object and not as a class
我快速浏览了 org.scalatest.tools.Runner
(和 DiscoverySuite
)实现,我认为这不会减少实例化时间。
记住 how object
s are actually compiled on JVM:你有一个 class StackSuite$
扩展 Suite
并且有一个 public 无参数构造函数(因为它必须从 StackSuite
调用的静态初始值设定项)。它的发现和处理方式与 class StackSuite
完全一样。
编辑:如果您找到套件并 运行 自己以这种方式而不是使用 ScalaTest 自己的 API,那么是的,您将获得查找而不是实例化。假设没有并发问题,应该没有问题:execute
本身就是线程安全的。
我有一个非常具体的用例,为了减少测试套件的实例化时间,我将它们定义为对象而不是 class,例如
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)
}
}
这是可行的,但这样做是否存在根本问题或缺陷?如果每个测试单独执行,并且在套件级别具有可修改状态的不幸情况下,则应与多线程问题分开。
更新:当我说 "reduce instantiation time" 时,我的意思是整体,例如考虑 object/class 内的重量级夹具数据,而不仅仅是纯 Suite class 实例化时间。由于对象是单例,因此它将是查找而不是新 class.
的实例化我需要这样做才能在计算机网格中分发数百万个测试。一些测试是标准的 scalatest 其他测试正在评估一组输入参数的排列,因此需要减少套件实例化的启动时间。
顺便说一句,我这样做是为了在集群机器上执行每个测试:
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)
如果您觉得不需要使用继承来模块化您的测试,那么使用对象而不是 class 没有问题。否则 classes 可以帮助您区分不同类型的测试。
来自ScalaTest docs :
Instead of duplicating code by mixing the same traits together repeatedly, we recommend you create abstract base classes for your project that mix together the features you use the most. For example, you might create a UnitSpec class (not trait, for speedier compiles) for unit tests that looks like:
package com.mycompany.myproject
import org.scalatest._
abstract class UnitSpec extends FlatSpec with Matchers with
OptionValues with Inside with Inspectors
You can then write unit tests for your project using the custom base class, like this:
package com.mycompany.myproject
import org.scalatest._
class MySpec extends UnitSpec {
// Your tests here
}
in order to reduce instantiation time for the test suites I define them as an object and not as a class
我快速浏览了 org.scalatest.tools.Runner
(和 DiscoverySuite
)实现,我认为这不会减少实例化时间。
记住 how object
s are actually compiled on JVM:你有一个 class StackSuite$
扩展 Suite
并且有一个 public 无参数构造函数(因为它必须从 StackSuite
调用的静态初始值设定项)。它的发现和处理方式与 class StackSuite
完全一样。
编辑:如果您找到套件并 运行 自己以这种方式而不是使用 ScalaTest 自己的 API,那么是的,您将获得查找而不是实例化。假设没有并发问题,应该没有问题:execute
本身就是线程安全的。