# 入門ガイド

- コンセプト
- Google Test との違い
  - Google Test にあって iutest にない機能
  - iutest 拡張機能
    - アサーション
      - アサーションの拡張
      - 戻り値のある関数での ASSERT 使用
      - 例外の値のアサーション
      - 警告アサーション
      - 前提条件アサーション
      - Visual Studio コード分析に対応
    - イベントリスナー
    - Private コードのテスト
    - Windows メニューへの登録ユーティリティ
  - iutest 独自機能
    - アサーション
      - 式アサーション
    - テストの生成
      - IUTEST_PMZ/IUTEST_PMZ_F
      - テストフィクスチャの省略（IUTEST_P）
      - Pairwise
      - 乱数パラメータの生成
      - パラメータの連結
      - CSV ファイルからパラメータを生成
      - Variadic Templates の対応
      - パッケージ
      - 日本語テスト名
    - テストのスキップ
    - イベントリスナー
    - Private コードのテスト
    - junit 形式での出力
    - コマンドラインオプション
- iutest / Google Test 切り替え
  - iutest モード
  - Google Test モード
- テストのフィルタリング
  - フォーマット
  - 例
  - ファイルから指定
- Matcher
  - Matcher の概要
  - アサーション
  - Matcher の種類

## コンセプト

iutest の基本コンセプトは Google Test のそれと同じです。
ここでは、iutest 独自のコンセプトを上げます。

- include オンリーで使用できる
  iutest は「簡単に」「すぐに」テストが書けることを目的としています。
  そのため、ライブラリを作成しなくても include するだけで使用できるようにし、初期障壁をなくすようにしました。
- Google Test との互換性
  iutest は、Google Test のインターフェイスを踏襲しています。
  iutest では、 Googlet Test のマクロに IUTEST_ プリフィックスを付けた名前にしています。
  ( ASSERT_EQ > IUTEST_ASSERT_EQ )
  また、「Google Test のコードで iutest を利用する」、「iutest のコードで Google Test を利用する」ことができるように、
  iutest_switch.hpp が用意されています。

## Google Test との違い

### Google Test にあって iutest にない機能

- Death Test
- スタックトレース
- スレッド対応
- etc...

### iutest 拡張機能

こちらの機能は、iutest_switch.hpp を使用することで Google Test でも使用できるようになる機能です。

