我目前正在使用Espresso以编程方式截取Android应用的屏幕截图。我成功使用了
android.support.test.runner.screenshot.Screenshot
问题是,给出以下假设from official Espresso docs:
- 消息队列为空。
- 当前没有AsyncTask执行任务的实例。
- 所有开发人员定义的空闲资源都处于空闲状态。
通过执行这些检查,Espresso大大增加了在任何给定时间只能发生一次UI操作或断言的可能性。此功能可为您提供更可靠,更可靠的测试结果。
任何AsyncTask
正在运行时,我都无法执行任何测试。我需要在AsyncTask
正在运行时拍摄一些屏幕截图,但无法了解如何执行此类任务的文档。 The most similar SO thread I found似乎不起作用,不知道这是因为AsyncTask
太快而无法截屏。
// Start the async task
onView(withId(R.id.start_task_button)).perform(click());
// Then "press" the back button (in the ui thread of the app under test)
mActivityTestRule.runOnUiThread(new Runnable() {
@Override
public void run() {
mScreenshotWatcher.captureScreenshot("screenshot1");
}
});
有关此问题的任何线索?这是正确的方法还是我应该在IdlingResource
?
AsyncTask
感谢 尼古拉
答案 0 :(得分:1)
根据我对您的问题的理解,您希望在正在进行AsyncTask时截取屏幕截图。
我创建了一个最小的Android应用来验证您的方案,并且当使用来自Espresso的click()时它不起作用。问题是,一旦Espresso执行click(),它之后会调用loopMainThreadUntilIdle()。由于您的AsyncTask已经在此时启动,因此UiControllerImpl#loopMainThreadUntilIdle()内的循环会反复运行,直到AsyncTask完成。
解决此问题的最简单方法是使用自定义ViewMatcher进行点击并立即返回。
<强> MainActivity.java 强>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.test_edit_text).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
v.setVisibility(View.INVISIBLE);
new AsyncTask<Object, Object, Object>() {
@Override
protected Object doInBackground(Object... objects) {
SystemClock.sleep(20000000);
return null;
}
@Override
protected void onPostExecute(Object o) {
findViewById(R.id.test_edit_text)
.setVisibility(View.VISIBLE);
}
}.execute();
}});
}
}
<强>的AndroidManifest.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.question.stackoverflow"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
<强> MainActivityTest.java 强>
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Rule
public ActivityTestRule<MainActivity> activityActivityTestRule = new ActivityTestRule<MainActivity>(MainActivity.class);
@Test
public void testTakeScreenshot() throws Exception {
Espresso.onView(withId(R.id.test_edit_text)).check(matches(isDisplayed()));
// use a custom ViewAction here because this call has be non-blocking
Espresso.onView(withId(R.id.test_edit_text)).perform(new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isDisplayingAtLeast(90);
}
@Override
public String getDescription() {
return "NonBlockingTap";
}
@Override
public void perform(UiController uiController, View view) {
view.performClick();
}
});
ScreenCapture screenCapture = Screenshot.capture();
screenCapture.setFormat(Bitmap.CompressFormat.PNG);
screenCapture.setName("test.png");
screenCapture.process();
Espresso.onView(withId(R.id.test_edit_text)).check(matches(isDisplayed()));
}
}