Si le but est de pouvoir accéder au nom du test depuis n'importe où, comme l'a suggéré @kajmanus dans les commentaires précédents, un ThreadLocal convient parfaitement.
Vous pourriez définir une classe de cas pour stocker les informations dont vous avez besoin pour le contexte de test actuel, par exemple,
case class TestContext(name: Option[String] = None)
object TestContext {
val currentTest: ThreadLocal[TestContext] =
ThreadLocal.withInitial(() => TestContext())
}
Définissez ensuite un trait que vos différentes spécifications étendront, par exemple,
trait BaseFunSpec
extends AnyFunSpec
...
{
override protected def withFixture(test: NoArgTest): Outcome = {
try {
TestContext.currentTest.set(TestContext(name = Some(test.name)))
super.withFixture(test)
} finally {
TestContext.currentTest.remove()
}
}
}
Enfin, vous pouvez accéder au contexte de test actuel que vous avez défini pour la discussion en cours (qui, dans cet exemple, est purement le nom du test) à partir de n'importe quel endroit de la discussion en cours,
def cachedResults(bytes: Array[Byte], fileType: String): Unit = {
TestContext.currentTest.get().name match {
case Some(testname) =>
import scala.util.Using
val file = new File("target", s"${testname}.${fileType}")
Using(new BufferedOutputStream(new FileOutputStream(file))) { os =>
os.write(bytes)
}
case None => throw new IllegalStateException("Unknown test context")
}
}
Cela fonctionnera que vous exécutiez des tests en parallèle ou non, à condition que vous ne traitiez pas les choses de manière asynchrone (c'est-à-dire dans un autre thread).
Une utilisation plus propre de cette méthode consiste à créer des acteurs ciblés, par exemple,
case class TestContext(name: Option[String] = None)
object TestContext {
val currentTest: ThreadLocal[TestContext] = ThreadLocal.withInitial(() => TestContext())
class TestNamer {
def currentName: String = currentTest.get().name match {
case Some(testname) => testname
case None => throw new IllegalStateException("No test context available")
}
}
class TestContextWriter(testNamer: TestNamer = new TestNamer()) {
def cachedBytes(bytes: Array[Byte], extension: String): Array[Byte] = {
import java.io.{BufferedOutputStream, File, FileOutputStream}
import scala.util.Using
val file = new File("target", s"${testNamer.currentName}.${extension}")
Using(new BufferedOutputStream(new FileOutputStream(file))) { outstream =>
outstream.write(bytes)
}
bytes
}
}
}
Et faire des injections si nécessaire :
trait BaseFunSpec {
val testContextWriter = new TestContextWriter()
def fetchRawResults(...): Array[Byte] = {
...
testContextWriter.cachedBytes(bytes, "pdf")
}
}