dave08
09/29/2022, 11:33 AMJhonatan Sabadi
09/29/2022, 11:58 AMdave08
09/29/2022, 12:01 PMdave08
09/29/2022, 12:02 PMJhonatan Sabadi
09/29/2022, 12:06 PMJhonatan Sabadi
09/29/2022, 12:06 PMdave08
09/29/2022, 12:08 PMJhonatan Sabadi
09/29/2022, 12:14 PMczuckie
09/29/2022, 12:43 PMcreateAndroidComposeRule
, where you specify the activity you want to test whilst being able to use the rule to evaluate assertions on nodes.
You use createComposeRule
to have the framework spin up an Activity for you to setContent on, which is good for doing things like 'given a compose in this state' type tests.
And finally you have createEmptyComposeRule
which can be used in tests that involve using a mix of both compose and XML views (maybe you have a new compose screen in your pre-existing XML view app).
For the createAndroidComposeRule
you won't be calling setContent
because the activity you specify will be doing that, so you'll have the same challenges you would have had before compose for injecting your dependencies.
For the createComposeRule
you've got a lot more fine grain control since you get to call setContent
so often you will just provide a UI state object to your composable you're testing (if you follow the pattern google advocates(?) with a composable that takes a view model and a composable that takes a UI state object).
I think pure compose apps wouldn't use the createEmptyComposeRule
but I could be wrong.
If you use test robots, you'll find yourself passing in a compose test rule of some description to be able to do the node resolution and assertion (whilst before you may have use onView()).
Beyond that, you might find that you can't target a particular node you're interesting in, in which case you'll end up having to use modifier.testTag(...)
as a way to be able to locate the element in your test by the tag instead.czuckie
09/29/2022, 12:43 PMdave08
09/29/2022, 12:49 PMcreateEmptyComposeRule
?dave08
09/29/2022, 12:50 PMcreateComposeRule
type tests...?czuckie
09/29/2022, 12:53 PMActivityScenario<ActivityA>
to spin it up as well as a createEmptyComposeRule
, but I might have a test that used createComposeRule
that I'd use to test the ComposeView on it's owndave08
09/29/2022, 12:56 PMdave08
09/29/2022, 12:57 PMczuckie
09/29/2022, 1:15 PMsetContent
on the rule created with createComposeRule
as that rule handles creating some kind of activity to host a ComposeView on your behalfJuliane Lehmann
09/29/2022, 1:28 PMActivityScenario
and Espresso view matchers as before. But you'll run into problems when trying to match Composables with espresso view matchers - they don't. So for that, also add an EmptyComposeRule
as a @Rule
to the test - it just needs to be there, so its registry setup will run. Now you can use the composeRule to do view matching and assertions on the composables.Juliane Lehmann
09/29/2022, 1:29 PMdave08
09/29/2022, 1:30 PMdave08
09/29/2022, 1:31 PMJuliane Lehmann
09/29/2022, 1:40 PMComponentActivity
, not any specific activity of the app. If I understand correctly, this is to workaround some issues with the test lifecycle that you get forced into because ComposeRules are Rules and must be used as Rules. (I.e., observe how there's both ActivityTestRule
and ActivityScenario
- the former taking away some boilerplate for a common case and a lot of flexibility to handle other cases. There's no compose equivalent to ActivityScenario
.)Juliane Lehmann
09/29/2022, 1:40 PMdave08
09/29/2022, 1:45 PMdave08
09/29/2022, 1:46 PMdave08
09/29/2022, 1:47 PMdave08
09/29/2022, 1:48 PMJuliane Lehmann
09/29/2022, 1:53 PMcomposeTestRule.onNodeWithText(...)
- if those don't work, the ultimate escape hatch/id-matching equivalent can be found in Modifier.semantics
czuckie
09/29/2022, 2:05 PMczuckie
09/29/2022, 2:06 PMdave08
09/29/2022, 2:06 PMczuckie
09/29/2022, 2:07 PMfun Modifier.definitelyNotATestTag(tag: String) = this.testTag(tag)
eases the pain /sAlex Vanyo
09/29/2022, 5:56 PMdave08
09/29/2022, 7:34 PM