Retrofitを使用してネットワーク呼び出しを開始する UI でアクションを実行する統合テストを作成しています。
を実装する必要があることはわかってCountingIdlingResource
いますが、それを正しい方法で実行したいと考えています (すでに実行されている場合は、車輪を再発明したくありません)。
IdlingResource
アプリのEspressoテスト スイートに、ネットワーク リクエストの実行中に待機する機能を実装した人はいますか?
詳細はこちら。
Retrofitを使用してネットワーク呼び出しを開始する UI でアクションを実行する統合テストを作成しています。
を実装する必要があることはわかってCountingIdlingResource
いますが、それを正しい方法で実行したいと考えています (すでに実行されている場合は、車輪を再発明したくありません)。
IdlingResource
アプリのEspressoテスト スイートに、ネットワーク リクエストの実行中に待機する機能を実装した人はいますか?
詳細はこちら。
これに対する最も簡単な解決策は、基本的に Retrofit の Thread-pool executor を AsyncTask のものと交換することです (リンクされた Google グループのディスカッションから非常に役立つ Nick が推奨するように)。私はこれを次のようにします:
new RestAdapter.Builder()
.setEndpoint(LOCLSET_SERVER_URL)
.setExecutors(AsyncTask.THREAD_POOL_EXECUTOR,
new MainThreadExecutor())
.build();
これが最も適切な解決策であるかどうかはわかりませんが、私が作業できる最も迅速で最も健全な解決策です. これは ICS+ でのみ機能するという警告に注意してください。
Retrofit 2.0 で RxJava Observables を使用している場合は、.subscribeOn(Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR))
代わりに使用することができ.subscribeOn(Schedulers.io())
、すべて正常に動作します!
または、代わりに RxJavaSchedulersHook をオーバーライドして、1 つの場所で変更を加えることができます。例えば:
public MySuperCoolClient() {
if (BuildConfig.DEBUG) {
configureIoSchedulerToUseAsyncTaskThreadPool();
}
this.restApi = new Retrofit.Builder()
.baseUrl(Parameters.endpoint)
.addConverterFactory(GsonConverterFactory.create(gsonBuilder()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()
.create(RestApi.class);
}
private void configureIoSchedulerToUseAsyncTaskThreadPool() {
RxJavaPlugins.getInstance().registerSchedulersHook(new RxJavaSchedulersHook() {
@Override
public Scheduler getIOScheduler() {
return Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
}
Retrofit 2 は okhttp3 を使用し、それがディスパッチャを使用します。Jake Whartonは、ディスパッチャのアイドル状態を監視するこのライブラリを作成しました。次のように IdlingResource を作成します。
IdlingResource resource = OkHttp3IdlingResource.create("OkHttp", okHttpClient);
IdlingResource は、http 呼び出しの直前または直後にアイドル状態であると言う可能性があり、Espresso テストは実行され、待機する代わりに失敗するため、Espresso テストを成功させるためにこれを使用するには十分ではないことに注意してください (私は試しました)。
これらのケースに対する私の推奨事項は、スレッド プールを使用してバックグラウンド タスクを起動し、このスレッド プールをラップする IdlingResource を作成することです。詳細については、この記事を参照してください: https://medium.com/@yair.kukielka/idlingresource-dagger-and-junit-rules-198e3ae791ff
以下の回答は Retrofit 1.6.1 に基づいていることに注意してください - 最新バージョンに更新されます。HttpExecutor
Retrofit 1.9.0 では、ビアを設定RestAdapter.Builder
できなくなりました
受け入れられた答えは正しい方向への一歩ですが、私は不快に感じます. AsyncTask.THREAD_POOL_EXECUTOR
実際には、ライブ ビルドとテスト ビルドまたはテスト ビルドのみを設定する必要があります。
両方を設定すると、すべてのネットワーク IO プーリングが aysnc キューの実装に依存することになり、ターゲット バージョン ICS+ のアプリではデフォルトでシリアル化されます。
テストのみの設定は、テストビルドがライブビルドとは異なることを意味します。これは、テストを開始するのに最適な場所ではありません。また、非同期プールの変更により、古いデバイスでテストの問題が発生 する場合があります。
すでにEspresso
フックされていることは、上記で正しく言及されています。AsyncTask.THREAD_POOL_EXECUTOR
ぶらぶらしてみましょう...
これはどのように取得しますか?
誰/何がこれを使用しますか?
BaseLayerModule
をprovideCompatAsyncTaskMonitor(ThreadPoolExecutorExtractor extractor)
返すAsyncTaskPoolMonitor
それはどのように機能しますか?見てください!
どこで使用されますか?
UiControllerImpl
ユーザーが登録したidlingResourcesをチェックする前loopMainThreadUntilIdle()
に手動で呼び出すメソッドがありますasyncTaskMonitor.isIdleNow()
idlingResourceRegistry.allResourcesAreIdle()
Retrofit では、メソッドを使用して、Android で initと同じ httpを使用RestAdapter.Builder.setExecutors(...)
して独自のインスタンス (またはバージョン) を渡すことができると推測しています。AsyncTaskPoolMonitor
Executor
Retrofit
@Override Executor defaultHttpExecutor() {
return Executors.newCachedThreadPool(new ThreadFactory() {
@Override public Thread newThread(final Runnable r) {
return new Thread(new Runnable() {
@Override public void run() {
Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND);
r.run();
}
}, RestAdapter.IDLE_THREAD_NAME);
}
});
}
(ここから)
そして、これをIdlingResource
インターフェイスにラップして、テストで使用します!!
唯一の問題は、メインのルーパーに依存する mainThread でRetrofit
別のメソッドを使用してコールバックを作成することです。これにより問題が発生する可能性がありますが、今のところ、Espresso もこれに関連付けられていると想定しています。これを調べる必要があります。Executor
Asynctasks を使用している場合、Espresso は既にそれらを待つ方法を知っているため、何もする必要はありません。Asynctask スレッド プールのラッパーであるAsyncTaskPoolMonitorを使用します。
独自のスレッド プールを使用している場合 (私の場合)、エグゼキュータをラップするこのクラスを使用して、Espresso がアイドル状態であることを認識できるようにすることができます。
この素晴らしい投稿は、その仕組みを説明しています。私は自分のプロジェクトで試してみましたが、素晴らしいです! ダガーを使用してスレッド プールを取得し、それを junit @rule の IdlingResource にラップしました。