android-jetpack-composeandroid-espressoandroid-jetpackandroid-jetpack-compose-testing

How to create a Page/Screen Object Model in Jetpack Compose Testing


For basic testing, if I create a test class like below, it works fine.

class MyComposeTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule<MainActivity>()

    @Test
    fun myTest() {

        composeTestRule.onNodeWithText("Login").performClick()

        composeTestRule.onNodeWithText("Home").assertIsDisplayed()
    }
}

But what if i want to abstract some of these into separate classes for an end-to-end test?

e.g. I want to create a login page class with all locators for Login and similarly for Home page and simplify my test as

@Test
fun myTest() {
   val login = LoginPage() 
   val home = HomePage()

   login.loginBtn.performClick() 
   home.homeTxt.assertIsDisplayed()
}

I am not sure how my page classes (with locators) should look like to make this possible.


Solution

  • You should pass the composeTestRule in the page's constructor. The code would look like this:

    class BaseTestSuite {
        @get:Rule
        val composeTestRule = createAndroidComposeRule<MainActivity>()
    }
    
    class LoginPage(composeTestRule: ComposeContentTestRule) {
        val loginBtn = onNodeWithText("Login")
    
        fun tapLoginButton() {
            loginBtn.performClick() 
        }
    }
    
    class MyTestSuite() : BaseTestSuite {
        val loginPage = LoginPage(composeTestRule) 
    
        @Test
        fun myTest() {
            loginPage.tapLoginButton()
        
            // rest of the code
        
        }
    }