kotlinx-kover
kotlinx-kover copied to clipboard
Ability to create custom report variant for specific dependency project
What is your use-case and why do you need this feature?
I would like to speed up my build by aggregating some tests into a single module. At the same time, I would like to retain the ability to check coverage of each module independently.
Imagine a project with 3 subprojects: :app, :core, and :lib. Let's say that the way things are now is that each subproject adds the kover plugin, and has its own tests. However, the overhead of running starting 3 separate test processes is too much. So, I want to only have one test test in :app, which will also test :core and :lib (3 projects is not significant overhead, but in real life there could be hundreds of subprojects).
I am looking at the newest API for creating custom variants in 8.0.0-Beta. I see in KoverVariantCreateConfig that I can create a new variant, however it doesn't seem that a variant can define its own dependencies. So here is the issue. Let's say :app adds kover depedencies on :core: and :lib. My understanding is that by default, all 3 modules code will be combined for the coverage verification rules. This means that you might be able to pass a rule even though you didn't cover a single line in :lib, because you covered enough lines in :core.
I was hoping custom variants solve this problem, but I cannot figure out how to do what I am imagining. I would like a custom variant in :app in which verification rules are only looking at a single kover dependency project, like :core.
Describe the solution you'd like
Possibly the closest thing I am finding looking at the API is KoverVariantSources.excludedSourceSets. If only there was something like KoverVariantSources.includedKoverDependencies: Set<String> in which each string was the path of a module. If empty, it could default to including all kover dependencies as well as the current project. but if we were to write includedKoverDependencies.append(':core') then that variant would analyze its rules only using the code fom :core, not even from the current project.
Hi, could you clarify your use case?
Suppose you have :core and :lib projects, would you like to create a variant in which tests from both projects were run, but only classes from :lib were included in the report?
Hey, sure I will clarify.
Let's say I just have :core and :lib.
I want to only have on test source set in :core. :lib will be on the classpath for the tests in :core, so I can add tests for :lib here as well.
For kover, lets say I want these two rules:
- cover at least 50% of the lines in
:core - cover at least 50% of the lines in
:lib
If each module has its own test source set, this is easy. This is how my real life project works now.
When I move the tests from :lib to :core, I need to make sure that these verifications work in the same way. If I do no special configuration and just add :lib as a kover dependency for :core, then only :core will run koverVerify. And when :core runs koverVerify, it will not discriminate between code in :core and :lib. It will still check for the 50% threshold, but it won't care where the lines are. They might all be in one module or the other. And this is not the behavior that I want. Rather, I want to still verify that 50% of lines are covered for each indivual module, even though their tests are combined.
All of what I said above is my understanding on how it works, but I did not fully test this. It is somewhat of an assumption based on how I understood the documentation, so please let me know if I am misunderstanding.
Please correct me if I made a mistake somewhere:
:libhave own sources and [optionally] tests on classes from:lib:corehave own sources and tests on classes from both:coreand:lib
You want to verify coverage only for :lib subproject, but to do this, the tests from :core and :lib must be run
Almost.
In my example, :lib has no test source set. All tests for :lib classes are contained in the :core test source set. The :core test source set also contains tests for :core classes.
When I execute :core:allTests, I am testing both :core and :lib.
When I execute :core:koverVerify I am verifing that the test source set of :core covered code from both :lib and :core.
The main issue is that I need verification rules to apply to each module separately. When Kover calculates whether or not 50% of the lines of ccode in :lib have been covered by :core tests, this calculation will need to completely ignore coverage of :core code.
At the same time, :core should have a separate verification rule that 50% of the lines of code in the :core main source set have been covered.
It looks like project filters can be added:
kover {
reports {
variant("onlyForLib") {
filters {
includes {
projects.add(":lib")
}
}
verify {
rule {
// lib should be covered by 50%
minBound(50)
}
}
}
variant("onlyForCore") {
filters {
includes {
projects.add(":core")
}
}
verify {
rule {
// core should be covered by 60%
minBound(60)
}
}
}
}
}
good idea. I think it would work!
Implemented in 0.8.0