これまで、即席の単体テスト手順を使用してきました。基本的には、バッチ ファイルによって自動的に実行される単体テスト プログラムの全負荷です。これらの多くは結果を明示的にチェックしますが、より多くの不正行為があります - バージョン管理されたテキスト ファイルに結果をダンプします。テスト結果の変更は、Subversion によってフラグが付けられ、変更内容を簡単に特定できます。テストの多くは、出力を視覚的に表現できるように、ドット ファイルまたはその他の形式で出力します。
問題は、cmake の使用に切り替えていることです。cmake フローを使用するということは、アウト オブ ソース ビルドを使用することを意味します。つまり、結果を共有ソース/ビルド フォルダーにダンプし、それらをソースと一緒にバージョン管理するという利便性は実際には機能しません。
代わりに、期待される結果のファイル (ソース ツリー内) を見つける場所を単体テスト ツールに指示し、比較を行うようにします。失敗した場合は、実際の結果と差分リストを提供する必要があります。
これは可能ですか、それともまったく別のアプローチを取る必要がありますか?
明らかに、ctest を無視して、私が常に行ってきたことをアウト オブ ソース ビルドに適応させることができます。たとえば、すべてのビルドがライブであるフォルダーをバージョン管理できます (もちろん、「無視」を自由に使用して)。それは正気ですか?おそらくそうではありません。ビルドごとに、期待される結果の個別のコピーが作成されるためです。
また、cmake/ctest を使用して単体テストを行うための推奨される方法についてのアドバイスもありがたく受け取りました。cmake が悪いからではなく、cmake の最適な操作方法を理解していなかったために、cmake でかなりの時間を無駄にしました。
編集
最終的に、単体テストの cmake/ctest 側をできるだけシンプルに保つことにしました。期待される結果に対して実際の結果をテストするために、ライブラリで次の関数のホームを見つけました...
bool Check_Results (std::ostream &p_Stream ,
const char *p_Title ,
const char **p_Expected,
const std::ostringstream &p_Actual )
{
std::ostringstream l_Expected_Stream;
while (*p_Expected != 0)
{
l_Expected_Stream << (*p_Expected) << std::endl;
p_Expected++;
}
std::string l_Expected (l_Expected_Stream.str ());
std::string l_Actual (p_Actual.str ());
bool l_Pass = (l_Actual == l_Expected);
p_Stream << "Test: " << p_Title << " : ";
if (l_Pass)
{
p_Stream << "Pass" << std::endl;
}
else
{
p_Stream << "*** FAIL ***" << std::endl;
p_Stream << "===============================================================================" << std::endl;
p_Stream << "Expected Results For: " << p_Title << std::endl;
p_Stream << "-------------------------------------------------------------------------------" << std::endl;
p_Stream << l_Expected;
p_Stream << "===============================================================================" << std::endl;
p_Stream << "Actual Results For: " << p_Title << std::endl;
p_Stream << "-------------------------------------------------------------------------------" << std::endl;
p_Stream << l_Actual;
p_Stream << "===============================================================================" << std::endl;
}
return l_Pass;
}
典型的な単体テストは次のようになります...
bool Test0001 ()
{
std::ostringstream l_Actual;
const char* l_Expected [] =
{
"Some",
"Expected",
"Results",
0
};
l_Actual << "Some" << std::endl
<< "Actual" << std::endl
<< "Results" << std::endl;
return Check_Results (std::cout, "0001 - not a sane test", l_Expected, l_Actual);
}
再利用可能なデータ ダンプ関数が必要な場合は、 type のパラメーターを使用するstd::ostream&
ため、実際の結果ストリームにダンプできます。