12

ソフトウェアがますます並行的になるにつれて、単体テストで型のコア動作をテストするにはどうすればよいでしょうか(並列動作ではなく、コア動作のみ)。

古き良き時代には、型があり、それを呼び出し、それが返すものやその他の呼び出しをチェックしていました。

今日では、メソッドを呼び出すと、実際の作業は次に利用可能なスレッドで実行されるようにスケジュールされます。それが実際にいつ開始され、他のものを呼び出すかはわかりません。さらに、それらの他のものも同時に発生する可能性があります。

これにどのように対処しますか?コンカレント スケジューラを抽象化/注入しますか (たとえば、タスク並列ライブラリを抽象化し、単体テストでフェイク/モックを提供しますか)?

役に立ったリソースは何ですか?


編集

タイプの通常の動作のテストを強調するように質問を編集しました(TPLなど、マルチコアを利用するために使用される並列メカニズムは無視します)


4

6 に答える 6

5

免責事項:私はシアトルの小さなスタートアップであるCorensicで働いています。コード内の同時実行エラーを検出するように設計されたJinxというツールがあります。ベータ版の期間中は今のところ無料ですので、ぜひチェックしてみてください。(http://www.corensic.com/

一言で言えば、Jinxは非常に薄いハイパーバイザーであり、アクティブ化されると、プロセッサーとオペレーティングシステムの間に滑り込みます。次に、Jinxは実行のスライスをインテリジェントに取得し、さまざまなスレッドタイミングのシミュレーションを実行して、バグを探します。バグが発生する特定のスレッドタイミングが見つかった場合、そのタイミングをマシン上で「現実」にします(たとえば、Visual Studioを使用している場合、デバッガーはその時点で停止します)。次に、バグが発生したコード内の領域を指摘します。Jinxには誤検知はありません。バグを検出した場合、それは間違いなくバグです。

Jinxは、LinuxとWindows、およびネイティブコードとマネージコードの両方で動作します。これは言語とアプリケーションプラットフォームに依存せず、既存のすべてのツールで動作します。

チェックアウトする場合は、機能するものと機能しないものについてフィードバックを送信してください。私たちはいくつかの大きなオープンソースプロジェクトでJinxを実行してきましたが、Jinxが単にコードのストレステストよりも50〜100倍速くバグを見つけることができる状況をすでに見ています。

于 2010-07-29T18:06:17.200 に答える
4

FreemanとPryceによるGrowingObjectOrientedSoftwareのコピーを入手することをお勧めします。最後の数章は非常に啓発的であり、この特定のトピックを扱っています。また、議論のために表記法を特定するのに役立ついくつかの用語を紹介します。

要約すると....彼らの中心的なアイデアは、機能と同時/同期の側面を分割することです。

  • 最初に、通常のオブジェクトのように、単一の同期スレッドで機能部分をテストドライブします。
  • 機能部分を固定したら。並行アスペクトに進むことができます。そのためには、オブジェクトの「同時実行性に関する観測可能な不変条件」を考えて考え出す必要があります。たとえば、カウントはメソッドが呼び出された回数と等しくなければなりません。不変条件を特定したら、複数のスレッドなどを実行するストレステストを記述して、不変条件を破ることができます。ストレステストはあなたの不変量を主張します。
  • 最後に、追加の防御策として、ツールまたは静的分析を実行してバグを見つけます。

パッシブオブジェクト、つまり異なるスレッドのクライアントから呼び出されるコードの場合:テストでは、独自のスレッドを開始してクライアントを模倣する必要があります。次に、テストをSUTと同期するために、通知を聞くアプローチまたはサンプリング/ポーリングのアプローチのいずれかを選択する必要があります。

  • 予想される通知を受け取るまでブロックすることができます
  • 妥当なタイムアウトを使用して、特定の観察可能な副作用をポーリングします。
于 2010-07-31T10:02:41.703 に答える
3

競合状態とデッドロックの単体テストの分野は比較的新しく、優れたツールが不足しています。

初期のアルファ/ベータ段階にある 2 つのツールを知っています。

別のオプションは、デッドロック/競合状態を表面化させ、複数のインスタンス/スレッドを作成し、それらを並べて実行する「ストレス テスト」を試して作成することです。このアプローチの欠点は、テストが失敗した場合、それを再現するのが非常に難しいことです。何が起こったのかを理解できるように、テスト コードと本番コードの両方でログを使用することをお勧めします。

于 2010-07-29T14:24:11.750 に答える
1

私が便利だと思った手法は、Intel Parallel Inspector のような競合状態を検出するツール内でテストを実行することです。タイミングへの依存関係をチェックする必要があるため、テストの実行は通常よりもはるかに遅くなりますが、1 回の実行で通常の実行を何百万回も繰り返す必要のあるバグを見つけることができます。

マルチコアを介して細粒度の並列処理のために既存のシステムを変換するときに、これが非常に役立つことがわかりました。

于 2010-07-29T13:59:02.427 に答える
0

TPLには独自の個別の単体テストがあることを考えると、それを検証する必要はありません。

モジュールごとに2つのテストを作成するとします
。1)モジュールの機能が正しいかどうかをテストできるように、環境変数または#defineを使用してTPLをオンにするシングルスレッド単体テスト。
2)モジュールをスレッド展開可能モードで実行するストレステスト。このテストは同時実行性の問題を見つけようとし、大量のランダムデータを使用する必要があります。

2番目のテストには多くのモジュールが含まれることが多いため、おそらく統合/システムテストの方が多くなります。

于 2010-07-29T23:36:50.147 に答える
0

単体テストでは、並行性/非同期動作を実際にテストするべきではありません。そこでモックを使用し、モックが期待される入力を受け取ることを確認する必要があります。

統合テストでは、バックグラウンドタスクを明示的に呼び出し、その後の期待を確認します。

キュウリでは、次のようになります。

When I press "Register"
And the email sending script is run
Then I should have an email
于 2010-07-29T13:25:56.937 に答える