MFC UI アプリケーションの単体テストを行っていますか?
-
01-07-2019 - |
質問
大規模な MFC UI アプリケーションの単体テストはどのように行うのでしょうか?
私たちは長年開発を続けてきた大規模な MFC アプリケーションをいくつか持っており、いくつかの標準的な自動 QA ツールを使用して基本的なスクリプトを実行し、基本事項やファイルのオープンなどをチェックします。これらは、毎日のビルド後に QA グループによって実行されます。
ただし、個々の開発者が毎日のビルドにコードを送信する前に、アプリケーションのダイアログ、メニュー、その他の視覚要素に対してテストを構築して実行できるような手順を導入したいと考えています。
デバッグ ビルドでのみ表示されるダイアログ上の非表示のテスト ボタンなどのテクニックについて聞いたことがありますが、このための標準ツールキットはありますか。
環境はC++/C/FORTRAN、MSVC 2005、Intel FORTRAN 9.1、Windows XP/Vista x86 & x64です。
解決
それはアプリの構造によって異なります。ロジックと GUI コードが分離されている (MVC) 場合、ロジックのテストは簡単です。マイケル・フェザーズを見てみよう 「謙虚なダイアログボックス」 (PDF)。
編集:考えてみると:アプリがそのように構造化されていない場合は、慎重にリファクタリングする必要があります。ロジックをテストするための他の手法はありません。クリックをシミュレートするスクリプトは表面をなぞっただけです。
実際にはとても簡単です:
ユーザーがボタンをクリックしたときにコントロール/ウィンドウなどでリストボックスの内容が変更され、クリック後にリストボックスに正しい内容が含まれていることを確認したいとします。
- リストボックスに表示する項目を含む別のリストが存在するようにリファクタリングします。項目はリストに保存され、データの取得元から抽出されることはありません。リストボックスのリストを作成するコードは、新しいリストについてのみ知っています。
- 次に、ロジック コードを含む新しいコントローラー オブジェクトを作成します。ボタンのクリックを処理するメソッドは、mycontroller->ButtonWasClicked() のみを呼び出します。リストボックスやその他のことについては知りません。
- MyController::ButtonWasClicked() は、目的のロジックに対して実行する必要があることを実行し、項目リストを準備して、コントロールに更新を指示します。これを機能させるには、コントロールのインターフェイス (純粋な仮想クラス) を作成して、コントローラーとコントロールを分離する必要があります。コントローラーはそのタイプのオブジェクトのみを認識し、コントロールは認識しません。
それでおしまい。コントローラーにはロジック コードが含まれており、インターフェイス経由でのみ制御を認識します。これで、コントロールをモックすることで、MyController::ButtonWasClicked() の通常の単体テストを作成できるようになりました。私が何を言っているのかわからない場合は、マイケルズの記事を読んでください。2回。そしてその後また。
(自分の為にメモする:あまり大騒ぎしないように学ばなければなりません)
他のヒント
MFC について言及したため、自動テスト ハーネスに適用するのが難しいアプリケーションがあると思いました。コードを作成しながらテストを構築すると、単体テスト フレームワークの最大の利点がわかります。しかし、テスト可能に設計されていないアプリケーションにテスト駆動の方法で新しい機能を追加しようとしています。大変な作業でイライラすることもあります。
今私が提案しようとしているのは間違いなく 大変な仕事..しかし、ある程度の規律と忍耐力があれば、すぐにその恩恵に気づくでしょう。
- まず、新しい修正を行うにはもう少し時間がかかりますが、管理者の支援が必要になります。全員がその理由を理解できるようにしてください。
- 次にコピーを購入します WELCの本. 。時間があれば最初から最後まで読んでください。または、難しい場合は、索引に目を通し、アプリが示している症状を見つけてください。この本には多くの優れたアドバイスが含まれており、既存のコードをテスト可能にしようとするときに必要なものです。
- 次に、新しい修正や変更が行われるたびに、時間をかけて、これから取り組む領域を理解してください。選択した xUnit バリアント (無料で利用可能) でいくつかのテストを作成し、現在の動作を実行します。
- すべてのテストに合格することを確認してください。必要な動作またはバグを実行する新しいテストを作成します。
- この最後のテストに合格するコードを作成します。
- テスト対象領域内で容赦なくリファクタリングを行い、設計を改善します。
- 今後、システムに新たな変更を加えるたびにこの手順を繰り返します。この規則には例外はありません。
- 今 約束の地:すぐに、十分にテストされたコードが増え続ける島が表面化し始めるでしょう。自動テストスイートに分類されるコードはますます増え、変更は徐々に容易になるでしょう。それは、ゆっくりと確実に、基礎となる設計がテストしやすくなるからです。
簡単な解決策は私の以前の答えでした。これは難しいですが正しい方法です。
これは古い質問であることは承知していますが、今でも MFC を使用している人にとっては、VS2012 の Microsoft C++ 単体テスト フレームワークはうまく機能します。
一般的な手順:
- MFC プロジェクトを静的ライブラリとしてコンパイルします。
- 新しいネイティブ単体テスト プロジェクトをソリューションに追加します。
- テスト プロジェクトで、MFC プロジェクトを参照として追加します。
- テスト プロジェクトの構成プロパティで、ヘッダー ファイルのインクルード ディレクトリを追加します。
- リンカーで、入力オプションにより MFC.lib;nafxcwd.lib;libcmtd.lib; が追加されます。
- 「特定のデフォルト ライブラリを無視する」の下に nafxcwd.lib;libcmtd.lib; を追加します。
- [全般] で、MFC でエクスポートされた lib ファイルの場所を追加します。
の https://stackoverflow.com/questions/1146338/error-lnk2005-new-and-delete-already-define-in-libcmtd-libnew-obj nafxcwd.lib と libcmtd.lib が必要な理由が詳しく説明されています。
レガシー プロジェクトで確認すべきもう 1 つの重要な点。一般構成プロパティで、両方のプロジェクトが同じ「文字セット」を使用していることを確認します。MFC がマルチバイト文字セットを使用している場合は、そのために MS テストも必要になります。
完璧ではありませんが、私がこれに最適なものを見つけたのは AutoIt です http://www.autoitscript.com/autoit3
「AutoIt v3 は、Windows GUI と一般的なスクリプトを自動化するために設計されたフリーウェアの BASIC に似たスクリプト言語です。他の言語 (例:VBScript と SendKeys)。また、AutoIt は非常に小さく、自己完結型であり、煩わしい「ランタイム」を必要とせずに、すぐに使用できる Windows のすべてのバージョンで実行されます。
これは、駆動するアプリケーションのソース コードにアクセスできる場合にうまく機能します。駆動するコントロールのリソース ID 番号を使用できるためです。この方法では、特定のピクセルでのシミュレートされたマウス クリックについて心配する必要はありません。残念ながら、従来のアプリケーションでは、リソース ID が一意ではないことがよくあり、問題が発生する可能性があります。しかし。ID を一意になるように変更して再構築するのは非常に簡単です。
もう 1 つの問題は、タイミングの問題が発生することです。これらに対する実証済みの解決策はありません。私は試行錯誤して使用しましたが、これは明らかに拡張性がありません。問題は、AutoIT スクリプトが次のコマンドを発行するか、正しい応答を確認する前に、テスト アプリケーションがコマンドに応答するまで待機する必要があることです。待ち望んでいる都合の良いイベントを見つけるのが難しい場合があります。
新しいアプリケーションを開発するときは、一貫した方法で「READY」を知らせる必要があると私は考えています。これは人間のユーザーだけでなく、テスト スクリプトにも役立ちます。これはレガシー アプリケーションにとっては課題かもしれませんが、問題のあるポイントに導入し、メンテナンスを続けながら徐々にアプリケーション全体に広げることができるかもしれません。
UI 側は処理できませんが、Boost Test ライブラリを使用して MFC コードの単体テストを行います。コード プロジェクトの開始に関する記事があります。
私たちの職場には、これらの巨大な MFC アプリの 1 つがあります。維持または拡張するのは非常に困難です...今は巨大な泥の塊だが、ムーラをかき集めている。とにかく
- を使用しております 合理的なロボット 煙テストなどを行うため。
ある程度の成功を収めたもう 1 つのアプローチは、製品固有の小さな言語を作成することです。 スクリプトテスト VBScript と一部のコントロール ハンドル スパイマジックを使用します。一般的なアクションをコマンドに変換します。例えばOpenDatabase は、メイン メニュー > ファイル > [開く...] の順にクリックするために必要なスクリプト ブロックを挿入するコマンドになります。次に、このような一連のコマンドである Excel シートを作成します。これらのコマンドはパラメーターも受け取ることができます。FITテストのようなもの。しかし、さらなる仕事。一般的なコマンドのほとんどを特定し、スクリプトを準備したら。新しいテストを作成するために、(CommandID でタグ付けされた) スクリプトを選択してアセンブルします。テストランナーはこれらの Excel シートを解析し、すべての小さなスクリプト ブロックをテスト スクリプトに結合して実行します。
- オープンデータベース「C: ests\MyDB」
- OpenDialog「モデルの追加」
- 追加モデル "M0001"、"MyModel"、2.5、100
- OKを押します
- データベースの保存
HTH
実際、私たちは Rational Team Test、次に Robot を使用してきましたが、Rational との最近の話し合いで、Rational が .NET に重点を置いたネイティブ x64 アプリケーションをサポートする計画がないことが判明したため、自動 QA ツールに切り替えることにしました。これは素晴らしいことですが、ライセンスコストの関係で、すべての開発者に有効にすることはできません。
すべてのアプリケーションはスクリプト用の COM API をサポートしており、VB 経由で回帰テストを行っていますが、これはアプリケーションそのものではなく API をテストします。
理想的には、cppunit や同様の単体テスト フレームワークを開発者レベルでアプリケーションにどのように統合するかに興味があります。