1

アンマネージ C++ に VS2005 VC++ を使用しています。私は VSTS を持っており、コード カバレッジ ツールを使用して単体テストに関して次の 2 つのことを達成しようとしています。

  1. テスト対象の参照コードがどれだけ実行されているかを確認する
  2. テスト対象のコード (存在する場合) のどれだけのメソッドが単体テストされていないかを確認します

VSTS コード カバレッジ ツール (リンク テキストを参照) のセットアップとタスク 1 の実行は簡単でした。しかし、#2は私にとって驚くべき挑戦でした。これが私のテストコードです。

class CodeCoverageTarget
{
public:
    std::string ThisMethodRuns() {
         return "Running";
    }

    std::string ThisMethodDoesNotRun() {
        return "Not Running";
    }
};



#include <iostream>
#include "CodeCoverageTarget.h"
using namespace std;
int main()

{
    CodeCoverageTarget cct; 
    cout<<cct.ThisMethodRuns()<<endl;
}

上記のように両方のメソッドがクラス内で定義されている場合、コンパイラは obj ファイルから ThisMethodDoesNotRun() を自動的に削除します。その定義をクラスの外に移動すると、それは obj ファイルに含まれ、コード カバレッジ ツールはそれがまったく実行されていないことを示します。ほとんどの状況では、コンパイラーにこの除去を行ってもらいたいのですが、コード・カバレッジ・ツールの場合、値のかなりの部分が無効になります (テストされていないメソッドの検出など)。私はコンパイラに私にとって賢くするのをやめてすべてをコンパイルするように指示するために多くのことを試みましたが、私は困惑しています. コード カバレッジ ツールがこれを補正してくれるといいのですが (ソースをスキャンしてリンカーの出力と照合することで可能だと思います)、有効にする特別なモードがあることを示唆するものは何も見つかりませんでした。

よろしくお願いします、KGB

4

5 に答える 5

1

関数が破棄されないようにする1つの方法は、関数をエクスポートすることです。__declspec(dllexport)これを行うには、関数宣言に追加します。これはコンパイラ固有であり、すべてのビルドでシンボルをエクスポートしたくない場合があるため、これをオフにできるようにCプリプロセッサマクロでラップすることをお勧めします。関数をエクスポートする別の方法は、.DEFファイルを作成することです。

インライン化が問題である場合は、で成功する可能性もあります__declspec(noinline)

コードは静的ライブラリにあり、テストEXE / DLLにコンパイルされていますか?リンカは、静的ライブラリにある参照されていないオブジェクトファイルを自動的に破棄します。例:静的ライブラリにa.objandb.objと、それを参照シンボルにリンクしているEXE / DLLが含まれているb.objが、ではないa.obj場合、のコンテンツはa.obj実行可能ファイルまたはDLLにリンクされません。ただし、説明を読み直した後は、ここで起こっていることのようには聞こえません。

于 2008-09-20T06:51:29.910 に答える
1

ある条件が true の場合にのみ関数を呼び出すコード行を追加して、その条件が決して true にならないことを保証することができます。コンパイラがそれを理解できないことを確認してください。例えば、


int main(int argc, char **argv)
{
  if(argv == NULL)  // C runtime says this won't happen
    someMethodWhichIsntReallyEverCalled();
}
于 2008-09-19T20:22:20.983 に答える
0

申し訳ありませんが、インライン化とすべての最適化をオフにしてデバッグモードを構築していることを明確にする必要があります。さらに、コードはインライン化の対象となることすら参照されていないため、インライン化が発生する前にコードが削除されます。

于 2008-09-19T20:05:02.883 に答える
0

もう1つのオプションは、次のように.inlファイルを使用して、ビルドに基づいてインライン関数と非インライン関数を切り替えることです。

foo.inlファイル内:

inline std::string Foo::ThisMethodDoesNotRun()
{
    return "Not Running";
}

foo.hで:

#if !COVERAGE_BUILD
#include "foo.inl"
#endif

foo.cpp:

#if COVERAGE_BUILD
#define inline
#include "foo.inl"
#endif
于 2008-09-19T20:43:18.377 に答える
0

関数のインライン化をオフにします。これを行う最も簡単な方法は、デバッグ モードでコンパイルすることです。

編集:あなたの説明を見た後、私の答えが間違っていることがわかりました。おそらく、「インライン」キーワードを使用して、関数の本体を .h ファイルの別のセクションに移動した場合はどうでしょうか。

于 2008-09-19T19:52:26.703 に答える