0

Espresso を使用して Web 通話をテストしたいと考えています。AsyncTask を使用せずにこれを機能させることができるかどうかを確認するために、小さなテスト アプリを作成しました。データが返されると、TextView は呼び出しが成功したかどうかをユーザーに通知します。新しいスレッドで Web 呼び出しを行っています。

私のテストでは、Web 要求が満たされるまでテストを待機させるパターンとしてAdvancedSynchronizationTestに従ってみました。ただし、私の実装は機能していないようです。私の理解では、コールバックがメイン アクティビティに返される前に、オーバーライドしているメソッドが終了しています。その場合、間違ったクラスを上書きしています。また、ランナブル自体をオーバーライドしようとしましたが (以下の例を参照)、UI の更新を単にブール値を設定するように変更しましたが、結果は変わりませんでした。明らかに、Espresso は別のスレッドを使用することを好みませんが、スレッドが完了するまで待機する必要があることを認識しないのはなぜですか? AsyncTask を使用しない代替手段は何でしょうか?

プロジェクト全体は、https ://github.com/bqmackay/EspressoCustomThreadingResourceExample で確認できます。

問題のコードは次のとおりです。

MainActivityTest

public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
...
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        getActivity();

        Runnable runnable = getActivity().getDownloadHelper().getWebCallRunnable();
        CountingIdlingResource countingIdlingResource = new CountingIdlingResource("WebCallRunnableCall");
        getActivity().getDownloadHelper().setWebCallRunnable(new DecoratedWebCallRunnable(runnable, countingIdlingResource));
        registerIdlingResources(countingIdlingResource);
    }

    public void testThreadRetrieval() throws Exception {
        onView(withText("Thread")).perform(click());
        assertTrue(getActivity().isDidThreadReturn());
        //onView(withText("Thread Retrieved")).check(matches(isDisplayed()));
    }

    private class DecoratedWebCallRunnable implements Runnable {

        private final Runnable realRunnable;
        private final CountingIdlingResource countingIdlingResource;

        private DecoratedWebCallRunnable(Runnable realRunnable, CountingIdlingResource countingIdlingResource) {
            this.realRunnable = realRunnable;
            this.countingIdlingResource = countingIdlingResource;
        }

        @Override
        public void run() {
            countingIdlingResource.increment();
            try {
                realRunnable.run();
            } finally {
                countingIdlingResource.decrement();
            }
        }
    }

ダウンロードを助ける人

public class DownloadHelper {
    private Runnable webCallRunnable;

    private Runnable createWebCallRunnable() {
        return new Runnable() {
        @Override
        public void run() {
            HttpClient httpclient = new DefaultHttpClient();
            HttpResponse response = null;
            try {

                response = httpclient.execute(new HttpGet("http://whoismyrepresentative.com/getall_mems.php?zip=84020"));
                StatusLine statusLine = response.getStatusLine();
                if(statusLine.getStatusCode() == HttpStatus.SC_OK){
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    response.getEntity().writeTo(out);
                    out.close();
                    repsCallbackInterface.onRepsThreadReceived(true);
                } else{
                    //Closes the connection.
                    response.getEntity().getContent().close();
                    repsCallbackInterface.onRepsThreadReceived(false);
                    throw new IOException(statusLine.getReasonPhrase());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        };
    }
}

主な活動

public class MainActivity extends Activity implements RepsCallbackInterface {
    ....
    @Override
    public void onRepsThreadReceived(final boolean didReceive) {
        setDidThreadReturn(true);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                threadText.setText(didReceive ? "Thread Retrieved" : "Thread Failed");
            }
        });
    }
}
4

1 に答える 1

2

ここで実際に質問を提供しなかったので、このセットアップが期待どおりに機能しない理由についての質問だと思います。

(少なくとも) 2 つの理由があります。

  1. assertassertTrue(getActivity().isDidThreadReturn());testThreadRetrieval()IdlingResources が終了するのをまったく待ちません。ViewInteraction.check()とのみViewInteraction.perform()がそれらを認識しており、ViewAssertionまたはを適用しようとする前に IdlingResources をチェックしますViewAction

  2. の後のコメントアウトされた行assertTrue()が代わりに適用されても、機能しません。これは、インストルメンテーション スレッドが独立しており、で作成された新しいスレッドgetReps()が開始されるのを待たないためCountingIdlingResourceです。 .

何らかの理由で本当に AsyncTask を使用したくない場合でも、エグゼキューターを使用して AsynTask スレッド プールを監視する Espresso から利益を得ることができます。したがって、別のスレッドを開始する代わりに、Runnable を に送信するだけAsyncTask.THREAD_POOL_EXECUTORです。

于 2014-04-27T20:19:25.423 に答える