2017-02-16 16 views
1

エスプレッソの文書によると、計測テストは自動的にAsyncTasksが終了するのを待つべきです。しかし、それは動作しません。私はこのシンプルなテストケースを作成しました。エスプレッソはAsyncTaskが完了するのを待たずに

package foo.bar; 

import android.os.AsyncTask; 
import android.support.test.annotation.UiThreadTest; 
import android.support.test.filters.LargeTest; 
import android.support.test.rule.UiThreadTestRule; 
import android.support.test.runner.AndroidJUnit4; 
import android.util.Log; 

import org.junit.Rule; 
import org.junit.Test; 
import org.junit.runner.RunWith; 

import static org.junit.Assert.assertEquals; 

@RunWith(AndroidJUnit4.class) 
@LargeTest 
public class ExampleInstrumentedTest { 

    private static final String TAG = "ExampleInstrumentedTest"; 

    @Rule public UiThreadTestRule uiThreadTestRule = new UiThreadTestRule(); 

    @Test 
    @UiThreadTest 
    public void testAsyncTask() throws Throwable { 
     Log.d(TAG, "testAsyncTask entry"); 
     uiThreadTestRule.runOnUiThread(() -> new AsyncTask<String, Void, Integer>() { 
      @Override 
      protected Integer doInBackground(String... params) { 
       Log.d(TAG, "doInBackground() called with: params = [" + params + "]"); 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException ignored) { 
       } 
       return params.length; 
      } 

      @Override 
      protected void onPostExecute(Integer integer) { 
       Log.d(TAG, "onPostExecute() called with: integer = [" + integer + "]"); 
       assertEquals(3, (int) integer); 
       throw new RuntimeException("this should fail the test"); 
      } 
     }.execute("One", "two", "three")); 
     Log.d(TAG, "testAsyncTask end"); 
    } 
} 

UIスレッドに戻ってもテストは失敗しますが、常に成功します。 これはテストのlogcat出力です:背景メソッドがさえ実行される前に、あなたは、テスト終了を見ることができるように

I/TestRunner: started: testAsyncTask(foo.bar.ExampleInstrumentedTest) 
D/ExampleInstrumentedTest: testAsyncTask entry 
D/ExampleInstrumentedTest: testAsyncTask end 
I/TestRunner: finished: testAsyncTask(foo.bar.ExampleInstrumentedTest) 
D/ExampleInstrumentedTest: doInBackground() called with: params = [[Ljava.lang.String;@8da3e9] 

。 テストを待機させるにはどうすればよいですか?

答えて

3

は、ビューの相互作用がある場合AsyncTasksはだけを終了するのエスプレッソ待ちをしていることが判明します。

エスプレッソは、すべてのビュー操作時にカーテンの後ろに自動的に呼び出されるUiController#loopMainThreadUntilIdle()メソッド中にタスクを待つためです。私のテストには見解やアクティビティは必要ありませんが、私はそれらを作成しなければなりませんでした。

これは、作業のテストは今どのように見えるかです:

@RunWith(AndroidJUnit4.class) 
@LargeTest 
public class ExampleInstrumentedTest { 

    private static final String TAG = "ExampleInstrumentedTest"; 

    @Rule public ActivityTestRule<TestingActivity> activityTestRule = new ActivityTestRule<>(
     TestingActivity.class, false, false); 

    @Before 
    public void setUp() throws Exception { 
     activityTestRule.launchActivity(new Intent()); 
    } 

    @Test 
    public void testAsyncTask() throws Throwable { 
     Log.d(TAG, "testAsyncTask entry"); 

     AsyncTask<String, Void, Integer> task = new AsyncTask<String, Void, Integer>() { 

      @Override 
      protected Integer doInBackground(String... params) { 
       Log.d(TAG, "doInBackground() called with: params = [" + params + "]"); 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException ignored) { 
       } 
       return params.length; 
      } 

      @Override 
      protected void onPostExecute(Integer integer) { 
       Log.d(TAG, "onPostExecute() called with: integer = [" + integer + "]"); 
       assertEquals(3, (int) integer); 
       throw new RuntimeException("this should fail the test"); 
      } 
     }; 
     task.execute("One", "two", "three"); 
     Espresso.onView(withId(android.R.id.content)).perform(ViewActions.click()); 

     Log.d(TAG, "testAsyncTask end"); 
    } 
} 

最も重要な新しいラインがある:Espresso.onView(withId(android.R.id.content)).perform(ViewActions.click());それが終了するAsyncTaskのバックグラウンド操作を待つためにエスプレッソを引き起こすので。あなたが意図した通りに動作しないのログメッセージから見ることができるように

public class TestingActivity extends Activity { 

} 
-1

これは意図したとおりに動作しています。 doInBackground()の中にThread.sleep()と呼んでいるので、UIスレッドはスリープしません。そのスリープコードをonPostExecuteに移動すると、期待どおりに動作するはずです。

+0

TestingActivityは、単に空のアクティビティです。テストが終了し、onPostExecute()が呼び出されていない場合でも、doInBackground()メソッドが呼び出されます。エスプレッソは、テストを終了する前にバックグラウンド操作が完了するのを待つ必要があります。これは、Thread.sleep()によってエミュレートできる長時間実行されるタスクです。 – McFarlane

+0

@McFarlane私が提案したようにしましたか? –

+0

これはテストケースを反映しないので、私はしませんでした。 Thread.sleepがネットワーク操作で置き換えられたとします。 onPostExecuteからこれらを実行することはできません。 – McFarlane

関連する問題