So given some test code like: ```internal class M...
# compiler
z
So given some test code like:
Copy code
internal class MyTest {
    @Jira("abc-1") @Test fun testFunction1() { .. }
    @Jira("abc-2") @Test fun testFunction2() { .. }
}
I need to generate a
.yaml
file, that identifies all the JIRA IDs, and associates each one with the test class name and method, like so:
Copy code
- jira_id: abc-1
   test_cases:
   -MyTest/testFunction1
- jira_id: abc-2
   test_cases:
   -MyTest/testFunction2
What tooling should I use to read the test annotations? A Kotlin compiler plugin? KSP? Note: I’m not generating any Kotlin code from this, so I technically don’t need to block normal compilation in any way for this use case
c
In a JVM environment with Junit I‘d implement a test runner https://github.com/junit-team/junit4/wiki/Test-runners In the mockito runner you can see how to interact with annotations.
z
I should note that I’m using Gradle for this, and the goal would be to make the necessary information available as input to a gradle task
c
Which input ?
z
all the JIRA IDs, and associates each one with the test class name and method
I need the class/function information for all functions annotated with
@Jira
, then the values inside that annotation. and from that, I can generate the
.yaml
file
c
The test task can generate in cooperation with the test runner the yaml file that the other task can consume it.
z
ah one caveat though is that it would be either a JVM and/or an android environment (
src/test
and
src/androidTest
)
c
still the same runner, both run with junit 🙂
z
is this a separate task than the existing gradle tasks for testing? ex: `test`/`testDebugUnitTest`/`connectedDebugAndroidTest`? how does one go about hooking up a new test task to gradle to use that runner? I would assume it doesn’t actually execute the tasks, just pulls in all the test function and annotation data?
c
the test tasks do not know about the runner. but you know that your tests use the runner and output the yaml file to a directory (like i.e the reports a junit test creates in the
build/reports
folder). your new task then just adds a dependency (
dependsOn
in gradle language) on
test
,
testDebugUnitTest
, etc., so when you run your task the test tasks are executed, and consumes the file.
z
test
,
testDebugUnitTest
don’t these test tasks already have a runner though? I don’t want to mess with them, and don’t want to actually execute tests to achieve my goal
👍 1
c
hm, the unit tests don’t. for the android integration tests you might need to extend the
AndroidJUnit4
If you don’t need any information if the tests are actually run or successful, I’d go with a KSP, create a gradle plugin that registers a processor over the test files, and creates a task you can execute from gradle to create the yaml.
👍 1
e
I had code for a similar purpose that just uses reflection to find all classes and annotated methods. create another JavaExec task from the same SourceSet, easy for the JVM target, a little annoying for the Android target, but doable
e.g. for the JVM target in a multiplatform project,
Copy code
kotlin {
    jvm {
        compilations.getByName("test") {
            tasks.register<JavaExec>("listTestCases") {
                classpath(runtimeDependencyFiles, output)
                mainClass = "com.example.test.ListTestCases"
and then write
src/jvmTest/kotlin/com/example/test/ListTestCases.kt
like any normal
main()
entry point
👍 1
z
Do you have an example for the Android source set? I think a KSP based solution may be easier given I need this to work on the
src/androidTest
code as well. But
JavaExec
does sound nice in that it's guaranteed not to mess with any normal compilation
e
I used to but I deleted it since we didn't need it anymore :p
if you're comfortable with bytecode you could just write a JavaExec which isn't in the same SourceSet, but takes the compiled test classes as input, and parses them as class files instead of using reflection on classes in the classpath. that's how Gradle's test runner discovers test classes by default
otherwise you need to mess around with attributes and stuff to get an android-like classpath in a host jvm environment
z
Yeah that sounds basically like robolectric lol