testfiles fails to be auto-registered in newer Kotest versions
Opened this issue · 0 comments
testfiles extension doesn't seem to be auto-registered in newer Kotest versions.
Background
My setup (I think) is quite simple:
build.gradle.kts
:
dependencies {
testImplementation("io.kotest:kotest-runner-junit5::5.6.2")
testImplementation("de.joshuagleitze:kotest-files:2.0.0")
}
how I'm using it in an example test:
class Test : FreeSpec({
"Some" - {
"nested" - {
"test" {
val directory = testFiles.createDirectory()
}
}
}
})
However, this failed for me on any subsequent build:
java.nio.file.FileAlreadyExistsException: /home/andrzej/work/xyz/build/test-outputs/test-176899501
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:94)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:397)
at java.base/java.nio.file.Files.createDirectory(Files.java:700)
at de.joshuagleitze.testfiles.DefaultTestFiles.createDirectory(DefaultTestFiles.kt:31)
Note that the directory is created under root test-outputs
and not under test scope like described in README.
The issue
I attempted to debug this and found that Kotest initializes @AutoScan
extensions in io.kotest:kotest-framework-engine-jvm
, io.kotest.engine.config.applyConfigFromAutoScan.kt:16
. However, to my surprise the scanning code doesn't discover testfiles' de.joshuagleitze.testfiles.kotest.KotestTestFilesAdapter
object which I believe to be the testfiles' extension for Kotest. Because of that it doesn't register it as a Kotest extension, making testfiles run with ROOT_SCOPE
context.
I don't have any environment variables set, Java properties set or Kotest-project-wide configuration that would be related to Kotest configuration.
Suspected reason
I think the reason are annotations:
-
Kotest during extension scanning uses ClassGraph which uses classfile bytecode for understanding which classes are matches for a given query. It uses the following query:
classgraph().scan().use { result -> result.getClassesWithAnnotation(AutoScan::class.java.name) ... }
The
AutoScan
here isio.kotest.core.annotation.AutoScan
-
testfiles'
KotestTestFilesAdapter
is annotated withio.kotest.core.spec.AutoScan
(note the different package), which in newer Kotest versions is a type alias:typealias AutoScan = io.kotest.core.annotation.AutoScan
I think the scanner, due to the different annotation package, doesn't consider testfiles'
KotestTestFilesAdapter
as a match.
A different problem
I though: hey, doesn't matter. I can use Kotest's project-wide configuration to manually register testfiles as its extension.
This doesn't work however, as testfiles' KotestTestFilesAdapter
is internal
and therefore I cannot reference it from my code.
Possible solution
- Migrate to updated Kotest annotation.
- Possibly make
KotestTestFilesAdapter
public so users can have fine-grained control over registration if they want to.