通过反射获取Scalatest方法信息

时间:2018-06-14 14:38:24

标签: scala reflection scalatest

我希望在类路径中获得有关测试的一些信息。我希望它看起来像:

class-name:method-name:test-string

例如:

MyTestClass:{some anonymous class/method}:A Stack should pop values in last-in-first-out order

我可以轻松地查询FlatSpec以获取名称和描述,但不能查询方法本身。如果我使用反射,我可以找到方法,但由于匿名名称,我不知道他们做了什么。

有谁知道如何做到这一点?

1 个答案:

答案 0 :(得分:0)

Engine.atomic可能会暗示如何解决这个问题。我们可以在Map[String, TestLeaf]结构处获取String键是测试名称,TestLeaf值包含测试函数testFun

  case class TestLeaf(
    parent: Branch,
    testName: String, // The full test name
    testText: String, // The last portion of the test name that showed up on an inner most nested level
    testFun: T, 
    location: Option[Location],
    pos: Option[source.Position],
    recordedDuration: Option[Long] = None,
    recordedMessages: Option[PathMessageRecordingInformer] = None
  ) 

以下电话会给我们上面的地图:

engine.atomic.get.testsMap

这似乎是ScalaTest用于在runTestImpl

中执行测试的内容

现在engine是私有字段成员,那么我们如何才能访问它?使用this回答我想出了类似的东西:

package org.scalatest

import java.lang.reflect.Field

class HelloSpec extends FlatSpec with Matchers {
  "The Hello object" should "say something" in {
    assert(true)
  }

  val engineField: Field = 
    this
      .getClass
      .getSuperclass
      .getDeclaredField("org$scalatest$FlatSpecLike$$engine")

  engineField.setAccessible(true)

  val engine: Engine = 
    engineField.get(this).asInstanceOf[Engine]

  val testLeaf = 
    engine.atomic.get.testsMap("The Hello object should say something")

  val testFun: () => Outcome = 
    testLeaf.testFun

  val testName: String = 
    testLeaf.testName

  val classFile: String =
    testLeaf.pos.get.fileName

  println(s"$classFile: $testFun: $testName")

}

println输出:

HelloSpec.scala: <function0>: The Hello object should say something

请注意我因为

而必须将上述反射片段放在package org.scalatest
private[scalatest] class Engine

总之,请尝试使用反射来访问TestLeaf