使用Espresso过程中遇到的问题
2016-10-19 17:45
316 查看
一、android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: (with text: is "gh" and Child at position 0 in parent (with id: studiotwotwotest.myapplication:id/lay_root and Child at position 0 in parent with id: android:id/content)
and is displayed on the screen to the user)
原因:在AdapterView控件中,在子view运行时才会动态填充view。所以如果布局中有AdapterView(例如ListView,GridView,or Spinner),并且屏幕初始化时并未加载到屏幕里,方法onView()将无效。你需要调用onData()方法来进行控件的查找。
过程:
(一)布局中没有ListView
目的:测试AdapterView之外的控件(测试以editText为id,并且文本为gh的EditText是否存在)
1.activity_main.xml中的代码,EditText中text为空
布局预览图(左边一个TextView,右边一个EditText)
现在执行Record Espresso Test,界面中输入的内容
选择exist
现在修改布局文件,给EditText赋值gh,运行生成的测试文件
修改后的main_activity.xml
生成的测试文件MainActivityTest3中的内容
运行结果可以看到一切正常:
(二)布局中有ListView
目的:测试AdapterView(本文中测试的是ListView)
activity_main.xml中的内容,布局中含有一个ListView,高度是固定值200dp
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/lay_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="100dp"
android:layout_height="200dp"
android:text=""
android:id="@+id/editText"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:text="TextView"
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/textView"
tools:layout_constraintTop_creator="1"
android:layout_marginStart="16dp"
android:layout_marginTop="7dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="16dp" />
<ListView
android:id="@+id/lv_listview"
android:layout_width="150dp"
android:layout_height="200dp"
tools:layout_constraintTop_creator="1"
android:layout_marginTop="251dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
手机界面
1.点击listview条目中的界面可见的button,并且也选择Exists
生成的测试文件
package studiotwotwotest.myapplication;
import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest3 {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void mainActivityTest3() {
//隐藏了虚拟键盘
pressBack();
<span style="white-space:pre"> </span>//查找listview中第一个button,显示内容为0,并点击
ViewInteraction button = onView(
allOf(withId(R.id.bt_button), withText("0"),
withParent(childAtPosition(
withId(R.id.lv_listview),
0)),
isDisplayed()));
button.perform(click());
<span style="white-space:pre"> </span>//查找listview中第四个按钮,显示的内容为3,并点击了一下
ViewInteraction button2 = onView(
allOf(withId(R.id.bt_button), withText("3"),
withParent(childAtPosition(
withId(R.id.lv_listview),
3)),
isDisplayed()));
button2.perform(click());
<span style="white-space:pre"> </span>//检测id为bt_btton,显示内容为0的按钮是否存在
ViewInteraction button3 = onView(
allOf(withId(R.id.bt_button),
childAtPosition(
childAtPosition(
withId(R.id.lv_listview),
0),
0),
isDisplayed()));
button3.check(matches(isDisplayed()));
}
private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}
@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
}
此时可以看到运行结果正常:
2.点击界面listview中不可见的条目,如6,或者7、8、9
package studiotwotwotest.myapplication;
import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest3 {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void mainActivityTest3() {
//隐藏键盘
pressBack();
<span style="white-space:pre"> </span>//查找第一个button,显示的内容为0,并点击
ViewInteraction button = onView(
allOf(withId(R.id.bt_button), withText("0"),
withParent(childAtPosition(
withId(R.id.lv_listview),
0)),
isDisplayed()));
button.perform(click());
<span style="white-space:pre"> </span>//查找第8个button,显示的内容为7,并点击
ViewInteraction button2 = onView(
allOf(withId(R.id.bt_button), withText("7"),
withParent(childAtPosition(
withId(R.id.lv_listview),
7)),
isDisplayed()));
button2.perform(click());
<span style="white-space:pre"> </span>//断言第8个按钮,显示内容为7的存在
ViewInteraction button3 = onView(
allOf(withId(R.id.bt_button),
childAtPosition(
childAtPosition(
withId(R.id.lv_listview),
7),
7),
isDisplayed()));
button3.check(matches(isDisplayed()));
}
private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}
@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
}
可以看到运行失败:
解决办法:AdapterView中,如果view在屏幕初始化时不显示,onView()方法将会失效。onData()方法是安全的,出于安全性考虑,可以全部使用该方法。
现在将onView()替换为onData(),运行结果正常
替换后的测试文件
package studiotwotwotest.myapplication;
import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onData;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasToString;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest5 {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void mainActivityTest3() {
//隐藏键盘
pressBack();
//查找第一个button,显示的内容为0,并点击
ViewInteraction button = onData(hasToString("0")).perform(click());
<pre name="code" class="java"> //查找第8个button,显示的内容为7,并点击 ViewInteraction button1 = onData(hasToString("7")).perform(click());
运行结果:
二、No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)
原因:屏幕锁屏了。
解决方法:测试时保持屏幕处于解锁常亮状态
三、运行测试文件时界面卡住了
布局文件如下,listview的高度设置的是wrap_content,并且距顶部251dp,所以listview位于屏幕底部,完全展开,但是没有在屏幕中完全显示
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/lay_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="100dp"
android:layout_height="100dp"
android:text=""
android:id="@+id/editText"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:text="TextView"
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/textView"
tools:layout_constraintTop_creator="1"
android:layout_marginStart="16dp"
android:layout_marginTop="7dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="16dp" />
<ListView
android:id="@+id/lv_listview"
android:layout_width="362dp"
android:layout_height="wrap_content"
tools:layout_constraintTop_creator="1"
android:layout_marginTop="251dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
手机界面为:
测试文件为:
package studiotwotwotest.myapplication;
import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onData;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasToString;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest5 {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void mainActivityTest3() {
ViewInteraction button = onData(hasToString("0")).perform(click());
ViewInteraction button1 = onData(hasToString("7")).perform(click());
ViewInteraction button2 = onData(hasToString("7")).perform(click());
button2.check(matches(isDisplayed()));
}
}
出现的状况如下,底部左侧的进度条不停地旋转,但是一直不结束:
原因:onData()加载AdapterView中的view时,需要先使view先获取焦点,即加载到屏幕中。如上的测试文件加载了条目7,但是条目7不在屏幕中,又由于listview设置为wrap_content,即listview已经完全展开,并不能移动条目,所以就出现了如上的问题
解决办法:使用onData()方法,在写布局时,需要将listview设置为一个固定的高度,即需要在listview内容长度过长显示不全时可以滑动界面。如设置高度200dp。
修改后的布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/lay_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="100dp"
android:layout_height="100dp"
android:text=""
android:id="@+id/editText"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:text="TextView"
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/textView"
tools:layout_constraintTop_creator="1"
android:layout_marginStart="16dp"
android:layout_marginTop="7dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="16dp" />
<ListView
android:id="@+id/lv_listview"
android:layout_width="150dp"
android:layout_height="200dp"
tools:layout_constraintTop_creator="1"
android:layout_marginTop="251dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
修改后的手机界面:
注:参考资料:http://blog.csdn.net/yang786654260/article/details/52670837
https://developer.android.com/training/testing/ui-testing/espresso-testing.html#run
http://blog.csdn.net/qq744746842/article/details/50664136
http://awonwon.blogspot.com/2015/10/hello-espresso.html
https://google.github.io/android-testing-support-library/docs/espresso/index.html
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: (with text: is "gh" and Child at position 0 in parent (with id: studiotwotwotest.myapplication:id/lay_root and Child at position 0 in parent with id: android:id/content)
and is displayed on the screen to the user)
原因:在AdapterView控件中,在子view运行时才会动态填充view。所以如果布局中有AdapterView(例如ListView,GridView,or Spinner),并且屏幕初始化时并未加载到屏幕里,方法onView()将无效。你需要调用onData()方法来进行控件的查找。
过程:
(一)布局中没有ListView
目的:测试AdapterView之外的控件(测试以editText为id,并且文本为gh的EditText是否存在)
1.activity_main.xml中的代码,EditText中text为空
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/lay_root" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="100dp" android:layout_height="100dp" android:text="" android:id="@+id/editText" tools:layout_constraintTop_creator="1" tools:layout_constraintRight_creator="1" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:text="TextView" android:layout_width="100dp" android:layout_height="100dp" android:id="@+id/textView" tools:layout_constraintTop_creator="1" android:layout_marginStart="16dp" android:layout_marginTop="7dp" tools:layout_constraintLeft_creator="1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_marginLeft="16dp" /> </android.support.constraint.ConstraintLayout>
布局预览图(左边一个TextView,右边一个EditText)
现在执行Record Espresso Test,界面中输入的内容
选择exist
现在修改布局文件,给EditText赋值gh,运行生成的测试文件
修改后的main_activity.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/lay_root" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="100dp" android:layout_height="100dp" android:text="gh" android:id="@+id/editText" tools:layout_constraintTop_creator="1" tools:layout_constraintRight_creator="1" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:text="TextView" android:layout_width="100dp" android:layout_height="100dp" android:id="@+id/textView" tools:layout_constraintTop_creator="1" android:layout_marginStart="16dp" android:layout_marginTop="7dp" tools:layout_constraintLeft_creator="1" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_marginLeft="16dp" /> </android.support.constraint.ConstraintLayout>
生成的测试文件MainActivityTest3中的内容
package studiotwotwotest.myapplication; import android.support.test.espresso.ViewInteraction; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.LargeTest; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; import static android.support.test.espresso.action.ViewActions.replaceText; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withParent; import static org.hamcrest.Matchers.allOf; @LargeTest @RunWith(AndroidJUnit4.class) public class MainActivityTest3 { @Rule public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class); @Test public void mainActivityTest3() { ViewInteraction editText = onView( allOf(withId(R.id.editText), withParent(allOf(withId(R.id.lay_root), withParent(withId(android.R.id.content)))), isDisplayed())); editText.perform(click()); ViewInteraction editText2 = onView( allOf(withId(R.id.editText), withParent(allOf(withId(R.id.lay_root), withParent(withId(android.R.id.content)))), isDisplayed())); editText2.perform(replaceText("gh"), closeSoftKeyboard()); } }
运行结果可以看到一切正常:
(二)布局中有ListView
目的:测试AdapterView(本文中测试的是ListView)
activity_main.xml中的内容,布局中含有一个ListView,高度是固定值200dp
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/lay_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="100dp"
android:layout_height="200dp"
android:text=""
android:id="@+id/editText"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:text="TextView"
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/textView"
tools:layout_constraintTop_creator="1"
android:layout_marginStart="16dp"
android:layout_marginTop="7dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="16dp" />
<ListView
android:id="@+id/lv_listview"
android:layout_width="150dp"
android:layout_height="200dp"
tools:layout_constraintTop_creator="1"
android:layout_marginTop="251dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
手机界面
1.点击listview条目中的界面可见的button,并且也选择Exists
生成的测试文件
package studiotwotwotest.myapplication;
import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest3 {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void mainActivityTest3() {
//隐藏了虚拟键盘
pressBack();
<span style="white-space:pre"> </span>//查找listview中第一个button,显示内容为0,并点击
ViewInteraction button = onView(
allOf(withId(R.id.bt_button), withText("0"),
withParent(childAtPosition(
withId(R.id.lv_listview),
0)),
isDisplayed()));
button.perform(click());
<span style="white-space:pre"> </span>//查找listview中第四个按钮,显示的内容为3,并点击了一下
ViewInteraction button2 = onView(
allOf(withId(R.id.bt_button), withText("3"),
withParent(childAtPosition(
withId(R.id.lv_listview),
3)),
isDisplayed()));
button2.perform(click());
<span style="white-space:pre"> </span>//检测id为bt_btton,显示内容为0的按钮是否存在
ViewInteraction button3 = onView(
allOf(withId(R.id.bt_button),
childAtPosition(
childAtPosition(
withId(R.id.lv_listview),
0),
0),
isDisplayed()));
button3.check(matches(isDisplayed()));
}
private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}
@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
}
此时可以看到运行结果正常:
2.点击界面listview中不可见的条目,如6,或者7、8、9
package studiotwotwotest.myapplication;
import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest3 {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void mainActivityTest3() {
//隐藏键盘
pressBack();
<span style="white-space:pre"> </span>//查找第一个button,显示的内容为0,并点击
ViewInteraction button = onView(
allOf(withId(R.id.bt_button), withText("0"),
withParent(childAtPosition(
withId(R.id.lv_listview),
0)),
isDisplayed()));
button.perform(click());
<span style="white-space:pre"> </span>//查找第8个button,显示的内容为7,并点击
ViewInteraction button2 = onView(
allOf(withId(R.id.bt_button), withText("7"),
withParent(childAtPosition(
withId(R.id.lv_listview),
7)),
isDisplayed()));
button2.perform(click());
<span style="white-space:pre"> </span>//断言第8个按钮,显示内容为7的存在
ViewInteraction button3 = onView(
allOf(withId(R.id.bt_button),
childAtPosition(
childAtPosition(
withId(R.id.lv_listview),
7),
7),
isDisplayed()));
button3.check(matches(isDisplayed()));
}
private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {
return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}
@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
}
可以看到运行失败:
解决办法:AdapterView中,如果view在屏幕初始化时不显示,onView()方法将会失效。onData()方法是安全的,出于安全性考虑,可以全部使用该方法。
现在将onView()替换为onData(),运行结果正常
替换后的测试文件
package studiotwotwotest.myapplication;
import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onData;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasToString;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest5 {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void mainActivityTest3() {
//隐藏键盘
pressBack();
//查找第一个button,显示的内容为0,并点击
ViewInteraction button = onData(hasToString("0")).perform(click());
<pre name="code" class="java"> //查找第8个button,显示的内容为7,并点击 ViewInteraction button1 = onData(hasToString("7")).perform(click());
<span style="white-space:pre"> </span>//断言第8个按钮,显示内容为7的存在ViewInteraction button2 = onData(hasToString("7")).perform(click()); button2.check(matches(isDisplayed())); }}
运行结果:
二、No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)
原因:屏幕锁屏了。
解决方法:测试时保持屏幕处于解锁常亮状态
三、运行测试文件时界面卡住了
布局文件如下,listview的高度设置的是wrap_content,并且距顶部251dp,所以listview位于屏幕底部,完全展开,但是没有在屏幕中完全显示
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/lay_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="100dp"
android:layout_height="100dp"
android:text=""
android:id="@+id/editText"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:text="TextView"
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/textView"
tools:layout_constraintTop_creator="1"
android:layout_marginStart="16dp"
android:layout_marginTop="7dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="16dp" />
<ListView
android:id="@+id/lv_listview"
android:layout_width="362dp"
android:layout_height="wrap_content"
tools:layout_constraintTop_creator="1"
android:layout_marginTop="251dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
手机界面为:
测试文件为:
package studiotwotwotest.myapplication;
import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onData;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasToString;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest5 {
@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void mainActivityTest3() {
ViewInteraction button = onData(hasToString("0")).perform(click());
ViewInteraction button1 = onData(hasToString("7")).perform(click());
ViewInteraction button2 = onData(hasToString("7")).perform(click());
button2.check(matches(isDisplayed()));
}
}
出现的状况如下,底部左侧的进度条不停地旋转,但是一直不结束:
原因:onData()加载AdapterView中的view时,需要先使view先获取焦点,即加载到屏幕中。如上的测试文件加载了条目7,但是条目7不在屏幕中,又由于listview设置为wrap_content,即listview已经完全展开,并不能移动条目,所以就出现了如上的问题
解决办法:使用onData()方法,在写布局时,需要将listview设置为一个固定的高度,即需要在listview内容长度过长显示不全时可以滑动界面。如设置高度200dp。
修改后的布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/lay_root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:layout_width="100dp"
android:layout_height="100dp"
android:text=""
android:id="@+id/editText"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:text="TextView"
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/textView"
tools:layout_constraintTop_creator="1"
android:layout_marginStart="16dp"
android:layout_marginTop="7dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="16dp" />
<ListView
android:id="@+id/lv_listview"
android:layout_width="150dp"
android:layout_height="200dp"
tools:layout_constraintTop_creator="1"
android:layout_marginTop="251dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
修改后的手机界面:
注:参考资料:http://blog.csdn.net/yang786654260/article/details/52670837
https://developer.android.com/training/testing/ui-testing/espresso-testing.html#run
http://blog.csdn.net/qq744746842/article/details/50664136
http://awonwon.blogspot.com/2015/10/hello-espresso.html
https://google.github.io/android-testing-support-library/docs/espresso/index.html
相关文章推荐
- 使用母板页过程中遇到的图片地址问题
- 使用Linux过程中遇到的问题以及解决方案
- TrayIcon 使用过程中的遇到问题
- [项目过程中所遇到的各种问题记录]编辑器篇——FCKeditor相关知识及各种常见使用问题
- 在nhibernate使用过程中遇到的几个问题。
- VC 使用过程中所遇到的一些问题,汇总在这里,希望对后来者有些许帮助
- VC6使用过程中遇到的问题收集(1) zz
- VC6使用过程中遇到的问题收集(1)
- 在nhibernate使用过程中遇到的几个问题02
- [项目过程中所遇到的各种问题记录]编辑器篇——使用FCKeditor生成静态分页HTML
- 使用jdic过程中遇到的问题总结
- 呵呵,很久没写随笔了,这次带来个新的小问题,在使用win7RTM过程中遇到的
- 使用webchart过程中遇到的一些问题
- [项目过程中所遇到的各种问题记录]编辑器篇——FCKeditor相关知识及各种常见使用问题
- updater application block v2.0的使用过程中遇到的问题及解决办法
- Eclipse RCP使用Spring时遇到的问题及解决过程
- 使用Ado.Net 中的OleDbCommand.ExecuteNonQuery()建立过程遇到的问题
- 在使用ArcGIS过程中遇到的一些问题
- 框架使用过程中遇到的几个问题
- [项目过程中所遇到的各种问题记录]ORM篇——使用NHibernate配置对象实体的一些小问题