GoogleTestフレームワーク初認識


文書ディレクトリ
  • 1. プロジェクトダウンロードおよびコンパイル
  • 2. 初識GoogleTestフレームワーク
  • 3. printf出力カラー文字
  • 4. 前処理コマンド
  • 4.1前処理コマンド--マクロ定義
  • 4.2前処理コマンド--条件付きコンパイル
  • 5. GoogleTestフレームワーク部分機能の実現
  • 1.プロジェクトのダウンロードとコンパイル
    GitHubからローカルにプロジェクトをクローン
    $ git clone https://github.com/google/googletest.git
    

    プロジェクトフォルダにアクセスしてコンパイル
    $ cd googletest
    $ mkdir build
    $ cd build
    $ cmake ../
    $ make
    

    上記のコマンドを実行した後、プロジェクトフォルダの./build/パスの下にlibフォルダがあり、./Googletestフォルダにはincludeフォルダがあり、この2つのフォルダを同じ新しいフォルダに入れます.
    $ cp -R         (           )
    

    2.GoogleTestフレームワーク
    加算を例にgoogletestでテストします
    #include 
    #include 
    
    int add(int a, int b) {
        return a + b;
    }
    
    TEST(test, add1) {
        EXPECT_EQ(add(3, 4), 7);//== 
        EXPECT_NE(add(3, 4), 6);//!= 
        EXPECT_LT(add(3, 4), 8);//< 
        EXPECT_LE(add(3, 4), 7);//<=
        EXPECT_GT(add(3, 4), 6);//>
        EXPECT_GE(add(3, 4), 7);//>=
    }
    
    TEST(test, add2) {
        EXPECT_EQ(add(3, 4), 7);//== 
        EXPECT_NE(add(3, 4), 7);//!= 
        EXPECT_LT(add(3, 4), 8);//< 
        EXPECT_LE(add(3, 4), 7);//<=
        EXPECT_GT(add(3, 4), 6);//>
        EXPECT_GE(add(3, 4), 7);//>=
    }
    int main() {
        printf("add(3 + 4) = %d
    ", add(3, 4)); testing::InitGoogleTest(); return RUN_ALL_TESTS(); }

    リンクのコンパイル
    $ g++ -std=c++11 -I./include -L./lib add.cpp -lgtest
    

    うんてん
    $ ./a.out
    

    3.printf出力色文字
    属性コード
    \033[ A1; A2; A3; ...An m
    

    部分フォーマットコード
    ユニバーサルフォーマットせいぎょ
    機能
    前景色
    機能
    背景色
    機能
    0
    すべてのプロパティをリセット
    30

    40

    1
    ハイライト/太字
    31

    41

    2
    くすんだ
    32

    42

    4
    下線
    33
    黄色
    43
    黄色
    5
    きらめき
    34

    44

    7
    反転
    35
    マゼンタ
    45
    マゼンタ
    8
    非表示
    36

    46

    カラーフォーマット制御の例
    printf("\033[0;1;33;41mHelloWorld!\033[0m
    ");

    色フォーマット制御は、他のコードに設定された属性干渉を防止するとともに、設定された属性が後続のコードに干渉しないように、前後にリセット処理を行う必要があります.
    4.前処理コマンド
    4.1前処理コマンド–マクロ定義
    サンプル
    //      
    #define PI 3.1415926
    #define MAX_N 10000
    
    //       
    #define MAX(a, b) (a) > (b) ? (a) : (b)
    #define S(a, b) a * b
    
    //     
    #define P(a) { \
    	 printf("%d
    ", a); \ }

    マクロ:単純置換
    コード機能を決定するのはソースコードではなく,前処理後のコンパイル対象ソースコードである.
    コンパイル対象ソース
    コンパイル対象ソースの表示(>output.cpp前処理結果をoutput.cppに出力)
    $ g++ -E xxx.cpp > output.cpp
    

    単純置換を深く理解する
    #define S(a, b) a * b
    
    int n;
    S(int, p) = &n; //   int * p = &n;
    S(1 + 2, 3); //   1 + 2 * 3
    

    内蔵マクロ
    マクロ#マクロ#
    説明
    __DATA__
    日付:Mmm dd yyyyy
    __TIME__
    時間:hh:mm:ss
    __LINE__
    行番号
    __FILE__
    ファイル名
    __func__
    関数名/非標準
    __FUNC__
    関数名/非標準
    __PRETTY_FUNCTION__
    より詳細な関数情報/非標準
    非標準マクロ表示は、使用する環境が必ずしも適用されるとは限らない
    LOGログ情報実装
    #define LOG(frm, args...) { \
    		printf("[%s : %d : %s]", __FILE__, __LINE__, __func__); \
    		printf(frm, ##args); \
    		printf("
    "); \ } LOG("HelloWorld!");

    ##argsをfrmに接着し、後のパラメータを空にする
    4.2前処理コマンド–条件付きコンパイル
    条件付きコンパイル:単純なコードクリップ
    関数#カンスウ#
    説明
    #ifdef DEBUG
    DEBUGマクロが定義されているかどうか
    #ifndef DEBUG
    DEBUGマクロが定義されていないか
    #if MAX_N == 5
    マクロMAX_Nが5に等しいか
    #elif MAX_N ==4
    マクロMAX_Nが4に等しいか
    #else
    #endif
    LOGデバッグ情報の出力を制御するか
    #ifdef DEBUG
    
    #define LOG(frm, args...) { \
    		printf("[%s : %d : %s]", __FILE__, __LINE__, __func__); \
    		printf(frm, ##args); \
    		printf("
    "); \ } #else #define LOG(frm, args...) #endif LOG("HelloWorld!");

    LOGを開く必要がある場合は、ifdefの前に#define DEBUGを付ければよいか、コンパイル時にパラメータ-DEBUGを追加して開く
    5.GoogleTestフレームワーク部分機能の実現
    EXPECTパッケージを実現
    #define EXPECT(a, comp, b) { \
    		if (!(a) comp (b)) { \
          printf("error
    "); \ } \ } #define EXPECT_EQ(a, b) EXPECT(a, ==, b) #define EXPECT_NE(a, b) EXPECT(a, !=, b) #define EXPECT_LT(a, b) EXPECT(a, , b) #define EXPECT_GE(a, b) EXPECT(a, >=, b)

    COLORシリーズパッケージを実現
    #define COLOR(msg, code) "\033[0;1;" #code "m" msg "\033[0m"
    
    #define RED(msg) COLOR(msg, 31)
    #define GREEN(msg) COLOR(msg, 32)
    #define YELLOW(msg) COLOR(msg, 33)
    #define BLUE(msg) COLOR(msg, 34)
    

    その他の色は同じです
    使用__attribute__関数登録機能の完了
    メイン関数は必ずしもプログラムのエントリではありません.
    #include 
    using namespace std;
    
    __attribute__((constructer))
    void test() {
      printf("%s : hello world
    ", __func__); return; } int main() { printf("%s : helloworld
    ", __func__); return 0; }

    上記プログラムの実行test関数は、主関数より先に実行されます.
    機能を完備する:テストフレームワークの初育成
    #define COLOR(msg, code) "\033[0;1;" #code "m" msg "\033[0m"
    #define RED(msg)    COLOR(msg, 31)
    #define GREEN(msg)  COLOR(msg, 32)
    #define YELLOW(msg) COLOR(msg, 33)
    #define BLUE(msg)   COLOR(msg, 34)
    
    #define EXPECT(a, comp, b) { \
        __typeof(a) __a = (a), __b = (b); \
        if (!((__a) comp (__b))) { \
            printf(YELLOW("  %s:%d: Failure
    "), __FILE__, __LINE__); \ printf(YELLOW(" Expected: (%s) %s (%s), actual: %d vs %d
    "),\ #a, #comp, #b, __a, __b); \ } \ } #define EXPECT_EQ(a, b) EXPECT(a, ==, b) #define EXPECT_NE(a, b) EXPECT(a, !=, b) #define EXPECT_LT(a, b) EXPECT(a, , b) #define EXPECT_GE(a, b) EXPECT(a, >=, b) #define TEST(a, b) \ void a##_##b(); \ __attribute__((constructor)) \ void reg_##a##_##b() { \ add_func(a##_##b, #a "." #b); \ return ; \ } \ void a##_##b() struct { void (*func)(); const char *func_name; } func_arr[100]; int func_cnt = 0; void add_func(void (*func)(), const char *str) { func_arr[func_cnt].func = func; func_arr[func_cnt].func_name = str; func_cnt += 1; return ; } int RUN_ALL_TESTS() { for (int i = 0; i < func_cnt; i++) { printf(GREEN("[ RUN ]") " %s
    ", func_arr[i].func_name); func_arr[i].func(); } return 0; }