Android Studio 运行 录制 Espresso 测试失败
AndroidStudio Running Recorded Espresso Test fails
我正在尝试在 AndroidStudio 4.2 中录制浓缩咖啡测试。录音似乎工作正常。但是,当我尝试 运行 记录的测试时,他们 运行 大约在中途出现 activity 开关,然后它失败了,因为找不到视图并且我不断得到 NoMatchingViewException
.
我在第一个 activity 中进行了一系列点击,这触发了第二个 activity 的加载。当 运行 试图在第二个 activity 中找到视图的测试永远不起作用。
@Test
fun firstRecordedTest() {
val materialButton = onView(
allOf(
withId(R.id.key1Button), withText("1"),
childAtPosition(
childAtPosition(
withClassName(`is`("android.widget.LinearLayout")),
0
),
3
),
isDisplayed()
)
)
materialButton.perform(click())
// Activity switches here
// The following never works
val matcher: Matcher<View> = allOf(
withId(R.id.tab_contacts), withContentDescription("Contacts"),
childAtPosition(
childAtPosition(
withId(R.id.navigation_view),
0
),
1
),
isDisplayed()
)
val bottomNavigationItemView = onView(matcher)
bottomNavigationItemView.perform(click())
}
我曾尝试放置不同种类的计时器等来等待视图加载,但要么卡住,要么失败。我也试过 this answer 但没有成功。
我错过了什么吗?是不是espresso刻录机允许,切换后无法继续测试activity?
Espresso 有时会因景色而变幻莫测。您是否尝试使用第二个 activity 中的另一个视图或删除导致测试失败的视图和 运行 没有它的测试?
浓缩咖啡不需要定时器。它会等到 activity 完全加载,你可以阅读它 here
其次,我自己没有用过录音机,因为它会产生很多噪音。例如下面的代码
val matcher: Matcher<View> = allOf(
withId(R.id.tab_contacts), withContentDescription("Contacts"),
childAtPosition(
childAtPosition(
withId(R.id.navigation_view),
0
),
1
),
isDisplayed()
)
我在这里假设点击了 navigation_view 中的一个按钮。
可以简单地替换为
onView(withId(R.id.tab_contacts)).perform(click())
现在,关于您的测试失败的原因,似乎 materialButton
点击正在执行一些异步工作或执行某种动画。
您可以像这样
在 build.gradle 中禁用动画
android {
...
testOptions {
animationsDisabled = true
}
...
}
如果您阅读 here,我总结一下,espresso 应该等待执行任何操作(在您的情况下,单击 tab_contacts
),直到消息队列为空,它会与异步任务也是如此,但是 espresso 不知道其他异步长 运行 操作。所以,如果你正在使用一些异步操作,你应该考虑使用空闲资源来进行可靠的测试。
但如果您想快速破解,可以使用这种睡眠方法:
private fun sleep(millis: Long): ViewAction {
return object : ViewAction {
override fun getConstraints(): Matcher<View> {
return isRoot()
}
override fun getDescription(): String {
return "Going to sleep for " + millis + "milliseconds"
}
override fun perform(uiController: UiController, view: View) {
uiController.loopMainThreadForAtLeast(millis)
}
}
}
然后像这样调用上面的方法:
onView(isRoot())
.perform(sleep(
TimeUnit.SECONDS.toMillis(10)
))
我正在尝试在 AndroidStudio 4.2 中录制浓缩咖啡测试。录音似乎工作正常。但是,当我尝试 运行 记录的测试时,他们 运行 大约在中途出现 activity 开关,然后它失败了,因为找不到视图并且我不断得到 NoMatchingViewException
.
我在第一个 activity 中进行了一系列点击,这触发了第二个 activity 的加载。当 运行 试图在第二个 activity 中找到视图的测试永远不起作用。
@Test
fun firstRecordedTest() {
val materialButton = onView(
allOf(
withId(R.id.key1Button), withText("1"),
childAtPosition(
childAtPosition(
withClassName(`is`("android.widget.LinearLayout")),
0
),
3
),
isDisplayed()
)
)
materialButton.perform(click())
// Activity switches here
// The following never works
val matcher: Matcher<View> = allOf(
withId(R.id.tab_contacts), withContentDescription("Contacts"),
childAtPosition(
childAtPosition(
withId(R.id.navigation_view),
0
),
1
),
isDisplayed()
)
val bottomNavigationItemView = onView(matcher)
bottomNavigationItemView.perform(click())
}
我曾尝试放置不同种类的计时器等来等待视图加载,但要么卡住,要么失败。我也试过 this answer 但没有成功。
我错过了什么吗?是不是espresso刻录机允许,切换后无法继续测试activity?
Espresso 有时会因景色而变幻莫测。您是否尝试使用第二个 activity 中的另一个视图或删除导致测试失败的视图和 运行 没有它的测试?
浓缩咖啡不需要定时器。它会等到 activity 完全加载,你可以阅读它 here
其次,我自己没有用过录音机,因为它会产生很多噪音。例如下面的代码
val matcher: Matcher<View> = allOf(
withId(R.id.tab_contacts), withContentDescription("Contacts"),
childAtPosition(
childAtPosition(
withId(R.id.navigation_view),
0
),
1
),
isDisplayed()
)
我在这里假设点击了 navigation_view 中的一个按钮。 可以简单地替换为
onView(withId(R.id.tab_contacts)).perform(click())
现在,关于您的测试失败的原因,似乎 materialButton
点击正在执行一些异步工作或执行某种动画。
您可以像这样
android {
...
testOptions {
animationsDisabled = true
}
...
}
如果您阅读 here,我总结一下,espresso 应该等待执行任何操作(在您的情况下,单击 tab_contacts
),直到消息队列为空,它会与异步任务也是如此,但是 espresso 不知道其他异步长 运行 操作。所以,如果你正在使用一些异步操作,你应该考虑使用空闲资源来进行可靠的测试。
但如果您想快速破解,可以使用这种睡眠方法:
private fun sleep(millis: Long): ViewAction {
return object : ViewAction {
override fun getConstraints(): Matcher<View> {
return isRoot()
}
override fun getDescription(): String {
return "Going to sleep for " + millis + "milliseconds"
}
override fun perform(uiController: UiController, view: View) {
uiController.loopMainThreadForAtLeast(millis)
}
}
}
然后像这样调用上面的方法:
onView(isRoot())
.perform(sleep(
TimeUnit.SECONDS.toMillis(10)
))