私はC++を使用しており、gtestをメインフレームワークとして使用しています。画像を入力として受け取り、エッジ検出された画像を返す、エッジ検出機能があるとしましょう。チェックできる画像が3つあります。
次のように自己完結型で書く方が良いですか
void EdgeCheck(const std::string& input, const std::string& ans) {
cv::Mat in_img = cv::imread(input);
cv::Mat ans_img = cv::imread(ans);
// Do some checks here
}
TEST(Edge) {
EdgeCheck(std::string("path to image 1"),std::string("path to ans image 1"));
EdgeCheck(std::string("path to image 2"),std::string("path to ans image 2"));
EdgeCheck(std::string("path to image 3"),std::string("path to ans image 3"));
}
int main(int argc, char** argv) {
return UnitTest::RunAllTests();
}
したがって、テストは単純な./unit-test
または次のように書く方が良いですか
TEST(Edge) {
cv::Mat in_img = cv::imread(argv[1]);
cv::Mat ans_img = cv::imread(argv[2]);
// Do some check here
}
int main(int argc, char** argv) {
return UnitTest::RunAllTests();
}
しかしそれはによって実行されなければなりません
./unit-test image1 ans_image1
./unit-test image2 ans_image2
./unit-test image3 ans_image3
私の理解から、 nitTest ++コマンドライン引数 による最初のアプローチの利点は、「適切に記述された単体テストは自己完結型であり、テストをパラメーター化すると、テストは単なるテストではなくなります。これは単体テストではなく関数になりました。」
ただし、2番目のアプローチの利点は、image4とimage5を追加する場合にコードを再コンパイルする必要がなく、bashスクリプトで実行できるという点で、柔軟性が高いことです。自己完結型ではありません。
どのアプローチがより良い実践と考えられていますか?
これは、テストを管理して環境全体に統合する方法についてのすべてです。私はあなたがする必要があると思います
2つのソリューションの両方を見ると、コマンドラインでパラメーター化することで、それらを個別に実行する場合と「一度にすべて」を実行する場合の切り替えの柔軟性が向上し、失敗したテストが他のテストに影響を与えないことを確認しやすくなります。テスト。必要に応じて、それらをより大きなテストスイートに統合する方が簡単かもしれません。ただし、この柔軟性は無料ではありません。パラメータを知る必要があるので、コマンドラインプログラムは、間違った方法で呼び出された場合、どの種類のパラメータが期待されるかを説明するメッセージを提供し、テスト実行スクリプトはテストの不可欠な部分である必要があります。
したがって、スクリプトと一緒にコマンドラインプログラムを自己完結型コンポーネントとして扱い、統合されたドキュメントを提供する限り、パラメータ化されたアプローチに問題はありません。何らかの不思議な理由でそれが「自己完結型」ではない場合は、1つのプログラムに統合しますが、私が述べた他の要件を解決するにはさらに努力が必要かもしれないという事実を受け入れてください。
自動テストは、渡されたパラメーターに依存せずにパラメーター化できます。多くの場合、ハイブリッドアプローチが最も役立ちます。
たとえば、コマンドライン引数なしで実行すると、テストは構成されたディレクトリをスキャンして、そのディレクトリ内のすべてのイメージを反復処理する場合があります。
この場合、ディレクトリを上書きできると便利な場合があります。そのための一般的な方法は、コマンドラインパラメータを指定するか、環境変数を指定することです。または、ユーザーはデフォルトのディレクトリに追加の画像を配置して、テストを拡張することもできます。
適切に作成された単体テストは自己完結型であり、テストをパラメーター化すると、テストは単なるテストではなくなります。単体テストではなく関数になりました
@Dymengはあなたがテストしているのはおそらく実際にはユニットテストではなく統合テストであることは正しいですが、それは本当に重要ではありません。単体テストはパラメーター化できるため、統合テストも可能です。
自己完結型であるという点は重要です。コマンドライン引数を指定せずにプロジェクトでテストを実行できるはずです。テストを実行したい人がいる場合、テストを実行するための正しいパラメータを知るには特別な知識が必要になるためです。しかし、その事実は、他のデータセットでテストを実行する方法を公開することを妨げるべきではありません。
申し訳ありませんが、これは今日聞いた最悪の考えです。いくつかの理由があります。
実際にデータを(変数に)テストし、(可能であれば)ファイルからロードしない場合は、単体テストに最適です。
Roy Osheroveによる The Art of Unit Testing によると、彼はユニットテストの次の特性を述べています。
1.2。優れた単体テストの特性
単体テストには次のプロパティが必要です。
- それは自動化され、再現可能でなければなりません。
- 実装は簡単です。
- いったん作成したら、将来の使用のために残しておく必要があります。
- 誰でも実行できるはずです。
- ボタンを押すだけで実行されます。
- すぐに実行されるはずです。
コマンドライン引数を使用することで、テストを繰り返したり自動化したりすることができなくなります。あなたのコンピューターに行き、「テストの実行」を押して実行してもらえますか?答えは単にノーです。
これらの画像を使用してテストする別の方法を見つけることをお勧めします。多分それらはあなたのプロジェクトの一部であり、相対パスをハードコードしていますか?