桜、抹茶、白、日記

名古屋市在住のC++使いのcoderの日記だったもの。

Catch

C++用のヘッダーファイルのみで利用できるUnitTestフレームワークのCatchを使ってみました。

Catch
https://github.com/philsquared/Catch


ヘッダーファイルは、複数ファイル構成と単一ファイル構成の2種類あります。

    • Catch
      • include
      • single_include

自分は単一ファイル版を使いました。

#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とかと組み合わせるのは向いてないのかもな。