我自己添加了功能。 (内置支持问题:https://github.com/etorreborre/specs2/issues/470)
src/test/java/test/Tag.scala
首先定义一个要使用的注解。 (我相信这只能在 Java 中完成。)
package test;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Tag {
String name();
}
src/test/scala/test/TaggingFramework.scala
然后定义一个sbt.testing.Framework 的实现,它包装了Framework 并为注释添加标签。 (注意:这取决于org.scala-sbt:test-interface。如果您已经在提取specs2,它应该已经存在。)
package test
import java.lang.annotation.Annotation
import sbt.testing._
import scala.util.Try
class TaggingFramework(framework: Framework) extends Framework {
def fingerprints(): Array[Fingerprint] = framework.fingerprints()
def name = s"TaggingFramework(${framework.name})"
def runner(args: Array[String], remoteArgs: Array[String], testClassLoader: ClassLoader) = {
val runner = framework.runner(args, remoteArgs, testClassLoader)
println(runner)
new Runner {
def args() = runner.args()
def done() = runner.done()
def remoteArgs = runner.remoteArgs()
def tasks(taskDefs: Array[TaskDef]) = runner.tasks(taskDefs).map { task =>
new Task {
def execute(eventHandler: EventHandler, loggers: Array[Logger]) = task.execute(eventHandler, loggers)
def taskDef = task.taskDef
def tags = task.tags ++ {
val fingerprint = taskDef.fingerprint
Try {
val isModule = fingerprint.getClass.getMethod("isModule").invoke(fingerprint).asInstanceOf[Boolean]
val className = taskDef.fullyQualifiedName + (if (isModule) "$" else "")
println(testClassLoader.loadClass(className).getAnnotationsByType(classOf[Tag]).map(_.name).toSeq)
testClassLoader.loadClass(className).getAnnotationsByType(classOf[Tag]).map(_.name)
}.getOrElse(Array.empty)
}
}
}
}
}
}
project/TaggingTestFramework.scala
然后在构建定义中,定义sbt.TestFramework 的TaggingTestFramework 子类。这将加载TaggingFramework(如果存在)。否则,它只是使用原始框架。
import sbt.TestFramework
import sbt.testing._
import scala.language.existentials
import scala.util.Try
class TaggingTestFramework(testFramework: TestFramework) extends TestFramework() {
override def create(loader: ClassLoader, log: sbt.Logger) = testFramework.create(loader, log).map { framework =>
Try(
Class.forName("test.TaggingFramework", true, loader).asInstanceOf[Class[Framework]]
.getConstructor(classOf[Framework]).newInstance(framework)
).getOrElse(framework)
}
override def toString = s"TaggingTestFramework($testFramework)"
}
build.sbt
并包装testFrameworks。
testFrameworks := testFrameworks.value.map(new TaggingTestFramework(_))
这应该主要适用于任何 Scala 或 Java 框架,包括 specs2。
src/test/scala/example/MySpec.scala
最后,要使用为测试任务添加标签,只需将注释添加到类。
import org.specs2.mutable.Specification
import test.Tag
@Tag(name = "database")
class MySpec extends Specification ...
注意 1:这目前不适用于继承。
注意 2:SBT 分叉测试的工作方式非常不同。此功能和许多其他测试功能不适用于分叉测试。