- アサーション
  - アサーションの拡張
    - IUTEST_ASSERT_ALMOST_EQ
    - IUTEST_ASSERT_EQ_RANGE
    - IUTEST_ASSERT_NE_RANGE
    - IUTEST_ASSERT_EQ_COLLECTIONS
    - IUTEST_ASSERT_NE_COLLECTIONS
    - IUTEST_ASSERT_STRLNEQ
    - IUTEST_ASSERT_STRIN
    - IUTEST_ASSERT_NULL
    - IUTEST_ASSERT_NOTNULL
    - IUTEST_ASSERT_SAME
    - IUTEST_ASSERT_MATCHES_REGEXEQ
    - IUTEST_ASSERT_MATCHES_REGEXNE
    - IUTEST_ASSERT_CONTAINS_REGEXEQ
    - IUTEST_ASSERT_CONTAINS_REGEXNE
    など
  - 例外の値のアサーション
    THROW,ANY_THROW,NO_THROW に加えて例外の値をテストするアサーションを追加しています。

        IUTEST(Hoge, ThrowValue)
        {
          IUTEST_ASSERT_THROW_VALUE_EQ(throw 2, int, 2);
          IUTEST_ASSERT_THROW_VALUE_STREQ(throw "error", const char *, "error");
        }

  - 戻り値のある関数での ASSERT 使用
    基本的に IUTEST_ASSERT_* マクロは return 文でテストの中断を行なっています。
    そのため、戻り値の型が void でない関数では、IUTEST_ASSERT_* は使用できませんでした。
    iutest では ::iutest::AssertionReturn を使用することで、明示的に IUTEST_ASSERT_* マクロの戻り値型を変更できます。
    (gtest モードでも使用できるようになりました。)

        int ReturnTest(void)
        {
            IUTEST_ASSERT_TRUE(true) << ::iutest::AssertionReturn<int>(-1);
            return 0;
        }

  - 警告アサーション
    Boost.Test の WARN フレーバーと同等のアサーションです。
    ログの出力はされますが、テスト失敗にはなりません。

        IUTEST(Hoge, Inform)
        {
          IUTEST_INFORM_TRUE(IsEven(2));
        }

  - 前提条件アサーション
    テストの前提条件を検証するためのアサーションです。
    この検証に失敗した場合、ログを出力してテストを即座に終了します。
    テスト失敗にはなりません。（iutest の場合はスキップになります。）

        IUTEST(Hoge, Size)
        {
          IUTEST_ASSUME_EQ(4, sizeof(int));
        }

  - Visual Studio コード分析に対応
    コード分析では NULL ポインタ参照の可能性のあるコードに警告(C6011)が報告されます。
    下記のようなコードの場合、コード分析ツールに p が NULL でないことを __analysis_assume で教えることでより正しく分析されます。

        IUTTEST(NullCheck, Sample)
        {
            int* p = (int*)malloc(4);
            IUTEST_ASSERT_TRUE(p != NULL);
            __analysis_assume(p != NULL);
            *p = 1;
            IUTEST_ASSERT_EQ(1, *p);
        }

    しかし、このような __analysis_assume は冗長な記述です。
    iutest では、IUTEST_*_NOTNULL, IUTEST_*_NULL を使用することで、__analysis_assume の記述を省くことができます。

        IUTEST(NullCheck, Sample)
        {
            int* p = (int*)malloc(4);
            IUTEST_ASSERT_NOTNULL(p);
            *p = 1;
            IUTEST_ASSERT_EQ(1, *p);
        }

- イベントリスナー
  - QuietResultPrinter
    成功時のテストログを出さないようにするイベントリスナーです。
- Private コードのテスト
  - IUTEST_FRIEND_TYPED_TEST
    TYPED_TEST に対しての friend 宣言をします。
- Windows メニューへの登録ユーティリティ
  - util/iutest_util_menu.hpp
    Windows のメニューバーにテストの実行メニューを生成するユーティリティです。
    コマンドラインからの実行ではなく、GUI から任意のテストを実行できます。
    テストの自動化ではなく、ランチャーとしての利用を想定しています。

### iutest 独自機能

こちらの機能は、iutest でのみ利用できる機能です。

- アサーション
  - 式アサーション
    - IUTEST_(ASSERT|EXPECT|INFORM|ASSUME) マクロ
      通常のアサーションではオペランドに合わせてマクロを変える必要がありましたが、式アサーションでは１つのマクロで記述できます。

          int f() { return 42; }
          IUTEST(Test, Sample)
          {
              IUTEST_ASSERT_EQ( 42, f() );
              IUTEST_ASSERT_TRUE( f() == 42 );
              IUTEST_ASSERT( f() == 42 );

              IUTEST_ASSERT_LE( f(), 0 );
              IUTEST_ASSERT_TRUE( f() <= 0 );
              IUTEST_ASSERT( f() <= 0 );
          }

      IUTEST_ASSERT_TRUE を使用した場合と違い、式アサーションでは式を分解して値を出力します。
      IUTEST_ASSERT( f() <= 0 ); は通常の出力に加えて "expansion: 42 <= 0" と出力されます。
    - IUTEST_*_NOT マクロ
      式アサーションの偽条件マクロです。
    - ||, && による複合条件
      式アサーションの式の分解には制限があり、|| や && で連結した以降の式は分解されません。
      iutest では式の展開を補助する２つのマクロを用意しています。
      IUTEST_OPERAND:

          IUTEST(Test, Sample)
          {
              IUTEST_ASSERT(f() <= 0 IUTEST_OPERAND(||) f() >= 100 );
          }

      IUTEST_EXPRESSION:

          IUTEST(Test, Sample)
          {
              IUTEST_ASSERT(f() <= 0 || IUTEST_EXPRESSION(f() >= 100) );
              IUTEST_ASSERT(IUTEST_EXPRESSION(f() <= 0) || IUTEST_EXPRESSION(f() >= 100) );

              IUTEST_ASSERT_TRUE(IUTEST_EXPRESSION(f() <= 0) || IUTEST_EXPRESSION(f() >= 100) );
          }

      IUTEST_OPERAND は || , && を補助します。これは式アサーション専用のマクロになります。
      IUTEST_EXPRESSION は式を補助します。こちらは式アサーション以外（例えば IUTEST_ASSERT_TRUE）でも利用可能です。
