https://kotlinlang.org logo
Title
c

Colton Idle

11/22/2021, 8:29 PM
Testing! I finished my first compose app and now I want to write a few end-to-end tests to test critical paths. App launch. App sign up. App log in. View all movies. Click and view a single movie. That sort of thing. How do I do that in a pure-compose app? Do I still just use espresso to string together clicks? The compose testing docs seem to be more about testing specific composables.
c

curioustechizen

11/22/2021, 8:52 PM
I'm also looking into UIAutomator for functional testing of an app that also uses Compose. One of the things that I've not looked into yet is how to perform things like text input into a Compose TextField from UIAutomator.
c

Colton Idle

11/22/2021, 9:22 PM
Yeah, curious to hear from Jose here. When I get back to my desk tomorrow I'm going to just wing it and try to get a few espresso E2E workflows going, I'm just not sure if that's "the way" to do it.
z

Zach Klippenstein (he/him) [MOD]

11/22/2021, 11:54 PM
Espresso is gonna be very painful to use for this directly, but you can use it together with the compose testing library (just use
createAndroidComposeRule
instead of
createComposeTestRule
)
a

Alex Vanyo

11/23/2021, 12:11 AM
If you’re in a completely pure-Compose app, you will probably find you don’t need Espresso at all. You can interop Espresso with the compose testing library as Zach mentioned, but if you only have Compose elements I don’t think Espresso will be super useful. Testing specific composables ends up being the easiest and simplest to do (because you can isolate the components and state under test), but you can absolutely use the same set of APIs for larger end-to-end tests. If you put your root composable under test, you can make assertions, perform actions, etc. JetNews has some very basic end-to-end tests that trigger navigation and check for content on different screens here: https://github.com/android/compose-samples/blob/main/JetNews/app/src/sharedTest/java/com/example/jetnews/JetnewsTests.kt
c

Colton Idle

11/25/2021, 1:33 AM
Update for anyone following along. The link that Alex Vanyo posted above was super helpful. So far though I hit this issue "java.lang.IllegalStateException: Given component holder class androidx.activity.ComponentActivity does not implement interface dagger.hilt.internal.GeneratedComponent or interface dagger.hilt.internal.GeneratedComponentManager"
Okay, used
createAndroidComposeRule
instead of createComposeRule and it launched! YAY
🎉 2
For some reason... my test (just running a single test, so it shouldn't have to do with any parrallel test weirdness) my test is
composeTestRule.onNodeWithText("Featured", true).assertExists()
and it succeeds on one emulator, and fails on the other. both emulators are api level 31. Hm. Anyone got any ideas on how to start debugging?
okay. so don't laugh, but this is my first time really writing a test lol. I've read a lot about it, but projects ive worked on never had it as a priority... I just added a thread.sleep() and now it works... So what's the catch here? Should I try to have some sort of espresso idling resource sort of thing going on?
Added this for now... lets see how flakey this ends up being
@Test
  fun app_opensFirstScreen() {
    runBlocking {
      delay(250)
      composeTestRule.onNodeWithText("Featured", true).assertExists()
    }
  }
m

Mark Murphy

11/28/2021, 1:28 PM
That's likely to wind up being fairly flaky. The Compose testing docs have a section on synchronization that might help.
c

Colton Idle

11/28/2021, 5:51 PM
oh. thanks mark. I missed that section the first go around ill take another look