ですから、私は、まだユニットテストが行われていない非常に大規模なプロジェクト(シャダー!)に参加しているので、それを紹介したいと思います。
Google TestとGoogleモックを使用する予定です。
コードは大きく、扱いにくく、「ヘッダースパゲッティ」の影響を受けます。
簡単にするために、b.cppで単一の関数のみを呼び出すa.cppのみをテストする場合は、Google Mockを使用してb.cppのモックを生成できます。
ただし、b.hをa.cppとテストスイートに#includeした場合、b.hは他の多くのヘッダーを#includeし、結局...何百ものヘッダーを#includeしていることがわかります。
ヘッダーファイルの再構築はありません(いつでも、いつでも)。私はそれと一緒に暮らす必要があります。
これまで、コードは、ARMプロセッサ用の完全なシステムとしてのみ構築されていました。今は、a.cppとb.cppに加えて、Linuxで実行するGoogleテストを構築したいと考えています。
システムビルドに数百(!)のコンパイラスイッチがあり、ARMのみ、どこでそれらを置き換えるのか、どこに必要かを簡単に確認できないため、私は大きな問題を抱えています。 Linuxなど.
さらに、それらの一部には、関数呼び出し(特にトレースログからだけでなく他のもの)に展開される#definesが含まれており、それらをモックするためにそれらを見つける場所がわかりません。
最後に質問:これは通常どのように処理されますか? a.cppで必要なものだけを含むb.hのモックを作成する必要がありますか?
その場合、手動で行う必要がありますか、それともGoogle Mockは何らかの方法で支援できますか?
そして、いや、コードは再構築されません。それを不安定にする恐れのため、少なくともすぐには。
システムの大部分のヘッダーを取り込むという考えは本当に好きではありませんが、それらをモックする簡単な方法を見つけることもできません:-(
レガシーシステム(単体テストなし)で作業しているので、コードを変更してリファクタリングしないと、それはかなり難しくなります。
モックの最適な使用方法は、依存関係の注入です。実際のクラスの代わりにモックオブジェクトを注入します。そしてnotは、異なるオブジェクトファイルをリンクすることで依存関係を注入します(何をしようとしているのか)。
開始するための最良の方法は、モックを使用せずにユニットテストできるものを見つけることです。次に、リファクタリングの時間があるときに、クラスを調整して依存関係を注入し、モックを使用します。
あなたが直面する問題は、選択した単体テストのスタイルであり、単一のファイルの外側にあるすべてのものはモックされますisそれと互換性があるように書かれていないコードベースをテストするとき、実際には役に立ちません。
あなたの選択肢は:
後者の意味は次のとおりです。
言い換えれば、レガシー組み込みシステムの場合、高水準言語で得られる意味でのユニットテストなどはありません。単にコンパイラーと常に統合しているからです。そして、そのコンパイラーは通常、抽象化ではなく、使用する正確なコードを実際にテストする必要がある、バグ、回避策、および文書化されていない制限の大雑把な混乱です。