https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
e

egorand

05/04/2020, 5:38 PM
I'm trying to find a sane solution for the following problem: I've got an
expect class
with a common test suite and implementations for Android and iOS. Sadly, the Android implementation uses Android SDK types which are mocked out when running the tests on the local JVM, so I need to slap a
@RunWith(RobolectricTestRunner::class)
on the test class declaration to make it work. Unfortunately, the common code doesn't know anything about test runners, so having this annotation directly on the test class in the common module would require a lot of complicated expect-actualing. I found the following example: https://github.com/Kotlin/mpp-example/blob/master/greeting/src/androidLibTest/kotlin/CalculatorTestJavaHelper.kt, the idea is to make the common test
open
and extend it in
androidTest
, which allows attaching the
@RunWith
annotation. The problem is that the example is actually trying to address a different issue (namely, being able to execute that test from the IDE) and doesn't prevent the common test from running and failing on Android. I figured out a way to
@Ignore
the common test on Android only, but that's a pretty ugly hack. I wonder if there's a more straightforward solution.
r

russhwolf

05/04/2020, 5:48 PM
I've handled Robolectric in a couple different ways. You can do `expect`/`actual` on the annotations, but it's a pain because you can's use
@OptionalExpectation
since you need to pass a parameter to the
@RunWith()
annotation. You can leave your test class open, but you lose out on IDE integration since the implementation doesn't have the test declarations so there's no gutter icon to click on. Or you can do an `expect`/`actual` base class, where the Android
actual
has the annotations and the other platforms no-op.
e

egorand

05/04/2020, 6:02 PM
`expect`/`actual`-ing the annotations indeed turned out to be a pain and I didn't get to the end of it. No having an option to run the tests from the IDE is not a huge no-no for me, so that feels like the least painful approach. `expect`/`actual` of the test class is undesirable, since the actual tests are in the common code and I don't wanna duplicate them. Actually not 100% sure I got your idea right, do you have any code on Github that I can look at? And thanks for the tips!
r

russhwolf

05/04/2020, 6:09 PM
I don't mean expect/actual everything, but just a base class. common
Copy code
expect abstract class BaseTest
android
Copy code
@RunWith(...)
actual abstract class BaseTest
non-android
Copy code
actual abstract class BaseTest
Then your test that needs robolectric extends
BaseTest
in common
k

Kris Wong

05/04/2020, 6:26 PM
For Android tests you can set the runner in the build file
r

russhwolf

05/04/2020, 6:38 PM
Does that work for non-instrumented tests?
k

Kris Wong

05/04/2020, 6:39 PM
no
12 Views