Is it possible to achieve `@BeforeClass` behavior ...
# multiplatform
j
Is it possible to achieve
@BeforeClass
behavior in Android/iOS common tests? kotlin.test has the annotation for Kotlin/Native, as does Junit for JVM. My naive attempt to typealias the two doesn't work on the JVM side.
e
if you are writing a multiplatform test, just use
@kotlin.test.BeforeClass
. it already has
actual typealias
defined in the
kotlin-test-junit
and
kotlin-test-junit5
artifacts
j
That's what I would have thought, but there's no such annotation available to import in my common tests. Maybe I'm missing something.
e
you do have
Copy code
kotlin {
    sourceSets {
        commonTest {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-test")
or something equivalent in your
build.gradle
?
b
IDE sometimes does not suggest it. Try annotating by fully qualified path
j
Yeah, my dependencies are:
Copy code
kotlin {
  sourceSets {
    ...
    val commonTest by getting {
      dependencies {
        implementation(kotlin("test"))
      }
    }
    ...
    val androidTest by getting {
      dependencies {
        implementation(kotlin("test-junit"))
      }
    }
  }
}
e
it may be an IDE issue, then. try using
@kotlin.test.BeforeAll
or manually importing it as Martynas suggests
j
I've tried
@kotlin.test.BeforeClass
and I get the error:
Unresolved reference: BeforeClass
e
in Gradle or in the IDE?
j
Same with
@kotlin.test.BeforeAll
Both. The IDE shows the error. If I run the tests gradle outputs the same error.
e
you could try adding
Copy code
kotlin {
  sourceSets {
    val commonTest by getting {
      dependencies {
        implementation(kotlin("test"))
        implementation(kotlin("test-annotations-common"))
      }
    }
}
but that's odd, the same setup works in my projects. do you have a public project?
j
This is running the common tests on Android. If I run them on iOS, they run without error there.
e
(I don't even have an ios target)
j
I tried adding the "test-annotations-common" and still no luck, same error.
e
actually, just to check, you are aware of the difference between
androidTest
and
androidAndroidTest
right?
j
My project isn't public, yet.
e
because if you are running instrumented tests, you need to add the dependency to the latter (the equivalent of
androidTest
in a non-multiplatform android project), not just the former (the equivalent of
test
in a non-multiplatform android project)
j
I have been able to use the
@BeforeTest
annotation. You have
@BeforeClass
working the same though?
I've only had unit tests up to this point, but I will need to get instrumented tests for the ones I'm working on now, the ones that need this annotation. What's the difference in the dependencies with KMM build.gradle.kts?
These tests need a context and file I/O.
(Haven't gotten to implementing the expect/actual for the I/O yet.)
From what I've gathered, the
kotlin-test
dependency includes
kotlin-test-common
and
kotlin-test-annotations-common
. annotations-common contains only 4 annotations:
Tests
,
Ignore
,
BeforeTest
, and
AfterTest
. Their definitions are pretty close to what I was attempting to typealias `BeforeClass`:
Copy code
@Target(AnnotationTarget.FUNCTION)
public expect annotation class BeforeTest()
The
kotlin-test-junit
dependency defines the jvm actual:
Copy code
public typealias BeforeTest = org.junit.Before
Again, similar to what I was attempting for
BeforeClass
. There must be some reason that this typealias doesn't work for this annotation. Not sure why though.
👍 1
e
j
Interesting there hasn't been a response from JetBrains. Curious as to why this particular test annotation isn't as straightforward to typealias as those others.
Testing further, while my expect/actual typealias gives errors in the IDE:
Copy code
Expected annotation class 'BeforeClass' has no actual declaration in module ...androidTest (test) for JVM
Copy code
Actual typealias 'BeforeClass' has no corresponding expected declaration
The tests still compile and run, but my function annotated
@BeforeClass
does not get run at all.
If I make my own versions of
BeforeTest
and
AfterTest
, with the same typealiasing, I get the same IDE errors. But the tests run and the annotations work as expected. So the IDE errors don't seem to have anything to do with the issue. There just seems to be something specific about the Junit
BeforeClass
behavior that doesn't work from common tests.
Ah, actually I just got it working with my typealias definition. I was just missing the required
@JvmStatic
annotation! So really, the kotlin team should be able to add these annotations to the common annotations library.
e
now that I recall some more, I believe there isn't an equivalent across all the JS test frameworks that Kotlin/JS supports
but if they drop older versions I think it might be doable
j
Seems like should be able to add support at least to the platforms/frameworks that support it.
177 Views