- テストの生成
  - IUTEST_PMZ/IUTEST_PMZ_F
    IUTEST_P とは違い、関数と引数を直指定するテストマクロです。
    IUTEST_P よりも直感的にテストが可能です。

        void TestFunction(int x, int y)
        {
            IUTEST_ASSERT_EQ(x, y);
        }
        IUTEST_PMZ(ParamMethodTest, EQ, TestFunction, 0, 0);
        IUTEST_PMZ(ParamMethodTest, EQ, TestFunction, 1, 1);

  - テストフィクスチャの省略（IUTEST_P）
    iutest の値のパラメータ化テストでは、テストフィクスチャの定義が省略できます。

        //class AnyParamtest : public ::iutest::TestWithParam<int> {}; // 不要
        IUTEST_P(AnyParamTest, Test)
        {
            const int value = GetParam<int>();
            IUTEST_ASSERT_EQ(0, value);
        }

        IUTEST_INSTANTIATE_TEST_CASE_P(My1, AnyParamTest, ::iutest::Values(0));

    テストフィクスチャを省略した場合のパラメータ型は、::iutest::any になっています。
    パラメータの値を取り出す際は、template 版の GetParam を使用してください。
    ※template 版の GetParam は型安全でないキャストを行います。キャスト不可能な型にキャストしないよう十分に注意してください。
    型をチェックする場合は、非 template な GetParam を使用して any を取得し、 ::iutest::any_cast で目的の型にキャストしてください。
  - Pairwise
    オールペア法による組み合わせの作成ができます。

        IUTEST_INSTANTIATE_TEST_CASE_P(A, TestP
            , ::iutest::Pairwise( ::iutest::Bool()
                , ::iutest::Values(1, 2)
                , ::iutest::Values(10, 11) ) );

  - 乱数パラメータの生成
    iutest ではランダムなパラメータを生成するためのジェネレータを用意しています。

        IUTEST_INSTANTIATE_TEST_CASE_P(A, TestP
            , ::iutest::RandomValues( 5 ) );

    RandomValues の第一引数にパラメータの総数を指定します。（第二引数に乱数シードを指定可能）
    また、特定の値を除いた乱数をパラメータにするなどフィルタリングにも対応しています。
    この場合、::iutest::ValuesGen と ::iutest::RandomGenerator を使用します。

        bool Filter(int n) { return n != 100 && n != 500 && n != 1000; }
        IUTEST_INSTANTIATE_TEST_CASE_P(A, TestP
            , ::iutest::ValuesGen( 5,  ::iutest::RandomGenerator<int>(&Filter) ) );

    ※ これらのジェネレータは補助的なジェネレータです。ValuesIn に乱数を格納した vector などのコンテナを渡すことで実現可能です。
  - パラメータの連結
    iutest では複数のパラメータの連結ができます。
    連結をすることにより、より複雑なパラメータでも簡単に生成することができます。
    連結をするには ::iutest::Concat もしくは operator + を使用します。
    ::iutest::Concat の場合

        IUTEST_INSTANTIATE_TEST_CASE_P(A1, TestP
            , ::iutest::Concat( ::iutest::Range(1, 10), ::iutest::Range(101, 110) ) );
        IUTEST_INSTANTIATE_TEST_CASE_P(A2, TestP
            , ::iutest::Concat( ::iutest::Range(1, 10), ::iutest::Bool() ) );

    operator + の場合

        IUTEST_INSTANTIATE_TEST_CASE_P(A1, TestP
            , ::iutest::Range(1, 10)
                + ::iutest::Range(101, 110) );
        IUTEST_INSTANTIATE_TEST_CASE_P(A2, TestP
            , ::iutest::Range(1, 10)
                + ::iutest::Bool()
                + ::iutest::Values(99, 88, 77) ) );

  - CSV ファイルからパラメータを生成
    CSV ファイルからパラメータを生成できます。

        IUTEST_INSTANTIATE_TEST_CASE_P(I, TestI
            , ::iutest::CSV<int>("intparams.csv") );
        IUTEST_INSTANTIATE_TEST_CASE_P(F, TestF
            , ::iutest::CSV<float>("fparams.tsv", '\t') );

    ファイルからのパラメータは動的に生成されるため、実行ファイルを更新せずにパラメータだけ更新することが可能になります。
  - Variadic Templates の対応
    C++11 Variadic Templates が利用可能な環境で、Variadic Templates に対応した Types,Values,Combine,Pairwise が利用可能です。
  - パッケージ
    IUTEST_PACKAGE マクロを使うことで、名前空間をパッケージとして扱うことができます。
    通常の名前空間ではテスト名が衝突してしまい、出力 XML で区別がつかなくなってしまいますが、
    IUTEST_PACKAGE マクロを使うことで、名前空間名がパッケージ名としてテストケース名に追加され、区別できるようになります。

        IUTEST_PACKAGE(TestPackageA)
        {
          IUTEST(Test, Hoge)
          {
            IUTEST_ASSERT_TRUE(true);
          }
        }
        IUTEST_PACKAGE(TestPackageB)
        {
          IUTEST(Test, Hoge)
          {
            IUTEST_ASSERT_TRUE(true);
          }
        }

    また、--iutest_default_package_name コマンドラインオプションでデフォルトのパッケージ名を設定できます。
  - 日本語テスト名
    IUTEST_JAPANESE_NAME マクロを使用することでテスト名に日本語を使用できます。

        IUTEST(IUTEST_JAPANESE_NAME(あいうえお)
                            , IUTEST_JAPANESE_NAME(かきくけこ))
        {
        }

    テストフィクスチャを利用する場合は、IUTEST_JAPANESE_NAME_F マクロを使用してください。

        class FixedTest : public ::iutest::Test {};
        IUTEST_F(IUTEST_JAPANESE_NAME_F(あいうえお, FixedTest)
                            , IUTEST_JAPANESE_NAME(かきくけこ))
        {
        }

    ※ IUTEST_TYPED_TEST_P は未対応です。
