Issue
I'm currently using Espresso to programmatically take screenshots of an Android app. I'm successfully using
android.support.test.runner.screenshot.Screenshot
Problem is, given the following assumptions from official Espresso docs:
- The message queue is empty.
- There are no instances of AsyncTask currently executing a task.
- All developer-defined idling resources are idle.
By performing these checks, Espresso substantially increases the likelihood that only one UI action or assertion can occur at any given time. This capability gives you more reliable and dependable test results.
I can't perform any test while any AsyncTask is running. I need to take some screenshots while my AsyncTask is running, but can't get my head around the docs on how to perform such task. The most similar SO thread I found doesn't seem to work, don't know if this is because the AsyncTask is too fast to take the screenshot.
// 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");
}
});
Any clue about this? Is this the correct approach or should I implement IdlingResource in my AsyncTask?
thanks nicola
Solution
From how I understood your question you'd like to take a screenshot when there's an AsyncTask in progress.
I created a minimum Android app to verify your scenario and it didn't work when click() from Espresso was used. The problem is that once Espresso performs its click() it invokes loopMainThreadUntilIdle() afterwards. As your AsyncTask has started at this point already the loop inside UiControllerImpl#loopMainThreadUntilIdle() gets run over and over again until the AsyncTask has finished.
The easiest way to overcome this is to use a custom ViewMatcher making a click and returning immediately.
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()));
}
}
Answered By - Anatolii
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.