如何通过 UI 测试读取 Jetpack Compose TextField 的语义值?

How to read the Semantic values of a Jetpack Compose TextField through UI tests?

我是 Jetpack Compose 测试的新手,正在尝试了解如何访问 OutlinedTextField 的值以对它们执行 Instrumentation 测试:

我无法弄清楚访问和检查 EditFeild 的 SemanticsNode 中某些值的语法。

我正在使用以下 Instrumentation 测试:

@Test
fun NameTextField_LongInput_CompleteStatusAndLabelCorrect() {
    composeTestRule.setContent {
        ComposeTemplateTheme {
            NameTextInput(name = "RandomName123", onNameInfoValid = { isComplete = it })
        }
        assertEquals(isComplete, true)

        // This is accessing the label text 
        composeTestRule.onNodeWithText("Name").assertIsDisplayed()
        //How do I access the Editable text?
        //composeTestRule.onNodeWithEditableText("RandomName123") // How do I do something like this?!?!123
    }
}

我想弄清楚如何访问此树中的各种项目:

printToLog:
 Printing with useUnmergedTree = 'false'
 Node #1 at (l=0.0, t=110.0, r=1080.0, b=350.0)px
  |-Node #2 at (l=48.0, t=158.0, r=1032.0, b=326.0)px
    ImeAction = 'Default'
    EditableText = 'RandomName123' // HOW DO I ACCESS THIS?!?! I want to confirm values of this?!?!
    TextSelectionRange = 'TextRange(0, 0)'
    Focused = 'false'
    Text = '[Name]'
    Actions = [GetTextLayoutResult, SetText, SetSelection, OnClick, OnLongClick, PasteText]
    MergeDescendants = 'true'

这是我要测试的完整可组合项:

@Composable
fun NameTextInput(name: String, onNameInfoValid: (Boolean) -> Unit) {
    // Name
    val nameState = remember { mutableStateOf(TextFieldValue(name)) }
    val nameString = stringResource(R.string.name)
    val nameLabelState = remember { mutableStateOf(nameString) }
    val isNameValid = if (nameState.value.text.length >= 5) {
        nameLabelState.value = nameString
        onNameInfoValid(true)
        true
    } else {
        nameLabelState.value = stringResource(R.string.name_error)
        onNameInfoValid(false)
        false
    }
    OutlinedTextField(
        shape = RoundedCornerShape(card_corner_radius),
        value = nameState.value,
        singleLine = true,
        onValueChange = { if (it.text.length <= 30) nameState.value = it },
        isError = !isNameValid,
        label = { Text(nameLabelState.value) },
        keyboardOptions = KeyboardOptions(
            keyboardType = KeyboardType.Text,
            capitalization = KeyboardCapitalization.Words
        ),
        colors = customTextColors(),
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizfull_verthalf)
    )
}

问得好,您可以通过其修饰符的标签访问文本字段。

OutlinedTextField(
    ...
    modifier = Modifier
        .fillMaxWidth()
        .padding(horizfull_verthalf)
        .testTag("field")
)

然后访问带有上述标签的文本字段,您可以断言结果如下:

val value = composeTestRule.onNodeWithTag("field")
value.assertTextEquals("RandomName123") // verify value of textfield
for ((key, value) in value.fetchSemanticsNode().config) {
    Log.d("AAA", "$key = $value") // access and print all config
    if (key.name == "EditableText"){
        assertEquals("RandomName123", value.toString())
    }
}

在我这边尝试并测试成功。