mercredi 7 septembre 2016

Android Espresso. perform(click()) waits for the tasks started by a button click to complete

I'm writing an instrumented Android test. When I click the button sample_btn, a Task and a DummyTask start. When the Task ends, the EditText sample_text becomes visible, and I can type some text there.

I was surprised when I noticed the following fact. onView(withId(R.id.sample_btn)).perform(click()); waits for the Task and the DummyTask to complete. Why?

MainActivity

package com.sample;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import java.lang.ref.WeakReference;

    public class MainActivity extends AppCompatActivity implements View.OnClickListener {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            findViewById(R.id.sample_btn).setOnClickListener(this);

        }

        @Override
        public void onClick(final View v) {
            switch (v.getId()) {
            case R.id.sample_btn:
                Log.d("UnderstandIsDisplayed", "Before sample_btn click IN CODE");
                new Task(this).execute();
                new DummyTask().execute();
                Log.d("UnderstandIsDisplayed", "After sample_btn click IN CODE");
                break;
            }
        }

        private static class DummyTask extends AsyncTask<Void, Void, Void> {

            @Override
            protected Void doInBackground(final Void... params) {
                try {
                    Log.d("UnderstandIsDisplayed", "DummyTask doInBackground");
                    Thread.sleep(8000);
                    Log.d("UnderstandIsDisplayed", "DummyTask doInBackground done");
                } catch (InterruptedException e) {
                }
                return null;
            }
        }

        private static class Task extends AsyncTask<Void, Void, Void> {

            final WeakReference<MainActivity> mActivityWeakReference;

            Task(MainActivity activity) {
                mActivityWeakReference = new WeakReference<>(activity);
            }

            @Override
            protected Void doInBackground(final Void... params) {
                try {
                    Log.d("UnderstandIsDisplayed", "doInBackground");
                    Thread.sleep(4000);
                    Log.d("UnderstandIsDisplayed", "doInBackground done");
                } catch (InterruptedException e) {
                }
                return null;
            }

            @Override
            protected void onPostExecute(final Void aVoid) {
                super.onPostExecute(aVoid);
                MainActivity mainActivity = mActivityWeakReference.get();
                if (mainActivity != null) {
                    mainActivity.findViewById(R.id.sample_text).setVisibility(View.VISIBLE);
                    Log.d("UnderstandIsDisplayed", "sample_text VISIBLE");
                }
            }
        }

    }

MainActivityTest

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

    private MainActivity mMainActivity;

    public MainActivityTest() {
        super(MainActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
        mMainActivity = getActivity();

    }

    public void testFoo() {
        Log.d("UnderstandIsDisplayed", "Before sample_btn click");
        onView(withId(R.id.sample_btn)).perform(click());
        Log.d("UnderstandIsDisplayed", "After sample_btn click");
        // TODO: Wait for sample_text to become visible
        onView(withId(R.id.sample_text)).perform(typeText("sample_text"));

    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/container"
    xmlns:android="http://ift.tt/nIICcg"
    xmlns:tools="http://ift.tt/LrGmb4"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#336633"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.sample.MainActivity">

    <Button
        android:id="@+id/sample_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="sample_btn"/>

    <EditText
        android:id="@+id/sample_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"/>

</LinearLayout>

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "24.0.1"

    defaultConfig {
        applicationId "com.sample"
        minSdkVersion 15
        targetSdkVersion 23
        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:23.0.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
}

This is what I see when running the app itself:

09-07 12:09:02.623 22356-22356/com.sample D/UnderstandIsDisplayed: Before sample_btn click IN CODE
09-07 12:09:02.629 22356-22660/com.sample D/UnderstandIsDisplayed: doInBackground 1562
09-07 12:09:02.631 22356-22356/com.sample D/UnderstandIsDisplayed: After sample_btn click IN CODE
09-07 12:09:06.670 22356-22660/com.sample D/UnderstandIsDisplayed: doInBackground done
09-07 12:09:06.672 22356-22356/com.sample D/UnderstandIsDisplayed: sample_text VISIBLE
09-07 12:09:06.680 22356-22771/com.sample D/UnderstandIsDisplayed: DummyTask doInBackground 1563
09-07 12:09:14.721 22356-22771/com.sample D/UnderstandIsDisplayed: DummyTask doInBackground done

This is what I see when running testFoo:

09-07 12:10:24.357 24892-24911/com.sample D/UnderstandIsDisplayed: testFoo = 1555
09-07 12:10:24.357 24892-24911/com.sample D/UnderstandIsDisplayed: Before sample_btn click
09-07 12:10:24.429 24892-24892/com.sample D/UnderstandIsDisplayed: Before sample_btn click IN CODE
09-07 12:10:24.431 24892-24954/com.sample D/UnderstandIsDisplayed: doInBackground 1563
09-07 12:10:24.431 24892-24892/com.sample D/UnderstandIsDisplayed: After sample_btn click IN CODE
09-07 12:10:28.465 24892-24954/com.sample D/UnderstandIsDisplayed: doInBackground done
09-07 12:10:28.469 24892-24892/com.sample D/UnderstandIsDisplayed: sample_text VISIBLE
09-07 12:10:28.472 24892-24936/com.sample D/UnderstandIsDisplayed: DummyTask doInBackground 1558
09-07 12:10:36.483 24892-24936/com.sample D/UnderstandIsDisplayed: DummyTask doInBackground done
09-07 12:10:36.702 24892-24911/com.sample D/UnderstandIsDisplayed: After sample_btn click

Aucun commentaire:

Enregistrer un commentaire