Android Junitユニットテスト、非同期テスト方法の概要と非同期テストフレームワークガイド
6567 ワード
Android Junitユニットテスト、非同期テスト方法の概要と非同期テストフレームワークガイド
本文で解決した問題
1.junitを使ってAndroidユニットのテストをする方法
2.junitを使用してAndroid非同期インタフェースユニットのテストを行う方法
3.著者らがカプセル化したフレームワークを用いて、junitでAndroid非同期インタフェースユニットテストを優雅に行う[doge]
JunitはAndroid Studioがオリジナルでサポートしているテストフレームワークとしてユニットテストを容易に実行でき、注記@Testで直接caseをテストしてサブスレッドで実行する方法をマークすることができます.@UiThreadTestとマークされている場合、テストcaseはuiスレッドで実行されます.
しかしjunit自体の設計では,testメソッドごとに実行が終了すると,そのメソッドの実行スレッドが一括してkillされるため,非同期呼び出しのメソッドではサブスレッドが一括して回収され,コールバック関数も実行できない.
栗を挙げると、以下のテストcaseではコールバックが届かず、エラーが発生します.
解決策ブロックtest case
テストスレッドが死んだ後、対応サブタスクが失敗する以上、最も直接的な方法は直接対応をブロックすることです.
1スレッドロック
Javaが極めて使いやすいオリジナルapiを提供してくれて嬉しいです.CountDownLatchはスレッドを直接ブロックし、完了を待つことができます.
走ってみると、できるようで、ロゴが出てきました.
しかし、実際の使用では新たな問題に直面した.
2 Looperブロッキング(Handler thread)
sdkをしたことのある学生は、このようなニーズに直面する可能性があります.
ビジネス・エンドの同級生プライマリ・スレッド(またはhandlerスレッド)は、非同期リクエストを開始し、実行が完了すると(handlerによって)プライマリ・スレッド(またはhandlerスレッド)にコールバックします.
この問題を処理すると,[スキーム1]のコールバック関数も実際には非同期スレッドでしか実行できず,開始スレッド(テストスレッド)に戻って実行を切り替えることができないことが分かった.これは明らかに私たちの優雅な非同期インタフェースのテストニーズを満たすことができません.そこで,新しいスキーム2 Looperブロッキングがlooperブロッキングによって実現され,コールバック関数のスレッド切替が必要となる.
上記の問題の根本はhandlerスレッドのコールバックと切り替えの問題であり,この場合テストスレッドにはlooperがないため,このような環境を作る必要がある.同時にlooperが存在する以上,そのスピン機能も閉塞に対する我々のニーズを満たすことができ,この場合,以前のCountDownLatchを直接捨てることができるようになった.
次のコードを入手しました
このような過程に適応できるように見え、楽しくテストを始めたが、すぐに新しい問題に出会った.
3 Handler thread+パッケージ
自動化テストの利点は、テストcaseを自動的に一括して実行することです.そして次の過程で
パラメータ化されたバッチ入力を実行するために、
そこで新たな問題が発生し,実際の実行時@Testメソッドは同じサブスレッドで実行されるため,
そこで最も直接的に解決する方法は、最初からprepareでいいですか?
実際にはできませんが、このような場合は次のような問題があります.
Looperに詳しい方はご存知ですが、quit以降はLooperのqueueは使えません.また、ブロック
そこで,このような状況を満たすためには,スレッド間コールバックを必要とするインタフェーステストを別のHandlerThreadで実行するしかない.その後、コールバックの実行が完了する前に、最初のテストスレッド
そこで以下のような内容が得られた
4異常の最適化と処理
[スキーム3]一般的なロットテストを基本的に処理できる.しかし、厳密なプログラマーとして、このようなコードは明らかに優雅ではありません.そこで、二次パッケージが必要です.パッケージされたコード呼び出しは、以下のように簡潔になります.
優雅になったのか、具体的なフレームワークとdemoは私のgithubを参考にすることができます.
まだ終わっていません.私たちはまだ一つの問題が残っています.実際の操作では,非同期スレッド中のAssert Errorが直接投げ出されるとAndroid StudioのRun Textウィンドウに直接表示されるのではなく,プロセスcrashのログとして表示されるので,実際の原因はlogcatで調べる必要がある.これは明らかに健全ではないので,対応するThrowableをテストスレッドに戻す必要がある.この機能も私のgithubにカプセル化されています.
That's all, thanks for your time
本文で解決した問題
1.junitを使ってAndroidユニットのテストをする方法
2.junitを使用してAndroid非同期インタフェースユニットのテストを行う方法
3.著者らがカプセル化したフレームワークを用いて、junitでAndroid非同期インタフェースユニットテストを優雅に行う[doge]
JunitはAndroid Studioがオリジナルでサポートしているテストフレームワークとしてユニットテストを容易に実行でき、注記@Testで直接caseをテストしてサブスレッドで実行する方法をマークすることができます.@UiThreadTestとマークされている場合、テストcaseはuiスレッドで実行されます.
しかしjunit自体の設計では,testメソッドごとに実行が終了すると,そのメソッドの実行スレッドが一括してkillされるため,非同期呼び出しのメソッドではサブスレッドが一括して回収され,コールバック関数も実行できない.
栗を挙げると、以下のテストcaseではコールバックが届かず、エラーが発生します.
@Runwith(Junit4.calss)
class Test1{
public static final String TAG="sample test";
@Test
public void test1(){
new YourAsyncJob().run(new YourAsyncTestCallback(){
@Override
public void onFinished(){
Log.i(TAG, "async call back");
}
});
Log.i(TAG, "run async ok");
}
}
解決策ブロックtest case
テストスレッドが死んだ後、対応サブタスクが失敗する以上、最も直接的な方法は直接対応をブロックすることです.
1スレッドロック
Javaが極めて使いやすいオリジナルapiを提供してくれて嬉しいです.CountDownLatchはスレッドを直接ブロックし、完了を待つことができます.
await()
メソッドが呼び出されると、対応するスレッドがcountdownlatchのcountが0になるまでブロックされ、実行が再開されます.そこで私たちは以下の案を得ました
@Runwith(Junit4.calss)
class Test1{
public static final String TAG="sample test";
@Test
public void test1(){
final CountDownLatch mutex = new CountDownLatch(1);
new YourAsyncJob().run(new YourAsyncTestCallback(){
@Override
public void onFinished(){
Log.i(TAG, "async call back");
mutex.countDown();
}
});
Log.i(TAG, "run async ok");
mutex.await();
}
}
走ってみると、できるようで、ロゴが出てきました.
しかし、実際の使用では新たな問題に直面した.
2 Looperブロッキング(Handler thread)
sdkをしたことのある学生は、このようなニーズに直面する可能性があります.
ビジネス・エンドの同級生プライマリ・スレッド(またはhandlerスレッド)は、非同期リクエストを開始し、実行が完了すると(handlerによって)プライマリ・スレッド(またはhandlerスレッド)にコールバックします.
この問題を処理すると,[スキーム1]のコールバック関数も実際には非同期スレッドでしか実行できず,開始スレッド(テストスレッド)に戻って実行を切り替えることができないことが分かった.これは明らかに私たちの優雅な非同期インタフェースのテストニーズを満たすことができません.そこで,新しいスキーム2 Looperブロッキングがlooperブロッキングによって実現され,コールバック関数のスレッド切替が必要となる.
上記の問題の根本はhandlerスレッドのコールバックと切り替えの問題であり,この場合テストスレッドにはlooperがないため,このような環境を作る必要がある.同時にlooperが存在する以上,そのスピン機能も閉塞に対する我々のニーズを満たすことができ,この場合,以前のCountDownLatchを直接捨てることができるようになった.
次のコードを入手しました
@Runwith(Junit4.calss)
class Test1{
public static final String TAG="sample test";
@Test
public void test1(){
Looper.prepare();
//final CountDownLatch mutex = new CountDownLatch(1);
new YourAsyncJob().run(new YourAsyncTestCallback(){
@Override
public void onFinished(){
Log.i(TAG, "async call back");
//mutex.countDown();
Looper.myLooper().quitSafely();
}
});
Log.i(TAG, "run async ok");
// mutex.await();
Looper.loop();
}
}
このような過程に適応できるように見え、楽しくテストを始めたが、すぐに新しい問題に出会った.
3 Handler thread+パッケージ
自動化テストの利点は、テストcaseを自動的に一括して実行することです.そして次の過程で
@RunWith(Parameterized.class)
パラメータ化されたバッチ入力を実行するために、
@Parameterized.Parameters
注記が使用される.そこで新たな問題が発生し,実際の実行時@Testメソッドは同じサブスレッドで実行されるため,
Looper.prepare()
を複数回実行することは明らかに現実的ではない(RuntimeExceptionがある).そこで最も直接的に解決する方法は、最初からprepareでいいですか?
実際にはできませんが、このような場合は次のような問題があります.
Looper.myLooper().quitSafely()
をいつ実行するかLooperに詳しい方はご存知ですが、quit以降はLooperのqueueは使えません.また、ブロック
@Test
のスレッドを終了まで再開するためには、[スキーム2]に基づいてloop()を解除する必要がある.そこで,このような状況を満たすためには,スレッド間コールバックを必要とするインタフェーステストを別のHandlerThreadで実行するしかない.その後、コールバックの実行が完了する前に、最初のテストスレッド
@Test
スレッドをブロックし、HandlerThreadの生存を保証する.(ここではsetupのたびに新しいスレッドを作成します.なぜなら、TestCaseにまたがってこのスレッドを再利用することはできません.Caseが実行されると、このスレッドはシステムによって強制的に回収されます)そこで以下のような内容が得られた
@RunWith(Parameterized.class)
class Test1{
public static final String TAG="sample test";
private HandlerThread t;
private Handler tH;
@Parameterized.Parameters
public static Collection
4異常の最適化と処理
[スキーム3]一般的なロットテストを基本的に処理できる.しかし、厳密なプログラマーとして、このようなコードは明らかに優雅ではありません.そこで、二次パッケージが必要です.パッケージされたコード呼び出しは、以下のように簡潔になります.
@RunWith(Parameterized.class)
class Test1 extend ZCCBase{
public static final String TAG="sample test";
@Parameterized.Parameters
public static Collection
優雅になったのか、具体的なフレームワークとdemoは私のgithubを参考にすることができます.
まだ終わっていません.私たちはまだ一つの問題が残っています.実際の操作では,非同期スレッド中のAssert Errorが直接投げ出されるとAndroid StudioのRun Textウィンドウに直接表示されるのではなく,プロセスcrashのログとして表示されるので,実際の原因はlogcatで調べる必要がある.これは明らかに健全ではないので,対応するThrowableをテストスレッドに戻す必要がある.この機能も私のgithubにカプセル化されています.
That's all, thanks for your time