- テストのスキップ
  - IUTEST_SKIP
    テストを明示的にスキップします。
    ASSUME と同等の機能ですが、IUTEST_SKIP には条件式がありません。
    ユーザーが適切な場所で呼び出してください。

        IUTEST(SkipTest, Skip)
        {
            if(sizeof(int) != 4 ) IUTEST_SKIP() << "sizeof(int) != 4";
        }

- イベントリスナー
  - ProgressPrintListener
    テストの実行状況をプログレス表示するイベントリスナーです。
  - SSTPNotifier
    伺かにテスト結果を通知するイベントリスナーです。
- Private コードのテスト
  - PEEP
    テンプレートの明示的な実体化を利用した private メンバーへのアクセスを簡易に行うためのマクロです。
    メンバーにアクセスするには、IUTEST_PEEP_GET マクロを使用するかクラスオブジェクト版の IUTEST_PEEP マクロを使用します。

        class Hoge
        {
          int m_x;
          int GetX() { return m_x; }
        };

        IUTEST_MAKE_PEEP(int Hoge::*, Hoge, m_x);
        IUTEST_MAKE_PEEP(int (Hoge::*)(), Hoge, GetX);

        IUTEST(ProdTest, Peep)
        {
          Hoge hoge;
          IUTEST_PEEP_GET(hoge, Hoge, m_x) = 4;
          IUTEST_ASSERT_EQ(4, IUTEST_PEEP_GET(hoge, Hoge, m_x));
          IUTEST_ASSERT_EQ(4, IUTEST_PEEP_GET(hoge, Hoge, GetX)());

          IUTEST_PEEP(Hoge, m_x) hoge_x(&hoge);
          hoge_x = 5;
          IUTEST_ASSERT_EQ(5, hoge_x);
        }

