C ++のモック、偽物、スタブ

この翻訳は、テストに十分に応答しないレガシーC ++コードの膨大なベースを単体テストするための新しいアプローチを示しています。







私たちはテストに多くの注意を払います-私たちの生活を単純化するため、また開発者に安定した信頼できるUnityエンジンを提供するためです したがって、このプロセスを継続的に最適化し続けます。



C#での高レベルテストについては既に説明しましたが、時間が経つにつれて、低レベルで高速かつ正確なテストを忘れてはならないという結論に達しました。 問題は、私たちのコードベースが非常に悪い反応をすることです。 レガシーC ++コードの膨大なベースをテストするのは簡単なことではありません。 しかし、私たちはまだそれを単純化することができました。



既存のソリューションを確認した後、それらのどれも私たちにふさわしくないことがわかりました( Typemock製品のようなものを探しましたが、Windowsでのみ動作するため、私たちにはふさわしくありません)。 もちろん、テストのためだけにコード配列全体を書き換えることは無意味でした。 C ++コードレイアウトと互換性のあるソリューションが必要でした。



傍受...



テストの任意の段階で関数をインターセプトし、それらからモックオブジェクト、偽物、またはスタブを作成できると便利であることがわかりました。 関数Yをインターセプトして任意のものに変換できる場合、関数Xが関数Yを直接呼び出すことに満足しています。



次に、コードを修正する必要があると考えました! すべてが、プロファイリングのためのリアルタイムのコード置換の必要性を示していました。 しかし、落とし穴がありました。多くのプラットフォームは、実行時にコードを変更する機能をサポートしていません。



...コンパイル時...



私たちは絶望しませんでした。最終的に、コンパイル時にパッチを適用できます! ここはそれほど単純ではないことがわかりました。 このプロセスは、たとえばブルズアイによって既に正常に実装されています。 ブルズアイの製品はコードカバレッジのテストに使用しています。 しかし、彼はまだ混乱しています。 さまざまなプラットフォームで多くのコンパイラを使用していますが、ビルドはすでに思ったよりも複雑なので、このオプションも拒否する必要がありました。



...マクロを使用する



C ++に常にフォールバック(テンプレートとマクロ)があるのは良いことです。 それで、私は快適になり、いくつかのテンプレートを作成し、マクロで希釈しました。

考え方は非常に単純です。関数のインターセプトのメカニズムに基づいて、テストの目的に応じて関数を変更するフレームワーク全体を構築できます。



ステップ1:インターセプター。







すべてがシンプルです。 デフォルトでは、このコードは何も実行しません(既製のエンジンアセンブリにコンパイルしません)が、テスト中はバタンと動作します。 このプロセスは少し煩わしいですが、ほんの少しです。



次のステップ:テスト中にインターセプターを起動します。







このコードは、偽物がスコープ内にある場合、関数の署名に基づいてインターセプターを検索します。

最後に、インターセプトメカニズム自体を記述できます。







これで、レイアウトを使用した通常の操作に進むことができます。呼び出しを独自の関数にリダイレクトし、引数を受け入れ、値を返し、元の関数の実行を制御します。 このシステムは、クラスメソッドとフリー関数をサポートするだけでなく、クラス全体を置き換えることもできます。







おわりに



このアプローチがどれほど効果的であるかはまだわかりませんが、以前は作成できなかった新しいテストをすでに作成できます。 機能テストを忘れることはありません。独自の高速で包括的かつ詳細なテストのおかげで、Unityエンジンのより安定した動作が保証されることを願っています。



All Articles