应用程序在 UI 测试期间启动后关闭
Application closes after launch during UI testing
我正在尝试 运行 UI 使用 espresso 在 android 应用程序上进行测试,但是当我 运行 在移动设备或模拟器上进行测试时,应用程序会打开甚至在测试 运行 之前,它突然以快速的方式关闭自己。
不是应用程序崩溃,它只是在测试运行时打开后立即关闭。我不确定我在引发此行为的测试配置中缺少什么。
这是我的 gradle 文件
apply plugin: 'com.android.application'
apply plugin: 'realm-android'
android {
compileSdkVersion 25
buildToolsVersion '25.0.3'
defaultConfig {
applicationId "com.test1"
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.android.support:cardview-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'jp.wasabeef:picasso-transformations:2.1.2'
compile 'com.google.firebase:firebase-database:9.4.0'
compile 'com.google.firebase:firebase-auth:9.4.0'
compile 'com.google.firebase:firebase-messaging:9.4.0'
compile 'com.google.android.gms:play-services-location:9.4.0'
compile 'com.google.android.gms:play-services-places:9.4.0'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
androidTestCompile ('com.android.support.test:runner:1.0.1') {
exclude module: 'support-annotations'
}
androidTestCompile ('com.android.support.test:rules:1.0.1') {
exclude module: 'support-annotations'
}
androidTestCompile ('com.android.support.test.espresso:espresso-intents:3.0.1') {
exclude module: 'support-annotations'
}
androidTestCompile ('com.android.support.test.espresso:espresso-web:3.0.1') {
exclude module: 'support-annotations'
}
androidTestCompile ('com.android.support.test.espresso:espresso-core:3.0.1') {
exclude module: 'support-annotations'
}
}
apply plugin: 'com.google.gms.google-services'
这是我的测试
@RunWith(AndroidJUnit4.class)
public class PAC4Testing {
@Rule
public ActivityTestRule<BookListActivity> mActivityRule = new ActivityTestRule<>(
BookListActivity.class);
@Test
public void checkLoadedList() {
if (getRVcount() > 0){
assertEquals(9,getRVcount());
}
}
private int getRVcount(){
RecyclerView recyclerView = (RecyclerView) mActivityRule.getActivity().findViewById(R.id.book_list);
return recyclerView.getAdapter().getItemCount();
}
@Test
public void checkMenuOpened() {
}
@Test
public void checkLoadedWebViewFromDetail() {
}
}
谢谢!
编辑这些是日志,当测试 运行 时出现错误,因为应用程序关闭,测试在屏幕上找不到任何东西。
java.lang.NullPointerException: Attempt to invoke virtual method 'int
android.support.v7.widget.RecyclerView$Adapter.getItemCount()' on a null object reference
at PAC4Testing.getRVcount(PAC4Testing.java:34)
at PAC4Testing.checkLoadedList(PAC4Testing.java:27)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:433)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:58)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:375)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1886)
错误清楚地表明 getRVcount()
中的 recyclerView.getAdapter()
调用正在返回 null
。那是因为即使您确实从 RecyclerView recyclerView = (RecyclerView) mActivityRule.getActivity().findViewById(R.id.book_list);
获得视图,您获得的 recyclerview 与 class 中的不同,因为它是新的并且没有与之关联的适配器或布局管理器.因此,您无法在适配器上调用 getItemCount()
。
我不确定你到底想在这里测试什么,因为你还没有发布 class' 代码,但这里有几个链接你可能想看一下,看看它们是否对你有帮助吗https://spin.atomicobject.com/2016/04/15/espresso-testing-recyclerviews/ and http://alexander-thiele.blogspot.in/2016/01/espresso-ui-tests-and-recyclerview.html
在测试执行期间,您不应该从 Instrumentation
线程查询 UI 的状态,因为它不提供与主线程的任何同步。
相反,如果您需要查询状态,您应该使用 espresso ViewMatcher
s 或实现您自己的匹配器。 Espresso 有一个内置的主线程同步,可以确保 UI 的所有更新在返回结果之前完成。
这里是returns项数的匹配器的例子:
fun hasCount(expectedCount: Int): Matcher<View> =
object : BoundedMatcher<View, RecyclerView>(RecyclerView::class.java) {
var actualCount = -1
override fun describeTo(description: Description) {
if (actualCount > -1) {
description.apply {
appendText("$expectedCount number of items in RecyclerView")
appendText("\n But $actualCount")
}
}
}
override fun matchesSafely(recyclerView: RecyclerView): Boolean {
actualCount = recyclerView.adapter.itemCount
return actualCount == expectedCount
}
}
它的用法是这样的:
onView(withId(R.id.recyclerView)).check(matches(hasCount(5)))
我正在尝试 运行 UI 使用 espresso 在 android 应用程序上进行测试,但是当我 运行 在移动设备或模拟器上进行测试时,应用程序会打开甚至在测试 运行 之前,它突然以快速的方式关闭自己。
不是应用程序崩溃,它只是在测试运行时打开后立即关闭。我不确定我在引发此行为的测试配置中缺少什么。
这是我的 gradle 文件
apply plugin: 'com.android.application'
apply plugin: 'realm-android'
android {
compileSdkVersion 25
buildToolsVersion '25.0.3'
defaultConfig {
applicationId "com.test1"
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:support-v4:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.android.support:cardview-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'jp.wasabeef:picasso-transformations:2.1.2'
compile 'com.google.firebase:firebase-database:9.4.0'
compile 'com.google.firebase:firebase-auth:9.4.0'
compile 'com.google.firebase:firebase-messaging:9.4.0'
compile 'com.google.android.gms:play-services-location:9.4.0'
compile 'com.google.android.gms:play-services-places:9.4.0'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
androidTestCompile ('com.android.support.test:runner:1.0.1') {
exclude module: 'support-annotations'
}
androidTestCompile ('com.android.support.test:rules:1.0.1') {
exclude module: 'support-annotations'
}
androidTestCompile ('com.android.support.test.espresso:espresso-intents:3.0.1') {
exclude module: 'support-annotations'
}
androidTestCompile ('com.android.support.test.espresso:espresso-web:3.0.1') {
exclude module: 'support-annotations'
}
androidTestCompile ('com.android.support.test.espresso:espresso-core:3.0.1') {
exclude module: 'support-annotations'
}
}
apply plugin: 'com.google.gms.google-services'
这是我的测试
@RunWith(AndroidJUnit4.class)
public class PAC4Testing {
@Rule
public ActivityTestRule<BookListActivity> mActivityRule = new ActivityTestRule<>(
BookListActivity.class);
@Test
public void checkLoadedList() {
if (getRVcount() > 0){
assertEquals(9,getRVcount());
}
}
private int getRVcount(){
RecyclerView recyclerView = (RecyclerView) mActivityRule.getActivity().findViewById(R.id.book_list);
return recyclerView.getAdapter().getItemCount();
}
@Test
public void checkMenuOpened() {
}
@Test
public void checkLoadedWebViewFromDetail() {
}
}
谢谢!
编辑这些是日志,当测试 运行 时出现错误,因为应用程序关闭,测试在屏幕上找不到任何东西。
java.lang.NullPointerException: Attempt to invoke virtual method 'int
android.support.v7.widget.RecyclerView$Adapter.getItemCount()' on a null object reference
at PAC4Testing.getRVcount(PAC4Testing.java:34)
at PAC4Testing.checkLoadedList(PAC4Testing.java:27)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:433)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:58)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:375)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1886)
错误清楚地表明 getRVcount()
中的 recyclerView.getAdapter()
调用正在返回 null
。那是因为即使您确实从 RecyclerView recyclerView = (RecyclerView) mActivityRule.getActivity().findViewById(R.id.book_list);
获得视图,您获得的 recyclerview 与 class 中的不同,因为它是新的并且没有与之关联的适配器或布局管理器.因此,您无法在适配器上调用 getItemCount()
。
我不确定你到底想在这里测试什么,因为你还没有发布 class' 代码,但这里有几个链接你可能想看一下,看看它们是否对你有帮助吗https://spin.atomicobject.com/2016/04/15/espresso-testing-recyclerviews/ and http://alexander-thiele.blogspot.in/2016/01/espresso-ui-tests-and-recyclerview.html
在测试执行期间,您不应该从 Instrumentation
线程查询 UI 的状态,因为它不提供与主线程的任何同步。
相反,如果您需要查询状态,您应该使用 espresso ViewMatcher
s 或实现您自己的匹配器。 Espresso 有一个内置的主线程同步,可以确保 UI 的所有更新在返回结果之前完成。
这里是returns项数的匹配器的例子:
fun hasCount(expectedCount: Int): Matcher<View> =
object : BoundedMatcher<View, RecyclerView>(RecyclerView::class.java) {
var actualCount = -1
override fun describeTo(description: Description) {
if (actualCount > -1) {
description.apply {
appendText("$expectedCount number of items in RecyclerView")
appendText("\n But $actualCount")
}
}
}
override fun matchesSafely(recyclerView: RecyclerView): Boolean {
actualCount = recyclerView.adapter.itemCount
return actualCount == expectedCount
}
}
它的用法是这样的:
onView(withId(R.id.recyclerView)).check(matches(hasCount(5)))