没有夹具的 ScalaTest 测试名称?

ScalaTest test name without fixture?

首先,我看到了 this other post 听起来和我需要的一模一样,除了一件事,我不能使用 fixture.TestDataFixture 因为我不能扩展 fixture.FreeSpecLike,而且我确信必须有 some 方法以看起来更像这样的方式获取测试名称(无法编译的想象代码)

class MySpec extends FlatSpecLike with fixture.TestDataFixture {
  "this technique" - {
     "should work" in { 
      assert(testData.name == "this technique should work")
    }
    "should be easy" in { td =>
      assert(testData.name == "this technique should be easy")
    }
  }
}

有什么想法吗?我简直不敢相信这样的事情是不可能的 :D

并找到了答案(一个同事做的很好),不确定我是否喜欢但有效:

关于其他测试所依赖的特征

class MySpec extends FlatSpecLike {
//... other stuff
    var testName = "UndefinedTestName"
    override def withFixture (test: NoArgTest) :Outcome= {
       testName = test.name
       super.withFixture(test)
   }
}

简单的解决方案但相当晦涩,我也想知道是否有人看到它有任何问题

虽然您基本上已经找到了这个解决方案,但这里有一个更安全的变体:

private val _currentTestName = new ThreadLocal[String]

override def withFixture(test: NoArgTest) = {
  _currentTestName.set(test.name)
  val outcome = super.withFixture(test)
  _currentTestName.set(null)
  outcome
}

protected def currentTestName: String = {
  val testName = _currentTestName.get()
  assert(testName != null, "currentTestName should only be called in a test")
  testName
}

或者,

protected def currentTestName = Option(_currentTestName.get())

您可以使用 FlatSpecLike 特征中的 testNames 方法找到测试名称序列:

import org.scalatest.FlatSpecLike

class FooSpec extends FlatSpecLike {

  it should "check case one" in {
    println("test some code ...")

    println(testNames.mkString("\n"))
    /*
      prints:
      should check case one
      should check case two
    */
    // ...
    assert(1 == 1)
    println("end.")
  }

  it should "check case two" in {
    println("test some code ...")

    assert(1 == 1)
    println("end.")
  }
}

并找到您需要的每一个。希望对你有帮助。