我想DRY原则适用于我ScalaTest测试定义。具体而言,我想定义一个抽象测试类定义了一系列测试。所有测试都使用指示要测试的条件的参数调用某个函数。该函数的定义留给扩展类。到目前为止,这是可行的。覆盖的测试标签ScalaTest
接下来,我想标记一个曾经失败,被定为“回归”测试任何测试,所以如果我是这样的倾向,我可以只运行这些测试。
但测试最初标记在抽象类。我需要在实现类中覆盖标签或添加标签。
是否有这样做的一个干净的方式?文档暗示着,但到目前为止,我无法找到如何做到这一点的例子。
我想DRY原则适用于我ScalaTest测试定义。具体而言,我想定义一个抽象测试类定义了一系列测试。所有测试都使用指示要测试的条件的参数调用某个函数。该函数的定义留给扩展类。到目前为止,这是可行的。覆盖的测试标签ScalaTest
接下来,我想标记一个曾经失败,被定为“回归”测试任何测试,所以如果我是这样的倾向,我可以只运行这些测试。
但测试最初标记在抽象类。我需要在实现类中覆盖标签或添加标签。
是否有这样做的一个干净的方式?文档暗示着,但到目前为止,我无法找到如何做到这一点的例子。
我从来没有找到如何做到这一点的文件,但在那我能弄明白的ScalaDocs足够的信息。对于那些可能想要做这样的事情的人来说,这里是你需要知道的东西:
首先,你会想要定义你自己的特质,你可以混合来获得这种额外的行为。它将改写标签(定义),就像这样:
trait _____ extends SuiteMixin with Informing { this: Suite with Informing =>
// with Informing, etc. is so that you can call info()
// to add comments to tests - not strictly needed for this
abstract override def tags : Map[String, Set[String]] = {
// implementation
}
}
的实现必须调用super.tags
,然后添加任何需要返回之前被添加到所产生的数据结构。结果的关键将是测试的名称,该值将套标签的字符串。注意:没有标签的测试将不会出现,因此您将无法依赖迭代该对象来查找您想要操作的测试。你将不得不打电话this.testNames
并迭代。
这里是我写的,说明如何退出这个功能的代码的例子。
abstract override def tags : Map[String, Set[String]] = {
val original = super.tags
val matching = <list of what to automatically add tags to>
if (matching.isEmpty) original
else {
val tests = this.testNames.toList
def extend(result: Map[String, Set[String]], test_list: List[String]) : Map[String, Set[String]] =
if (test_list.isEmpty) result
else {
val matches = (for (p <- matching if (<applicable>)) yield true) contains true
if (! matches) extend(result, test_list.tail)
else extend(
result.updated(
test_list.head,
result.getOrElse(test_list.head, Set[String]())
+ "<tag-to-be-added>"),
test.tail
)
}
extend(original, tests)
}
}
希望这可以帮助除我以外的人。
评论如何在更优雅或scala-esque方式做到这一点,值得欢迎和赞赏。