- junit 形式での出力
  iutest では、junit 形式の XML 出力に対応しています。
  コマンドラインオプションに --iutest_output=junit[:path] と指定すると junit 形式で XML 出力を行います。
- コマンドラインオプション
  - --iutest_file_location
    エラーログなどのファイル/行表記のフォーマット gcc,vs,auto から指定します。
    例えば、ビルドエラーと区別を付けるために別のフォーマットで出力するという使い方が考えられます。
  - --iutest_output=junit[:path]
    junit 形式で XML 出力を行います。
  - --iutest_default_package_name
    トップのパッケージ名を指定できます。
  - --iutest_list_tests_with_where
    パラメータの情報を含んだテストリストを出力します。
  - --iutest_warning_into_error
    警告をエラーとします。
  - --verbose
    冗長出力を有効にします。
  - --feature
    iutest の機能をリストアップします。

## iutest / Google Test 切り替え

iutest と Google Test の切り替えには gtest/iutest_switch.hpp を使用します。

    //#include "iutest.hpp"
    #include "gtest/iutest_switch.hpp" // iutest.hpp の代わりに iutest_switch.hpp を使用する

### iutest モード

デフォルトでは iutest モードになっています。
iutest.hpp と違うのは Google Test の記法が使えるという点です。
既存の Google Test のテストコードも iutest_switch.hpp ヘッダーをインクルードすることで、
iutest の実装に切り替わります。

### Google Test モード

Google Test モードに切り替えるには iutest_switch.hpp ヘッダーをインクルードする前に、
IUTEST_USE_GTEST マクロを定義してください。
これにより、iutest のテストコードで Google Test の実装を使用するようになります。

## テストのフィルタリング

--iutest_filter コマンドラインオプションでフィルタを指定できます。 ここでは、フィルタのフォーマットについて説明をします。

### フォーマット

フィルタのフォーマットは、':' で区切られたワイルドカードパターン（ポジティブパターン）になります。
また、先頭に '-' を付けることで、マッチしたテストを除外するネガティブパターンも指定できます。
（iutest のテスト名は、TestCaseName.TestName です）

* | 任意の文字列にマッチ
? | 任意の1文字にマッチ

### 例

./foo_test | 全てのテストを実行します
./foo_test --iutest_filter=*
./foo_test --iutest_filter=FooTest.* | テストケース FooTest 内のテストを全て実行します
./foo_test --iutest_filter=*Null*:*Init* | 名前に "Null" または "Init" を含むテストを実行します
./foo_test --iutest_filter=-*Foo* | 名前に "Foo" を含むテスト 以外 を全て実行します
./foo_test --iutest_filter=FooTest.*-FooTest.Bar | テストケース FooTest 内のテストで FooTest.Bar を除く 全てのテストを実行します
./foo_test --iutest_filter=FooTest.*-FooTest.Bar:FooTest.Baz | テストケース FooTest 内のテストで FooTest.Bar と FooTest.Baz を除く全てのテストを実行します

### ファイルから指定

iutest ではフィルターをファイルから読み込むことができます。
--iutest_filter=@filter.txt のように先頭に @ を付け、その後にファイル名を指定することで読み込みできます。
フォーマットはコマンドラインと同じです。（改行は ':' に置き換えられます）

## Matcher

### Matcher の概要

iutest では Matcher を提供しています。iutest の Matcher は Google Mock のそれとほぼ同じ使い方をします。
ただし、Google Mock との互換性対応はしていませんのでご注意ください。

### アサーション

Matcher は IUTEST_*_THAT アサーションで利用します。

IUTEST_*_THAT(expression, m) | expression の値が Mathcer m にマッチするか検証します

### Matcher の種類

Matcher の種類については Doxygen 生成のドキュメントを確認してください。
Copyright (c) 2011-2020, Takazumi-Shirayanagi, All rights reserved.