你能从输入数据动态生成 ScalaTest 的测试名称吗?
Can you dynamically generate Test names for ScalaTest from input data?
我有许多测试数据集,运行 通过相同的 ScalaTest 单元测试。如果每个测试数据集都是它自己的一组命名测试,我会很高兴,所以如果一个数据集未通过其中一项测试,我会确切地知道它是哪一个,而不是进行单个测试并查看它失败的文件。我似乎无法找到在 运行 时间生成测试名称的方法。我查看了基于 属性 和 table 的测试,目前正在使用 should behave like
共享固定装置,但其中 none 似乎可以满足我的要求。
我是不是在 ScalaTest 中发现了正确的测试方法,或者这是不可能的?
如何使用 ScalaTest 的线索机制,以便任何测试失败都可以报告为正在使用哪个数据集的线索?
You can use the withClue construct provided by Assertions,
which is extended by every style trait in ScalaTest, to add
extra information to reports of failed or canceled tests.
另请参阅 AppendedClues
上的文档
您可以在测试名称中使用 Scala 字符串替换。使用 behavior functions,这样的事情会起作用:
case class Person(name: String, age: Int)
trait PersonBehaviors { this: FlatSpec =>
// or add data set name as a parameter to this function
def personBehavior(person: => Person): Unit = {
behavior of person.name
it should s"have non-negative age: ${person.age}" in {
assert(person.age >= 0)
}
}
}
class TheTest extends FlatSpec with PersonBehaviors {
val person = Person("John", 32)
personBehavior(person)
}
这会产生如下输出:
TheTest:
John
- should have non-negative age: 32
您可以编写一个基础测试 class,并针对每个数据集对其进行扩展。像这样:
case class Person(name: String, age: Int)
abstract class MyTestBase extends WordSpec with Matchers {
def name: String
def dataSet: List[Person]
s"Data set $name" should {
"have no zero-length names" in {
dataSet.foreach { s => s.name should not be empty }
}
}
}
class TheTest extends MyTestBase {
override lazy val name = "Family" // note lazy, otherwise initialization fails
override val dataSet = List(Person("Mom", 53), Person("Dad", 50))
}
产生这样的输出:
TheTests:
Data set Family
- should have no zero-length names
您可以使用 ScalaTest 编写动态测试用例,就像 Jonathan Chow 在他的博客中写的那样:http://blog.echo.sh/2013/05/12/dynamically-creating-tests-with-scalatest.html
但是,我总是更喜欢 WordSpec
测试定义,这也适用于动态测试用例,就像 Jonathan 提到的那样。
class MyTest extends WordSpec with Matchers {
"My test" should {
Seq(1,2,3) foreach { count =>
s"run test $count" in {
count should be(count)
}
}
}
}
当运行测试它时运行 3个测试用例
TestResults
MyTest
My test
run test 1
run test 2
run test 3
ps。您甚至可以使用相同的 count
变量在同一个 foreach
函数中执行多个测试用例。
我有许多测试数据集,运行 通过相同的 ScalaTest 单元测试。如果每个测试数据集都是它自己的一组命名测试,我会很高兴,所以如果一个数据集未通过其中一项测试,我会确切地知道它是哪一个,而不是进行单个测试并查看它失败的文件。我似乎无法找到在 运行 时间生成测试名称的方法。我查看了基于 属性 和 table 的测试,目前正在使用 should behave like
共享固定装置,但其中 none 似乎可以满足我的要求。
我是不是在 ScalaTest 中发现了正确的测试方法,或者这是不可能的?
如何使用 ScalaTest 的线索机制,以便任何测试失败都可以报告为正在使用哪个数据集的线索?
You can use the withClue construct provided by Assertions, which is extended by every style trait in ScalaTest, to add extra information to reports of failed or canceled tests.
另请参阅 AppendedClues
上的文档您可以在测试名称中使用 Scala 字符串替换。使用 behavior functions,这样的事情会起作用:
case class Person(name: String, age: Int)
trait PersonBehaviors { this: FlatSpec =>
// or add data set name as a parameter to this function
def personBehavior(person: => Person): Unit = {
behavior of person.name
it should s"have non-negative age: ${person.age}" in {
assert(person.age >= 0)
}
}
}
class TheTest extends FlatSpec with PersonBehaviors {
val person = Person("John", 32)
personBehavior(person)
}
这会产生如下输出:
TheTest:
John
- should have non-negative age: 32
您可以编写一个基础测试 class,并针对每个数据集对其进行扩展。像这样:
case class Person(name: String, age: Int)
abstract class MyTestBase extends WordSpec with Matchers {
def name: String
def dataSet: List[Person]
s"Data set $name" should {
"have no zero-length names" in {
dataSet.foreach { s => s.name should not be empty }
}
}
}
class TheTest extends MyTestBase {
override lazy val name = "Family" // note lazy, otherwise initialization fails
override val dataSet = List(Person("Mom", 53), Person("Dad", 50))
}
产生这样的输出:
TheTests:
Data set Family
- should have no zero-length names
您可以使用 ScalaTest 编写动态测试用例,就像 Jonathan Chow 在他的博客中写的那样:http://blog.echo.sh/2013/05/12/dynamically-creating-tests-with-scalatest.html
但是,我总是更喜欢 WordSpec
测试定义,这也适用于动态测试用例,就像 Jonathan 提到的那样。
class MyTest extends WordSpec with Matchers {
"My test" should {
Seq(1,2,3) foreach { count =>
s"run test $count" in {
count should be(count)
}
}
}
}
当运行测试它时运行 3个测试用例
TestResults
MyTest
My test
run test 1
run test 2
run test 3
ps。您甚至可以使用相同的 count
变量在同一个 foreach
函数中执行多个测试用例。