从内部测试访问ScalaTest测试的名字吗?(Access ScalaTest test name

2019-08-16 21:54发布

是否有可能访问当前正在执行的测试的名称,从ScalaTest测试中? (和我将如何做呢?)

背景:

我测试我的数据访问对象最终抛出OverQuotaException如果用户如创建页面太多。 这些测试需要相当长的运行。 为了更快乐,我想打印的进展到标准输出 - 而且由于有相当多的测试,我想在输出中包含测试的名字,所以我知道什么是测试当前正在运行。

(我没有在这里找到任何看似相关的功能: http://www.artima.com/docs-scalatest-2.0.M5/#org.scalatest.FreeSpec )

例:

  "QuotaCharger can" - {
    "charge and decline quota consumers" - {

      "charge a per site IP number (guest user)" in {
         // ... Here, a guest user post very many comments until it's over quota.
         // This takes a little while, and there are many similar tests.

         // ---> Here <--- I'd like to access the string:
         //   "charge a per site IP number (guest user)",
         //  is that possible somehow?
      }

Answer 1:

预期的方式做到这一点是重写withFixture并捕获的测试数据。 在这种使用情况下,这是更好地覆盖在withFixture这样fixture.FreeSpec您可以通过测试数据为每个测试,而不是使用VAR。 在该信息是在这里:

http://www.artima.com/docs-scalatest-2.0.M5/org/scalatest/FreeSpec.html#withFixtureNoArgTest

当我今天早上看到你的问题,我意识到ScalaTest应该有一个特点,做这一点,所以我只是增加了一个。 这将是2.0.M6,下一个里程碑版本,但在此期间,您可以使用一个本地副本。 这里是:

import org.scalatest._

/**
 * Trait that when mixed into a <code>fixture.Suite</code> passes the
 * <code>TestData</code> passed to <code>withFixture</code> as a fixture into each test.
 *
 * @author Bill Venners
 */
trait TestDataFixture { this: fixture.Suite =>

  /**
   * The type of the fixture, which is <code>TestData</code>.
   */
  type FixtureParam = TestData

  /**
   * Invoke the test function, passing to the the test function to itself, because
   * in addition to being the test function, it is the <code>TestData</code> for the test.
   *
   * <p>
   * To enable stacking of traits that define <code>withFixture(NoArgTest)</code>, this method does not
   * invoke the test function directly. Instead, it delegates responsibility for invoking the test function
   * to <code>withFixture(NoArgTest)</code>.
   * </p>
   *
   * @param test the <code>OneArgTest</code> to invoke, passing in the
   *   <code>TestData</code> fixture
   */
  def withFixture(test: OneArgTest) {
    withFixture(test.toNoArgTest(test))
  }
}

你会使用这样的:

import org.scalatest._

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


Answer 2:

创建自己的特质,让说RichFreeSpec

trait RichFreeSpec extends Free {
  protected final class RichFreeSpecStringWrapper(name: scala.Predef.String) {
    def in(f: String => scala.Unit) {
      def f2 = f(name)
      new WordSpecStringWrapper(string).in(f2)
    }
  }  

  protected implicit def convertToRichFreeSpecStringWrapper(n: scala.Predef.String): = {
    new RichFreeSpecStringWrapper(n)
  }
}

不仅仅是使用:

"sth" in { testName => 
   ...
 }

当然,你可以更进一步,实现完整的名称层次结构。



Answer 3:

这里有一个解决方案。 扩展此类,而不是FreeSpec。 许可: CC0 。

编辑:这不会同时进行测试的工作,虽然。

(这种方法与其他答案之间的区别在于,1)这里有一个currentTestName领域,对方的回答测试名被传递给测试体,和2)该测试的名称包括级联+中的所有测试分支名称实际测试的名字,而对方的回答的测试名称正是考验名(不含测试分支名称)。)

(哎呀,你需要使用getOrElse ...而不是我的可爱getOrDie 。)

/**
 * Adds a field `currentTestName` that you can use inside a FreeSpec test,
 * if you for example have many tests that take rather long, and you wonder
 * which one is currently running.
 */
trait RichFreeSpec extends FreeSpec {

  private var _currentTestName: Option[String] = None
  def currentTestName = _currentTestName getOrDie "DwE90RXP2"

  protected override def runTest(testName: String, args: org.scalatest.Args) {
    _currentTestName = Some(testName)
    super.runTest(testName, args)
  }
}


文章来源: Access ScalaTest test name from inside test?