Catch
C++用のヘッダーファイルのみで利用できるUnitTestフレームワークのCatchを使ってみました。
ヘッダーファイルは、複数ファイル構成と単一ファイル構成の2種類あります。
-
- Catch
- include
- single_include
- Catch
自分は単一ファイル版を使いました。
#define CATCH_CONFIG_MAIN #include "catch.hpp" #include <cstdio> #include <cstring> TEST_CASE( "TestCase1", "[tag]" ) { REQUIRE( 0 == strcmp( "aaa", "aaa" ) ); }
自前のmain関数利用時
#define CATCH_CONFIG_RUNNER #include "catch.hpp" #include <cstdio> #include <cstring> int main( int argc, char* argv[] ) { return Catch::Session().run( argc, argv ); } TEST_CASE( "TestCase1", "[tag]" ) { REQUIRE( 0 == strcmp( "aaa", "aaa" ) ); }
VC++でUNICODEビルド設定の場合、Catchフレームワークのmain関数を利用するのは不味い気がする。
#define CATCH_CONFIG_RUNNER #include "catch.hpp" #include <cstdio> #include <clocale> #include <cstring> #include <windows.h> void allocate_argv( int argc, _TCHAR * const argv[] ) { #ifdef UNICODE __argv = (char**)malloc( sizeof( char* ) * ( argc + 1 ) ); for ( int i = 0; i < argc; ++i ) { char szAnsi[ 1024 ]; sprintf_s( szAnsi, "%ls", argv[ i ] ); __argv[ i ] = _strdup( szAnsi ); } __argv[ argc ] = NULL; #endif } void deallocate_argv() { #ifdef UNICODE for ( int i = 0; __argv[ i ]; ++i ) { free( __argv[ i ] ); } free( __argv ); __argv = NULL; #endif } int _tmain( int argc, _TCHAR * const argv[] ) { (void)::_tsetlocale( LC_ALL, _T("") ); allocate_argv( argc, argv ); int nResult = Catch::Session().run( argc, __argv ); // 常にANSI版 deallocate_argv(); if ( IsDebuggerPresent() ) { (void)::fgetc( stdin ); // キー入力を待つ } return nResult; } TEST_CASE( "TestCase1", "[tag]" ) { REQUIRE( 0 == strcmp( "aaa", "aaa" ) ); }
テストは簡単に書けるけども、出力結果はあまり良い感じではないので(テスト正常終了時には殆ど何も出力されない)、CIとかと組み合わせるのは向いてないのかもな。