Catch使用マニュアル
9219 ワード
キャッチを取得
Catchを取得する最も簡単な方法は、最新のシングルヘッダファイルバージョンをダウンロードすることです.このファイルは、個別のヘッダファイルのセットをマージすることによって生成されますが、通常のソースコードを含むヘッダファイルにすぎません.Catchの完全なソースコードは、テスト項目、ドキュメント、その他の内容を含め、GitHubが管理しています.http://catch-lib.netリダイレクトします.
どこに置きますか.
Catchにはヘッダファイルが1つしか必要ありません.必要なのは、指定したサードパーティ製ライブラリの場所にファイルを配置し、ヘッダーファイル検索パス(VS下のC++ディレクトリ->ディレクトリを含む)で検索するか、プロジェクト内でディレクトリツリーを介して直接配置するか、プロジェクトにファイルを含めることです.Catchのテストキットを使用したい他のオープンソースプロジェクトにとって、これは特に良い選択です.詳細については、ブログエントリを参照してください.このチュートリアルの残りの部分では、単一ヘッダファイルのCatchを直接使用します.もちろん、フォルダに置いて使用することもできます.
テストケースの作成
簡単な例でCatchの使い方を説明します.階乗を計算する方法を書く必要があるとしたら、それをテストします(まずテスト駆動開発の問題を気にしないでください).
簡単にするために、すべてのコードを同じファイルに書きます(テストファイルをどのように組織するかについては、
Let's add that to the test case:コマンドラインパラメータに応答する完全な実行可能ファイルにコンパイルされます.パラメータなしで実行すると、すべてのテスト・インスタンスが実行され、失敗が報告され、テストの合格と失敗の要約が報告され、失敗したテストの数が返されます.(どのようにあなたが望んでいるのは、「コードが正常に機能するかどうか」という答えだけです).
上記のテスト・インスタンスを実行すると、合格します.すべてがうまくいっています.そうですか.しかし、ここにバグがあります.問題はゼロの乗算とは何ですか.ゼロの乗算については、ここをクリックしてテスト・インスタンスを補足します.
次のような失敗のヒントが得られます.
印刷されたFactorial(0)の戻り値が0で、自然な==式が使用されていることがわかります.問題がどこにあるかを直感的に見るのに役立ちます.factorial関数のコードを変更します.
すべてのテストに合格しました.もちろん、私たちができることはたくさんあります.例えば、unsigned intの値範囲を超えた値を返すと、私たちは問題に直面します.関数factorialsはこのようなことが起こりやすいです.このような状況のためにテストを増やし、どのように処理するかを決定する可能性があります.ここでは、このような問題を処理しません.
ここで私たちは何をしましたか?
これは簡単なテストですが、どのようにCatchするかを理解するのに十分です.続ける前に、時間をかけて振り返ってみましょう.私たちがしなければならないのは ここでは、 テストケース名およびラベルは、通常の文字列にすぎません.これまでメソッドまたは関数を宣言したり、テストケースを任意の場所に明示的に登録したりしていません.バックグラウンドでは、テストケース名によって関数を定義し、静的レジストリクラスを使用して自動的に登録します.関数名を抽出することで、テストケースの名前を付けることができます.識別子名の制約を受けません. マクロは、 テストケースとセクション
ほとんどのテストフレームワークには、クラスベースのスイート・メカニズムがあります.つまり、テスト・インスタンスはクラスにマッピングされ、初期化および破棄は
We might want to verify that attempting to reserve a capacity smaller than the current capacity of the vector changes nothing.We can do that,naturally,like so:各
BDDスタイル
テスト・インスタンスとセクションの名前を適切に付けた場合は、BDDスタイルの仕様構造を実装できます.これは、Catchが適切なサポートを追加した有用な動作となります.シーンでは、指定した
これらのテストは、実行時に次のように報告されます.
さらに
チュートリアルを簡略化するために、すべてのコードを1つのファイルに配置します.これによって開始するのは良いです.Catchにもっと速く、簡単に入ることができます.しかし、実際の世界のテストをもっと書くと、これは本当に最善の方法ではありません.このようなコードブロック(または等価物)を書きます.
ちょうど1つのソースファイルに表示されます.可能な限り多くの追加のcppファイル(インプリメンテーションファイルとも呼ばれます)を使用してテストを行います.ある意味、お客様の作業に最適です.これらのcppファイルは
次のステップ
これは簡単な説明です.Catchを実行し始め、Catchとおなじみの他のフレームワークの主な違いを指摘します.これにより、遠くまで行くことができます.テストを深く理解し、書くことができます.もちろん、もっと勉強する必要があります.参考部分を参照して、使用可能な内容を理解してください.
Catch公式サイト
Catchを取得する最も簡単な方法は、最新のシングルヘッダファイルバージョンをダウンロードすることです.このファイルは、個別のヘッダファイルのセットをマージすることによって生成されますが、通常のソースコードを含むヘッダファイルにすぎません.Catchの完全なソースコードは、テスト項目、ドキュメント、その他の内容を含め、GitHubが管理しています.http://catch-lib.netリダイレクトします.
どこに置きますか.
Catchにはヘッダファイルが1つしか必要ありません.必要なのは、指定したサードパーティ製ライブラリの場所にファイルを配置し、ヘッダーファイル検索パス(VS下のC++ディレクトリ->ディレクトリを含む)で検索するか、プロジェクト内でディレクトリツリーを介して直接配置するか、プロジェクトにファイルを含めることです.Catchのテストキットを使用したい他のオープンソースプロジェクトにとって、これは特に良い選択です.詳細については、ブログエントリを参照してください.このチュートリアルの残りの部分では、単一ヘッダファイルのCatchを直接使用します.もちろん、フォルダに置いて使用することもできます.
テストケースの作成
簡単な例でCatchの使い方を説明します.階乗を計算する方法を書く必要があるとしたら、それをテストします(まずテスト駆動開発の問題を気にしないでください).
unsigned int Factorial( unsigned int number ) {
return number <= 1 ? number : Factorial(number-1)*number;
}
簡単にするために、すべてのコードを同じファイルに書きます(テストファイルをどのように組織するかについては、
)#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
unsigned int Factorial( unsigned int number ) {
return number <= 1 ? number : Factorial(number-1)*number;
}
TEST_CASE( "Factorials are computed", "[factorial]" ) {
REQUIRE( Factorial(1) == 1 );
REQUIRE( Factorial(2) == 2 );
REQUIRE( Factorial(3) == 6 );
REQUIRE( Factorial(10) == 3628800 );
}
Let's add that to the test case:コマンドラインパラメータに応答する完全な実行可能ファイルにコンパイルされます.パラメータなしで実行すると、すべてのテスト・インスタンスが実行され、失敗が報告され、テストの合格と失敗の要約が報告され、失敗したテストの数が返されます.(どのようにあなたが望んでいるのは、「コードが正常に機能するかどうか」という答えだけです).
上記のテスト・インスタンスを実行すると、合格します.すべてがうまくいっています.そうですか.しかし、ここにバグがあります.問題はゼロの乗算とは何ですか.ゼロの乗算については、ここをクリックしてテスト・インスタンスを補足します.
TEST_CASE( "Factorials are computed", "[factorial]" ) {
REQUIRE( Factorial(0) == 1 );
REQUIRE( Factorial(1) == 1 );
REQUIRE( Factorial(2) == 2 );
REQUIRE( Factorial(3) == 6 );
REQUIRE( Factorial(10) == 3628800 );
}
次のような失敗のヒントが得られます.
Example.cpp:9: FAILED:
REQUIRE( Factorial(0) == 1 )
with expansion:
0 == 1
印刷されたFactorial(0)の戻り値が0で、自然な==式が使用されていることがわかります.問題がどこにあるかを直感的に見るのに役立ちます.factorial関数のコードを変更します.
unsigned int Factorial( unsigned int number ) {
return number > 1 ? Factorial(number-1)*number : 1;
}
すべてのテストに合格しました.もちろん、私たちができることはたくさんあります.例えば、unsigned intの値範囲を超えた値を返すと、私たちは問題に直面します.関数factorialsはこのようなことが起こりやすいです.このような状況のためにテストを増やし、どのように処理するかを決定する可能性があります.ここでは、このような問題を処理しません.
ここで私たちは何をしましたか?
これは簡単なテストですが、どのようにCatchするかを理解するのに十分です.続ける前に、時間をかけて振り返ってみましょう.
#define
1つの識別が#include
1つのヘッダファイルに合致し、それから私たちはすべてを持っていて、main
の実現さえコマンドラインパラメータに応答することによって完成します.あなたは1つのcppファイルの中で#define
しかできません.明らかな原因(翻訳速度)のためです.ユニットテストが必要なファイルが1つ以上ある場合は、各測定対象ファイルに#include "catch.hpp"
が必要です.通常、専用のcppファイルに#define CATCH_CONFIG_MAIN
と#include "catch.hpp"
が必要です.もちろん、自分のmain関数を実装し、自分で実行するCatchの機能も提供できます.(詳細は、自分のmain
関数を提供します).TEST_CASE
マクロを使用してテストの例を説明します.このマクロには、任意の文字列と1つ以上のラベル(詳細は、Test cases and Sectionsを参照)の1つまたは2つのパラメータがあります.を選択します.テスト・インスタンスの名前は一意でなければなりません.ワイルドカードを指定してテスト・インスタンス名またはラベル式を識別することで、指定したテスト・インスタンスを実行できます.テスト・インスタンスの実行の詳細については、コマンド・ライン・ドキュメントを参照してください.REQUIRE
マクロによって個別のテストブレークスルーを記述します.各条件に対して個別のマクロを定義するのではなく、自然なC/C++の意味を使用して条件を表現します.バックグラウンドでは、単純な表現テンプレートのセットが式の左側と右側をキャプチャし、テストレポートに値を表示できます.後で他のブレークスルーマクロが表示されますが、このため技術、それらの数量は急激に減少します.ほとんどのテストフレームワークには、クラスベースのスイート・メカニズムがあります.つまり、テスト・インスタンスはクラスにマッピングされ、初期化および破棄は
setup()
メソッドおよびteardown()
メソッドで実行されます(C++などの言語では構造/プロファイルと呼ばれます)..Catchはこの動作を完全にサポートしていますが、いくつかの問題があります.特に、コードを分割する必要があり、その細粒度が問題になる可能性があります.一連の方法では、1対のsetup
/teardown
/setup
しか使用できませんが、各関数でわずかに異なるNUnit
を設定するか、複数のレベルの設定が必要になる場合があります.(このチュートリアルでは後述する).James Newkirkがチームを率いてNUnit
を内蔵し、xUnitを最初から構築する.Catchは異なる方法(xUnit
およびSECTION
)を採用しており、これはC++およびCシリーズの言語にとってより自然である.一例で完璧に解釈する:TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
std::vector v( 5 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
SECTION( "resizing bigger changes size and capacity" ) {
v.resize( 10 );
REQUIRE( v.size() == 10 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "resizing smaller changes size but not capacity" ) {
v.resize( 0 );
REQUIRE( v.size() == 0 );
REQUIRE( v.capacity() >= 5 );
}
SECTION( "reserving bigger changes capacity but not size" ) {
v.reserve( 10 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
}
SECTION( "reserving smaller does not change size or capacity" ) {
v.reserve( 0 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
}
}
We might want to verify that attempting to reserve a capacity smaller than the current capacity of the vector changes nothing.We can do that,naturally,like so:各
TEST_CASE
および各section
について最初から実行されています.したがって、各SECTION
に入ると、サイズは5であり、容量は少なくとも5であることがわかります.これは正常に動作します.マクロsection
にはif文が含まれているため、TEST_CASE
を実行すべきかどうかを確認するためにCatchがコールバックされます(部分)を選択します.スタックを作成しました.しかし、一連の検査操作を実行する必要がある場合にのみ、section
の実力が実際に表示されます.section
の例を続行すると、section
の容量が現在の容量より小さい場合、無効であることを検証したい場合があります.たとえば、次のようにします. SECTION( "reserving bigger changes capacity but not size" ) {
v.reserve( 10 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
SECTION( "reserving smaller again does not change capacity" ) {
v.reserve( 7 );
REQUIRE( v.capacity() >= 10 );
}
}
setup
は任意の深さ(スタックサイズのみ)にネストすることができる.各リーフteardown
(すなわち、ネストsetup
を含まないsection
)は、他のブレード部分を実行するための別のパス上で1回実行される(したがって、ブレード部分は他のリーフノードに干渉する可能性がある).親vector
の失敗は、ネストvector
の実行を阻止するように設計されている.BDDスタイル
テスト・インスタンスとセクションの名前を適切に付けた場合は、BDDスタイルの仕様構造を実装できます.これは、Catchが適切なサポートを追加した有用な動作となります.シーンでは、指定した
Sections
,section
,section
,section
およびsection
マクロを使用して、section
およびSCENARIO
にマッピングできます.詳細は、Test cases and sectを参照してください.ions.GIVEN
例は、以下に示すように、これらのマクロを使用するように調整することができる.SCENARIO( "vectors can be sized and resized", "[vector]" ) {
GIVEN( "A vector with some items" ) {
std::vector v( 5 );
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
WHEN( "the size is increased" ) {
v.resize( 10 );
THEN( "the size and capacity change" ) {
REQUIRE( v.size() == 10 );
REQUIRE( v.capacity() >= 10 );
}
}
WHEN( "the size is reduced" ) {
v.resize( 0 );
THEN( "the size changes but not capacity" ) {
REQUIRE( v.size() == 0 );
REQUIRE( v.capacity() >= 5 );
}
}
WHEN( "more capacity is reserved" ) {
v.reserve( 10 );
THEN( "the capacity changes but not the size" ) {
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 10 );
}
}
WHEN( "less capacity is reserved" ) {
v.reserve( 0 );
THEN( "neither size nor capacity are changed" ) {
REQUIRE( v.size() == 5 );
REQUIRE( v.capacity() >= 5 );
}
}
}
}
これらのテストは、実行時に次のように報告されます.
Scenario: vectors can be sized and resized
Given: A vector with some items
When: more capacity is reserved
Then: the capacity changes but not the size
さらに
チュートリアルを簡略化するために、すべてのコードを1つのファイルに配置します.これによって開始するのは良いです.Catchにもっと速く、簡単に入ることができます.しかし、実際の世界のテストをもっと書くと、これは本当に最善の方法ではありません.このようなコードブロック(または等価物)を書きます.
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
ちょうど1つのソースファイルに表示されます.可能な限り多くの追加のcppファイル(インプリメンテーションファイルとも呼ばれます)を使用してテストを行います.ある意味、お客様の作業に最適です.これらのcppファイルは
WHEN
-繰り返しTHEN
|を必要としません.実際には、指定したソースファイルにTEST_CASES
を配置します.(このファイルにはSECTION
とvector
の2つのコードしか含まれていません)通常は良いアイデアです.ヘッダーファイルにテストを書かないでください.次のステップ
これは簡単な説明です.Catchを実行し始め、Catchとおなじみの他のフレームワークの主な違いを指摘します.これにより、遠くまで行くことができます.テストを深く理解し、書くことができます.もちろん、もっと勉強する必要があります.参考部分を参照して、使用可能な内容を理解してください.
Catch公式サイト