Espresso - 在AsyncTask期间截屏

时间:2018-03-23 20:34:24

标签: android android-asynctask android-espresso

我目前正在使用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

感谢 尼古拉

1 个答案:

答案 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()));       
    }
}