18

Retrofitを使用してネットワーク呼び出しを開始する UI でアクションを実行する統合テストを作成しています。

を実装する必要があることはわかってCountingIdlingResourceいますが、それを正しい方法で実行したいと考えています (すでに実行されている場合は、車輪を再発明したくありません)。

IdlingResourceアプリのEspressoテスト スイートに、ネットワーク リクエストの実行中に待機する機能を実装した人はいますか?

詳細はこちら

4

5 に答える 5

22

これに対する最も簡単な解決策は、基本的に Retrofit の Thread-pool executor を AsyncTask のものと交換することです (リンクされた Google グループのディスカッションから非常に役立つ Nick が推奨するように)。私はこれを次のようにします:

new RestAdapter.Builder()
               .setEndpoint(LOCLSET_SERVER_URL)
               .setExecutors(AsyncTask.THREAD_POOL_EXECUTOR,
                             new MainThreadExecutor())
               .build();

これが最も適切な解決策であるかどうかはわかりませんが、私が作業できる最も迅速で最も健全な解決策です. これは ICS+ でのみ機能するという警告に注意してください。

于 2014-05-03T22:26:39.157 に答える
4

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);
         }
      });
   }
于 2016-04-28T20:23:50.903 に答える
1

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

于 2016-08-02T02:13:34.337 に答える
1

以下の回答は Retrofit 1.6.1 に基づいていることに注意してください - 最新バージョンに更新されます。HttpExecutorRetrofit 1.9.0 では、ビアを設定RestAdapter.Builderできなくなりました

受け入れられた答えは正しい方向への一歩ですが、私は不快に感じます. AsyncTask.THREAD_POOL_EXECUTOR実際には、ライブ ビルドとテスト ビルドまたはテスト ビルドのみを設定する必要があります。

両方を設定すると、すべてのネットワーク IO プーリングが aysnc キューの実装に依存することになり、ターゲット バージョン ICS+ のアプリではデフォルトでシリアル化されます。

テストのみの設定は、テストビルドがライブビルドとは異なることを意味します。これは、テストを開始するのに最適な場所ではありません。また、非同期プールの変更により、古いデバイスでテストの問題が発生 する場合があります。

すでにEspressoフックされていることは、上記で正しく言及されています。AsyncTask.THREAD_POOL_EXECUTORぶらぶらしてみましょう...

これはどのように取得しますか?

ThreadPoolExecutorExtractor

誰/何がこれを使用しますか?

BaseLayerModuleprovideCompatAsyncTaskMonitor(ThreadPoolExecutorExtractor extractor)返すAsyncTaskPoolMonitor

それはどのように機能しますか?見てください!

AsyncTaskPoolMonitor

どこで使用されますか?

UiControllerImplユーザーが登録したidlingResourcesをチェックする前loopMainThreadUntilIdle()に手動で呼び出すメソッドがありますasyncTaskMonitor.isIdleNow()idlingResourceRegistry.allResourcesAreIdle()

Retrofit では、メソッドを使用して、Android で initと同じ httpを使用RestAdapter.Builder.setExecutors(...)して独自のインスタンス (またはバージョン) を渡すことができると推測しています。AsyncTaskPoolMonitorExecutorRetrofit

@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

于 2015-02-25T18:36:17.573 に答える
0

Asynctasks を使用している場合、Espresso は既にそれらを待つ方法を知っているため、何もする必要はありません。Asynctask スレッド プールのラッパーであるAsyncTaskPoolMonitorを使用します。

独自のスレッド プールを使用している場合 (私の場合)、エグゼキュータをラップするこのクラスを使用して、Espresso がアイドル状態であることを認識できるようにすることができます。

この素晴らしい投稿は、その仕組みを説明しています。私は自分のプロジェクトで試してみましたが、素晴らしいです! ダガーを使用してスレッド プールを取得し、それを junit @rule の IdlingResource にラップしました。

于 2016-03-31T03:00:58.400 に答える