Blog Infos
Author
Published
Topics
Author
Published
Topics

I have recently started adding UI tests for all the Composables in one of my side projects.

So I have the following composable, which uses rememberSaveable to survive configuration changes.

@Composable
fun UserNameComposable() {
    var name by rememberSaveable() {
        mutableStateOf("Nav Singh")
    }

    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = "User name is: $name",
            style = TextStyle(fontWeight = FontWeight.ExtraBold)
        )

        Spacer(modifier = Modifier.size(32.dp))

        OutlinedButton(onClick = { name = "Navjot Singh" }) {
            Text(text = "Change name")
        }
    }
}
Composable preview:

 

There are other tests I need to perform, but I want to ensure that this composable can survive changes such as activity recreation, etc.

My search for How to test state restoration in Compose led me to the following official documentation:

  • Fortunately, we have an inbuilt class that helps us to accomplish this 😇.
  • Its called StateRestorationTester
Now let’s take a look at how this class can test state restoration
  • Its basically 5️⃣ step process
  1. Create StateRestorationTester’s instance
val restorationTester = StateRestorationTester(composeTestRule)

2. Set the content on the instance that we have created in the 1st step

restorationTester.setContent{
    UserNameComposable()
}

3. Run any action that modifies the state

  • In our case, Whenever we click on the button it sets the name = “Navjot Singh”
// Change name is the text of Button
composeTestRule.onNodeWithText("Change name").performClick()

4. Trigger the restoration

  • We will call the method called emulateSavedInstanceStateRestore() on restorationTester instance.
restorationTester.emulateSavedInstanceStateRestore()

5. Final step, Verify the result

// Verify if Node still has the name that was set by the button's onClick
composeTestRule.onNodeWithText("User name is: Navjot Singh")
               .assertIsDisplayed()

 

Job Offers

Job Offers


    Android Software Engineer (f/m/d)

    Paradox Cat GmbH
    Munich
    • Full Time
    apply now

    Android Test Automation Engineer

    Komoot
    Remote
    • Full Time
    apply now

    Senior Android Software Engineer (f/m/d)

    Paradox Cat GmbH
    Munich
    • Full Time
    apply now

OUR VIDEO RECOMMENDATION

, , ,

Snapshot testing (and more!) with Paparazzi

Unit tests allow you refactor your code with confidence and usually run blazingly fast! But how do you ensure that your UI looks as expected? Espresso tests are hard to set up, prone to flakiness…
Watch Video

Snapshot testing (and more!) with Paparazzi

John Rodriguez
Android engineer
Android

Snapshot testing (and more!) with Paparazzi

John Rodriguez
Android engineer
Android

Snapshot testing (and more!) with Paparazzi

John Rodriguez
Android engineer
Android

Jobs

Here is the full sample code 🧑‍💻👩‍💻
// Composable

@Composable
fun UserNameComposable() {
    var name by rememberSaveable() {
        mutableStateOf("Nav Singh")
    }

    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = "User name is: $name",
            style = TextStyle(fontWeight = FontWeight.ExtraBold)
        )
        Spacer(modifier = Modifier.size(32.dp))
        OutlinedButton(onClick = { name = "Navjot Singh" }) {
            Text(text = "Change name")
        }
    }
}

// Restoration test

@RunWith(AndroidJUnit4::class)
class StateRestorationTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun onRecreation_stateIsRestored() {
        
        // 1.
        val restorationTester = StateRestorationTester(composeTestRule)
        
        // 2.
        restorationTester.setContent {
            UserNameComposable()
        }

        // OPTIONAL: Verify the initial state before restoration
        composeTestRule.onNodeWithText("User name is: Nav Singh")
                       .assertIsDisplayed()

        // 3. Run actions that modify the state
        composeTestRule.onNodeWithText("Change name")
                       .performClick()
        
        // 4. Trigger a recreation
        restorationTester.emulateSavedInstanceStateRestore()
        
        // 5. Verify that state has been correctly restored.
        composeTestRule.onNodeWithText("User name is: Navjot Singh")
                       .assertIsDisplayed()
    }
}

✅ Test Results

 

😊😊 👏👏👏👏 HAPPY CODING 👏👏👏👏 😊😊

This article was originally published on proandroiddev.com on December 22, 2022

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
Automation is a key point of Software Testing once it make possible to reproduce…
READ MORE
blog
Every good Android application should be well tested to minimize the risk of error…
READ MORE
blog

Running Instrumented Tests in a Gradle task

During the latest Google I/O, a lot of great new technologies were shown. The…
READ MORE
blog
Notifications are a very important part of Android apps, showing relevant information, informing when…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu