安卓系统上的Espresso测试在设备上正常工作时,日志上的视图层次结构错误



我为活动开关编写了一个简单的测试示例,当我点击按钮时,会打开新的片段(LoginFragment(。有测试类代码:

@RunWith(AndroidJUnit4::class)
@LargeTest
class MainActivityTest {
@get:Rule
var activityScenarioRule = activityScenarioRule<MainActivity>()

@Test
fun test_clickLogInButton_openLoginFragment() {
onView(withId(R.id.btnEnter)).perform(click())
onView(withId(R.id.loginFragmentLayout)).check(matches(isDisplayed()))
}
}

这个测试在一台计算机上运行正常,但现在我将它转移到另一台计算机,日志中的视图层次结构开始错误显示。日志:

androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: view.getId() is <2131362001/com.example.android:id/btnEnter>

同时,我看到给定的";按钮按压";命令实际上是在模拟器上使用的,并且启动了新的片段。因此,我假设测试仍然有效,但日志的显示以及测试结果被破坏了。

我的依赖关系。我尝试了很多变体,现在我有以下几种:

// Testing
testImplementation 'junit:junit:4.13.2'
testImplementation "org.json:json:20180813"
testImplementation 'org.mockito:mockito-core:3.12.4'
testImplementation 'org.powermock:powermock-api-mockito2:2.0.9'
testImplementation 'org.powermock:powermock-core:2.0.9'
testImplementation 'org.powermock:powermock-module-junit4-rule-agent:2.0.2'
testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.2'
testImplementation 'org.powermock:powermock-module-junit4:2.0.9'
testImplementation "androidx.room:room-testing:$room_version"
//UI tests
androidTestImplementation "androidx.test.espresso:espresso-core:3.4.0"
androidTestImplementation "androidx.test.ext:junit-ktx:1.1.3"
debugImplementation "androidx.fragment:fragment-testing:1.4.0"
androidTestImplementation "androidx.fragment:fragment-ktx:1.4.0"
androidTestImplementation "androidx.test:core:1.4.0"
androidTestImplementation "androidx.test:rules:1.4.0"
androidTestImplementation "androidx.test:runner:1.4.0"
androidTestImplementation "androidx.navigation:navigation-testing:2.3.5"

我想做的事:

  • 清除缓存并重新启动
  • 从输出文件夹中删除apk
  • 在多个设备上进行测试(真实设备和模拟器(
  • 在调试模式下进行测试(代码工作正常,但测试的日志和结果相同(

在我的androidTest清单上,我有以下内容:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.presentation.activities"
android:versionCode="1"
android:versionName="1.0">
<application>
<uses-library android:name="android.test.runner" />
</application>
</manifest>

有什么建议吗?

正如我所看到的,问题出在UI测试本身。我设法通过在测试中的第一个onView操作中添加try-catch逻辑来修复它。这是我为它写的小乐趣:
private fun performActionCount(
action: () -> Unit,
maxRepeatTimes: Int = -1
) {
var success = false
var counter = if (maxRepeatTimes == -1) Int.MIN_VALUE else 0
while (!success && counter < maxRepeatTimes) {
success = try {
counter++
action()
true
} catch (e: NoMatchingViewException) {
false
}
}
}

它执行您需要执行的lambda操作,并尝试多次执行它。我如何使用它的例子:

performActionCount(
action = {
onView(withId(R.id.btnEnter)).perform(click())
},
maxRepeatTimes = 20
)

最新更新