我想将DRY原则应用于我的ScalaTest测试定义。具体来说,我想定义一个定义一堆测试的抽象测试类。所有测试都调用一些函数,其中的参数指示要测试的条件。该函数的定义留给扩展类。到目前为止,这是可行的。
接下来,我想标记任何曾经失败的测试并将其修复为"回归"测试,所以如果我这么倾向,我可以运行那些测试。
但测试最初是在抽象类中标记的。我需要在实现类中覆盖标记或添加标记。
这样做有干净的方法吗?文档暗示存在,但到目前为止,我无法找到如何执行此操作的示例。
答案 0 :(得分:0)
我从来没有找到关于如何做到这一点的文档,但ScalaDocs中有足够的信息让我能够弄明白。为了那些可能想要做这样的事情的人的利益,这是你需要知道的:
首先,您需要定义自己的特征,并将其混合以获得此额外行为。它将覆盖tag()的定义,如下所示:
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 方式执行此操作的评论。