Kotlin Multiplatform testing commonTest @Composable UI

597 Views Asked by At

I'm attempting a Kotlin Compose Multiplatform project and want to write a unit test for a piece of @Composable UI in my commonMain project. From the references I've found online, I should be able to do the following:


@get:Rule
val compose = createComposeRule()

But I haven't been able to find the right dependency to have createComposeRule show up as a valid function.

My current build.gradle.kts has this (just displaying applicable points):

plugins {
   kotlin("multiplatform") version "1.7.10"
   id("org.jetbrains.compose") version "1.3.0"
}

kotlin {
   sourceSets {
      val commonTest by getting {
         dependencies {
            implementation(kotlin("test"))
            implementation(kotlin("test-junit"))
            implementation(kotlin("test-common"))
            implementation(kotlin("test-annotations-common"))
            implementation(compose("org.jetbrains.compose.ui:ui-test-junit4"))
         }
      }
   }
}

Is there an available dependency or version I'm missing to make createComposeRule available, or should I be using a different type of UI test for this source set?

3

There are 3 best solutions below

0
Jesser On BEST ANSWER

I upgraded my IntelliJ from a 2021 version to 2023.2.2 yesterday. This actually fixed 2 issues I was having:

  1. The above issue. I can now import and use createComposeRule() method in the commonTest source set and it runs successfully.
  2. I was having an error syntax highlight showing up on the runTest method. The IDE was being troublesome and insisting that there was some missing dependency, and the file would appear to have an error. But Gradle would execute the test task successfully. After upgrading IntelliJ, the error syntax highlighting went away.
2
Nikolai Rykunov On

Try to include compose junit4 dependency this way in Gradle

implementation(compose.uiTestJUnit4)
0
BoydyBoydy On

It is a bit difficult to get this to work, but I have actually found something that might work for you, as it works for me... (I am/was having the same problem)

I wish that there was a JUnit option to be added when creating, but there isn't.

Instructions:

  1. Create a new IntelliJ Project
  2. Let the Gradle Build compile
  3. Go to Common > commonMain > App.kt
  4. right click on App class - as App()
  5. Generate > Test
  6. Select Junit4
  7. Fix
  8. Wait for Gradle
  9. Click OK
  10. Untick Show only...
  11. Click on common > DesktopTest
  12. Update to look more like a proper class and add get rule
    @get:Rule
    val compose = createComposeRule()
  1. Add Small Test
    @Test
    fun test_this_works(){

        val testNumber = 1

        assertEquals(testNumber, testNumber)

    }
  1. Go to build.gradle.kts in common - ensure that it is 'common' build.gradle, not any others

    Add implementation in DesktopTest sourceset:

    Add Option, above desktopTest @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)

        @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
        val desktopTest by getting {
            dependencies {
                implementation(compose.uiTestJUnit4)
                implementation(compose.desktop.currentOs)
            }
        }
  1. Refresh Gradle
  2. Go back to appkttest
  3. import in the createComposeRule
  4. Add in a compose test
    @Test
    fun test_create_button_with_text(){

        val testString = "Simple Button"
        val testTag = "Button"

        compose.setContent {

            Button(onClick = {

            },
            modifier = Modifier.testTag(testTag)) {
                Text(text = testString)
            }

        }

        compose.onNodeWithTag(testTag).assertTextEquals(testString)
        compose.onNodeWithText(testString).assertTextEquals(testString)

    }
  1. Update all imports for Kotlin Compose
  2. Run All Tests in the class
  3. It should work properly

Not sure if this is the right way to do this, but it is working for me at the moment

I haven't further tested that it works for everything, it is difficult to find good tutorials for desktop stuff

Other Sources:

  1. Setting up JUnit with IntelliJ IDEA

  2. How to search in Android Kotlin Compose UI test for a specific view? (ProgressBarRangeInfo/CircularProgressIndicator)

    • It is suggested this is created by AI, but it does help out with figuring out how to test different components. I'm sure there is a better way but that can be figured out now that there is a way to test Compose.

Why does it work?:

I believe that the test generation will generate the test and if you pick and fix the Junit4 then you should be able to load the correct dependency into the gradle build script. I have also added in the implementations needed, based on compose variables.

Hopefully these instructions are actually able to be used, as I have only tested for myself. Happy to help out if possible.