Hi, I have a challenge about generating a code ins...
# ksp
c
Hi, I have a challenge about generating a code inside generated test source sets. I have an android module and ksp module, which finds the annotation in the
main
source and generates some kind of runnable unit test code. The problem is, it generates the code inside the generated main source set instead of test one which makes sense because the ksp module is added as
ksp
dependency and the annotation is in
main
source set. I have a trick for it. I can create generated files wherever I want using basic
File
class rather than
CodeGenerator
in my processor but it is not the right way because ksp doesn't aware my files. If I clean and build the project, it won't generate them since ksp doesn't have any knowledge about my files. So I need a way to generate these files into the generated
test
source set. If anyone can share their experiences, I would very much appreciate it. Thank you.
g
Hi! As you said, using CodeGenerator will handle a proper build and build cache mechanisms, creating your own files may randomly fail , and KSP doesn't offer such mechanism now (afaik). If I was you, I'd go with either: • no-annotation approach, KSP runs on the test, scan all classes (from main) and generate the code. It's not optimal for performances. • an annotation in test code that targets all classes where I want to generate a test (something like
@GenerateTestFor([MyClass1::class, MyClass2::class])
), which is better for performances (avoid scanning all classes) but may be tedious to maintain (that's why the 1st option may be handy) • As you said "main" in your message, I guess that's JVM only, so it's likely you can do something with a bit of reflection, without even needing to generate code. The usage of reflection being in the test folder, you'll be able to scan and execute. The choice depends on your constraints (numbers of classes to cover, if this list of classes should be manually maintained or automatically, if reflection is good enough or not for the tests you want to write, etc.)
c
Hey, thank you for your answers. I did figure out the problem. My aim was generate screenshot test from compose preview functions and run them without need write any test class. Because writing a test class for screenshot test bit more useless for my project, I just need output(
png
). Since ksp couldn't handle the custom files which is not generated by
CodeGenerator
(this is 100% makes sense), I deal with it like that. • My ksp generates the classes under
main
source set but their classpath start from
screenshot/kotlin
.
Copy code
.
├── debug
│   └── kotlin
│       └── screenshot
│           └── kotlin
│               └── com
│                   └── screenshot
│                       └── generated
│                           └── Screen_Test_1733530405871.kt
• I attach the new source set(
screenshot/kotlin
) to
testDebug
in
build.gradle.kts
also.
Copy code
getByName("testDebug").apply {
    kotlin.srcDir("${layout.buildDirectory.get()}/generated/ksp/debug/kotlin/screenshot/kotlin")
}
• Luckily there is no issue for it and if I run the test command it generates class by using
CodeGenerator
and run the tests. There is no performance issue since I have a gradle plugin which hides these implementations behind the some specific command and parameters.