在Unit Compose UI测试中,存在OutlinedTextField但未显示。

huangapple go评论137阅读模式
英文:

In Unit Compose UI test, OutlinedTextField exists but is not displayed

问题

我在单元测试中测试了一个名为 OutlinedTextField 的组件。当我运行应用程序时,文本字段始终显示出来。但是,当我运行单元测试时,该元素存在,但未显示出来。我不能在未调用项目的焦点的情况下进行文本输入,这让我认为该项目已显示。

这是我的 OutlinedTextField:

@Composable
fun ChangeUserNameInput(
    userName: String,
    onChangeUserName: (String) -> Unit
) {
    Box(modifier = Modifier.testTag(UpdateUserNameTags.USERNAME).alpha(1f)) {
        OutlinedTextField(
            modifier = Modifier
                .fillMaxWidth()
                .alpha(1f)
                .semantics { contentDescription = UpdateUserNameTags.USERNAME },
            value = userName,
            onValueChange = onChangeUserName,
            colors = TextFieldDefaults.textFieldColors(
                backgroundColor = Color.Transparent,
                focusedIndicatorColor = MaterialTheme.colors.primary,
                unfocusedIndicatorColor = niro,
                disabledIndicatorColor = Color.Transparent,
                focusedLabelColor = MaterialTheme.colors.primary,
                unfocusedLabelColor = niro,
                textColor = MaterialTheme.colors.onBackground
            ),
            label = {
                Text(text = stringResource(id = R.string.update_user_name))
            },
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Text
            )
        )
    }
}

这是我的测试:

@Test
fun `测试用户名输入文本是否显示`() = runTest {
    val value = composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME)
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).assertExists()
    composeTestRule.awaitIdle()

    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).assertIsDisplayed() // 在这里失败
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).performTextInput(" Welsh")
    value.assertTextEquals("Kristy Welsh")

    //composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).assertTextContains("Kristy Welsh")
}

我无法弄清楚为什么该项目没有显示出来。

英文:

I have an OutlinedTextField that I'm testing in unit tests. When I run the app, the TextField is always displayed. However, when I run the unit tests, the element exists, but is not displayed. I can't do text input without calling focus on the item, which I am assuming means the item is displayed.

Here is my OutlinedTextField:

@Composable
fun ChangeUserNameInput(
    userName: String,
    onChangeUserName: (String) -> Unit) {
    Box(modifier = Modifier.testTag(UpdateUserNameTags.USERNAME).alpha(1f)) {
        OutlinedTextField(
            modifier = Modifier
                .fillMaxWidth()
                .alpha(1f)
                .semantics { contentDescription = UpdateUserNameTags.USERNAME },
            value = userName,
            onValueChange = onChangeUserName,
            colors = TextFieldDefaults.textFieldColors(
                backgroundColor = Color.Transparent,
                focusedIndicatorColor = MaterialTheme.colors.primary,
                unfocusedIndicatorColor = niro,
                disabledIndicatorColor = Color.Transparent,
                focusedLabelColor = MaterialTheme.colors.primary,
                unfocusedLabelColor = niro,
                textColor = MaterialTheme.colors.onBackground
            ),
            label = {
                Text(text = stringResource(id = R.string.update_user_name))
            },
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Text
            )
        )
    }
}

Here is my test:

@Test
fun `test to see if username typed text is Displayed`() = runTest {
    val value = composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME)
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).assertExists()
    composeTestRule.awaitIdle()


   composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).assertIsDisplayed() ---> FAILS here
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).performTextInput(" Welsh")
    value.assertTextEquals("Kristy Welsh")

    //composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).assertTextContains("Kristy Welsh")
}

I can't figure out why the item is not displaying.

答案1

得分: 0

I've translated the code portion for you:

我已经测试过这个并通过在测试函数的开头设置内容来使其工作

composeTestRule.setContent { ChangeUserNameInput("Kristy", {}) }

看起来你正在测试传递给文本框的状态是否在输入文本时更新 - 这意味着你的设置内容函数需要包括保存传递给ChangeUserNameInput()的用户名状态的组合项

这是我使用的测试类

@RunWith(AndroidJUnit4::class)
class StackTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    @OptIn(ExperimentalCoroutinesApi::class)
    @Test
    fun teststack() = runTest {
        composeTestRule.setContent { ChangeUserNameInput("Kristy", {}) }
        composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).assertExists()
        composeTestRule.awaitIdle()
        composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).assertIsDisplayed() // 在这里失败
        composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).performTextInput(" Welsh")
        composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).printToLog("OutlineTextBox Test")
        composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).assertTextEquals(R.string.update_user_name, "Kristy Welsh")
    }
}

最后注意assertTextEquals() 测试了你的OutlinedTextField中的标签 + 值所以你需要在assertTextEquals()中添加标签文本就像我在这个函数中所做的那样

Please note that I've translated the code portion only, as per your request.

英文:

I've tested this out and got it working by setting the content at the start of your test function.

composeTestRule.setContent { ChangeUserNameInput("Kristy",{})}

It looks like you're testing the state passed to the text box is updated when you enter text - this means your set content function will need to include the composable that is holding the state of username passed to ChangeUserNameInput().

Here is the test class I used.

@RunWith(AndroidJUnit4::class)
class StackTest {

@get:Rule
val composeTestRule = createComposeRule()


@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun teststack() = runTest {
    composeTestRule.setContent {  ChangeUserNameInput("Kristy",{})}
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).assertExists()
    composeTestRule.awaitIdle()
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).assertIsDisplayed() // fails here
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).performTextInput(" Welsh")
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).printToLog("OutlineTextBox Test")
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).assertTextEquals(R.string.update_user_name, "Kristy Welsh")
}

}

Final note, assertTextEquals() tests the label + value in your OutlinedTextField so you need to add the label text to your assertTextEquals() as i've done in this function.

答案2

得分: 0

My problem actually was that the screen was too large and a bunch of the content was off screen.

I solved it by making the screen scrollable and then doing performScrollTo:

@Test
fun test to see if username is showing() = runTest {
composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).assertExists()
composeTestRule.onNodeWithTag("Annotated String").assertIsDisplayed()
composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).performScrollTo()
composeTestRule.onNodeWithTag(UPDATE_USER_SCREEN).assertIsDisplayed()
composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).assertTextContains("Kristy")
}

英文:

My problem actually was that the screen was too large and a bunch of the content was off screen.

I solved it by making the screen scrollable and the doing performScrollTo:

@Test
fun `test to see if username is showing`() = runTest {
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).assertExists()
    composeTestRule.onNodeWithTag("Annotated String").assertIsDisplayed()
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).performScrollTo()
    composeTestRule.onNodeWithTag(UPDATE_USER_SCREEN).assertIsDisplayed()
    composeTestRule.onNodeWithTag(UpdateUserNameTags.USERNAME).onChildAt(0).assertTextContains("Kristy")
}

huangapple
  • 本文由 发表于 2023年8月11日 02:31:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76878454.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定