Is it expected that new `androidInstrumentedTest` ...
# multiplatform
b
Is it expected that new
androidInstrumentedTest
sourceSet doesn't inherit dependencies from
androidUnitTest
nor sources from
commonTest
?
j
A change in the new source set layout is that
androidInstrumentedTest
no longer inherits from
commonTest
. I'm not sure about the dependency sharing. Did that used to be the case in the old source set layout?
s
Yes! InstrumentedTests need to dependOn commonTest explicitly if want that behavior!
The new default will be, that only unitTest source sets will dependOn commonTest
j
In my case, I need
androidInstrumentedTest
to inherit from
commonTest
, but not
androidUnitTest
, as the common tests require running on a device for the Android platform. So I still employ this workaround to sever the dependency for
androidUnitTest
.
s
Please do not remove a dependsOn edge by casting something to mutableSet. This is entirely unexpected and can lead to many issues in tooling.
j
Is there some other way to accomplish removing this
androidUnitTest
dependency on
commonTest
? I haven't run into any issues with this workaround. Without it, the tests attempt to run as Android unit tests and fail.
s
No, dependOn edges cannot be removed. The fact that you do not experience any issues is quite surprising, but can change with any kotlin release. In your case I would not use commonTest, but create a custom shared test source set. I am also open for discussing the default dependsOn edge from Android unit tests to commonTest.
j
I think it would certainly make sense to allow control over which of the two Android test types were the desired edge for common tests. Maybe a gradle property option to choose between the two. Generally a test suite can either be compatible with running on pure JVM or mocked by Robolectric (
androidUnitTest
) or has Android-specific dependencies that require
androidInstrumentedTest
. In my case, it's the latter. The majority of code is shared between the JVM and Android source sets, but the underlying Android library requires a valid Android
Context
and loads a native JNI library which only works on a physical Android device. I think it's good that
androidInstrumentedTest
no longer depends on
commonTest
by default, as it's unlikely someone would want both
androidUnitTest
and
androidInstrumentedTest
to depend on
commonTest
. But it should be equally possible to choose
androidInstrumentedTest
as the edge that does depend on
commonTest
and not
androidUnitTest
. Will it be possible to configure the source set dependency graph this way with the new source set DSL in 1.8.20?
@Sebastian Sellmair [JB] FYI, turns out this hack to remove
androidUnitTest
as a
commonTest
edge no longer works as of Kotlin 1.8. It worked up to 1.7.21. I'm looking forward to a solution for how to properly remove the edge or switch it to use
androidInstrumentedTest
. Please let me know if I can assist in any way.
s
This is not surprising to me, as I mentioned: This set was used to incrementally update data in the KGP. So, indeed you could help, but its okay if the time investment is too hight: This could a a contribution from your side in 1.9. If you’re interested, please send me a written proposal of the desired behaviour changes. If the proposal gets accepted by me and my @stanislav.erokhin, then I can help you with the contribution. The code is OK to get into.
j
Ok, I'd be happy to write up a formal proposal. I'm assuming we'd want a solution for both the current preset API and the new source set DSL API. Where can I see the latest documentation for the DSL API so I can become more familiar with it? Right now I'm thinking along the lines of something like this for the existing API:
Copy code
kotlin {
    android {
        commonTestEdge = INSTRUMENTED // UNIT, INSTRUMENTED, or BOTH (default UNIT)
    }
}

// or

kotlin {
    android(commonTestEdge = INSTRUMENTED)
}
This would allow the user to configure either of the Android test edges to depend on common, or both, as it seems there are some users that use the
commonTest
source set for common test fixtures, but not necessarily tests that cannot run as either unit or instrumented. This API change should not affect existing code, which would continue with the default behavior of
BOTH
pre-1.8 and
UNIT
post-1.8.
Based on this, the new DSL might similarly include the argument:
Copy code
targetHierarchy.default {
    common {
        withAndroid(commonTestEdge = INSTRUMENTED)
    }
}
a
Does that mean that you could define separate
jvmUnitTest
and
jvmInstrumentedTest
instead of
jvmTest
(if you wanted to)?
s
Sorry this was not clear enough, but this is only about android. But yes you could do something like what you described already in 1.8.20
j
I tested this with 1.9.0-Beta-47 and it works great! No more build errors from
androidUnitTest
being connected to
commonTest
.
Copy code
targetHierarchy.android {
    instrumentedTest.sourceSetTree.set(SourceSetTree.test)
    unitTest.sourceSetTree.set(SourceSetTree.unitTest)
}
149 Views