スケジューラを単体テストするための戦略にはどのようなものがありますか?
-
06-09-2019 - |
質問
この投稿は「マルチスレッド コードの単体テストにおける一般的なパターンは何ですか?」ということで始まりましたが、いくつか見つかりました。 他の ディスカッション SO については、「It is Hard (TM)」と「It depends (TM)」にほぼ同意しました。したがって、質問の範囲を狭めた方がより有益であると考えました。
背景 :ジョブの開始および停止時にコールバックを登録し、もちろんスケジュールの頻度を構成する方法を提供するシンプルなスケジューラーを実装しています。現在、java.util.Timer の軽量ラッパーを作成しています。
側面:
パブリックインターフェイスのみに依存してこのスケジューラをテストする方法が見つかりませんでした(次のようなもの)
addJob(jobSchedule, jobArgs,jobListener)
,removeJob(jobId)
).指定されたスケジュールに従ってジョブが呼び出されたことを確認するにはどうすればよいですか?
解決
を使用できます レコーダーオブジェクト スケジューラの各単体テストの順序、タイミング、その他の役立つ情報を記録します。テストは簡単です:
- を作成します レコーダーオブジェクト
- スケジュールを設定する
- 単体テストを実行する
- レコーダー オブジェクトがスケジュールと「互換性がある」ことを確認します。
他のヒント
また、覚えておくべきことの一つは、あなたはタイマーが動作することをテストする必要がないということです。あなたは、単にあなたがいることを確認し、タイマのモックバージョン(クラスを拡張するか、使用して EasyMockする)を書くことができますおそらくも、あなたがすべてのスレッドを必要としないことを十分に置換し、それを正しく呼んでいます。あなたの仕事のリスナーがスケジューラを追跡するのに十分なコールバックを持っている場合は、この場合、必要以上の仕事かもしれないと。
覚えておくべき他の重要なことは、スケジューラをテストする場合、スケジューラが動作しているかを追跡カスタムジョブを使用することです。スケジュールされたジョブをテストするとき、スケジューラから直接ではなくコールバックを呼び出します。あなたは、システムに応じて、一緒に両方をチェックし、より高いレベルの統合テストを持っていることがあります。
このようなスケジューラが示す可能性のある障害モードは多数あり、それぞれに独自のテスト ケースが必要になる可能性が高くなります。これらのテスト ケースは大きく異なる可能性が高いため、「場合によって異なります」。
一般に Java で並行ソフトウェアをテストする場合は、JavaOne 2007 の次のプレゼンテーションをお勧めします。 同時実行ソフトウェアのテスト.
スケジューラがスケジュールに従ってジョブを正確に実行する必要があることをテストするには、時間自体の抽象化を作成します。私は自分のプロジェクトの 1 つで、Time または Clock インターフェイスを使用して同様のことを行いました。デフォルトの実装は MillisecondTime ですが、テスト中にこれを TickTime に切り替えます。この実装により、単体テストで時間がいつどれだけ進むかを制御できるようになります。
このようにして、ジョブが 10 ティックごとに 1 回実行されるようにスケジュールされたテストを作成できます。次に、テストはティック カウンターを進めて、ジョブが正しいティックで実行されていることを確認するだけです。
同時実行コードをテストするいくつかの方法。
- 負荷がかかっている状態で同じコードを何度も実行すると、一部のバグがたまにしか発生しませんが、繰り返し実行すると一貫して発生する可能性があります。
- さまざまなスレッド/ジョブの結果を BlockingQueue などのコレクションに保存します。これにより、現在のスレッドで結果を確認し、適切なタイミングで終了することができます (醜い恣意的な sleep ステートメントを使用せずに)
同時実行性のテストが難しい場合は、オブジェクト/コンポーネントをリファクタリングしてテストしやすくすることを検討してください。
スケジューラが Executor
または ExecutorService
タスクを実行するには、Dependency Injection を使用して、タスクのタイプに対する直接の依存関係を削除できます。 Executor
, 、 そして 単純なシングルスレッドを使用する Executor
スケジューラの機能の多くをテストするため それなし 真のマルチスレッドコードの複雑さ。これらのテストをデバッグしたら、スレッド セーフをテストするという、より困難ではあるものの規模が大幅に縮小されたタスクに進むことができます。