4

I'm trying to write some test cases for my compose functions. I have an outlined Text field with a maximum value of 16 characters. So I want to test this feature. Here is the test:

    @Test
    fun checkMaxTaxCodeLength_16Character() {
        val taxCode = composeRule.onNodeWithTag(testTag = AUTHENTICATION_SCREEN_TAX_CODE_EDIT_TEXT)
        for (i in 'A'..'Z')
            taxCode.performTextInput(i.toString())
        taxCode.assertTextEquals("ABCDEFGHIJKLMNOP")
    }

But although I can see the input is correct, the test fails, and it seems assertTextEquals doesn't work correctly. So:

  • first of all, what am I doing wrong?
  • Second, is there any way to, instead of checking the equality, check the text does not contain specific characters?

here is the code of text field:

                OutlinedTextField(
                    value = state.taxCode,
                    maxLines = 1,
                    onValueChange = { string ->
                        viewModel.onEvent(
                            AuthenticationEvent.TaxCodeChanged(string)
                        )
                    },
                    label = {
                        Text(text = stringResource(id = R.string.tax_code))
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .testTag(TestingConstant.AUTHENTICATION_SCREEN_TAX_CODE_EDIT_TEXT)
                )

The maximum length is handled in the view model. If the user adds more characters than 16, the view model won't update the state and keep the old value.

Mohammad Derakhshan
  • 1,262
  • 11
  • 33

2 Answers2

4

first of all, what am I doing wrong?

assertTextEquals() takes the value of Text and EditableText in your semantics node combines them and then does a check against the values you pass in. The order does not matter, just make sure to pass in the value of the Text as one of the arguments.

     val mNode = composeTestRule.onNodeWithText("Email")) 
     mNode.performTextInput("test@mail.com")
     mNode.assertTextEquals("Email", "test@mail.com")

Please note the text Email is the label for the textfield composable.

To get the semantic information about your nodes you can have

    @Test
    fun print_semantics_tree() {
        composeTestRule.onRoot(useUnmergedTree = true).printToLog(TAG)
    }

For the TAG you can use any string. After running the above test you can search the logcat with the specified TAG. You should see something like

    |-Node #3 at (l=155.0, t=105.0, r=925.0, b=259.0)px
                                                                                                        
    | Focused = 'false'
                                                                                                        
    | ImeAction = 'Default'
                                                                                                        
    | EditableText = 'test@mail.com'
                                                                                                        
    | TextSelectionRange = 'TextRange(0, 0)'
                                                                                                        
    | Text = '[Email]'
                                                                                                        
    | Actions = [RequestFocus, GetTextLayoutResult, SetText, SetSelection, 
                 OnClick, OnLongClick, PasteText]

Please note you can also obtain the semantics node object with an index operation rather than iterating through all the values.

   val value = fetchSemanticsNode().config[EditableText]

   assertEquals("test@mail.com", value.toString())
OtienoSamwel
  • 316
  • 2
  • 12
1

Ok, still, the problem is open, but I achieved what I wanted another way. I used semantic nodes to get what is in edit text and compared it with what it should be:

    @Test
    fun checkMaxTaxCodeLength_16Character() {
        val taxCode = composeRule.onNodeWithTag(testTag = AUTHENTICATION_SCREEN_TAX_CODE_EDIT_TEXT)
        for (i in 'A'..'Z')
            taxCode.performTextInput(i.toString())
        for ((key,value) in taxCode.fetchSemanticsNode().config)
            if (key.name =="EditableText")
                assertEquals("ABCDEFGHIJKLMNOP",value.toString())
    }
Mohammad Derakhshan
  • 1,262
  • 11
  • 33