## README README |

## 名前

Cutter

## ライセンス

LGPL

## Cutter?

CのためのUnit Testing Frameworkです。

Cutterの特徴は以下の通りです。

- テストが簡単に書ける

- 出力結果がデバッグに使いやすい

- テストを共有ライブラリとしてビルドする

## 依存ライブラリ

- GLib >= 2.16

## 入手方法

<URL:http://sourceforge.net/project/showfiles.php?group_id=208375>

    % svn co https://cutter.svn.sourceforge.net/svnroot/cutter/cutter/trunk cutter

## インストール

    % ./configure
    % make
    # make install

### GLibを別途インストールする場合

システムにインストールされているGLibが2.16より古い場合はGLib >= 2.16を別途インストールし、それを用いてCutterをインストー ルすることができる。その場合は以下のようになる。この例で は~/local/以下にGLibをインストールしている。

    % wget http://ftp.gnome.org/pub/GNOME/sources/glib/2.16/glib-2.16.3.tar.gz
    % tar xvfz glib-2.16.3.tar.gz
    % cd glib-2.16.3
    % ./configure --prefix=$HOME/local
    % make
    % make install

このGLibを用いてCutterをビルド・インストールする場合は以下の ようになる。

    % export PKG_CONFIG_PATH=$HOME/local/lib/pkgconfig
    % export LD_LIBRARY_PATH=$HOME/local/lib
    % ./configure
    % make
    # make install

## 使い方

    % cutter [オプション] [test_*.soがあるディレクトリ]

注: test_*.soはディレクトリを再帰的にたどって検索されます。

### オプション

--version | バージョンを表示して終了します。
-s DIRECTORY, --source-directory=DIRECTORY | テストが失敗した場合にファイル名の前にDIRECTORYを付加しま す。Cutterの出力からテストが失敗した箇所にジャンプするツー ル（Emacsなど）と連携するための機能です。
-t TEST_CASE_NAME, --test-case=TEST_CASE_NAME | TEST_CASE_NAMEにマッチしたテストケースを実行します。もし、 TEST_CASE_NAMEが"/"で囲まれていた場合は（例: /test_/）正 規表現として扱います。 このオプションは複数回指定できます。その場合は、どれかの TEST_CASE_NAMEにマッチしたテストケースを実行します。（OR）
-n TEST_NAME, --name=TEST_NAME | TEST_NAMEにマッチしたテストを実行します。もし、TEST_NAME が"/"で囲まれていた場合は（例: /test_/）正規表現として扱 います。 このオプションは複数回指定できます。その場合は、どれかの TEST_NAMEにマッチしたテストケースを実行します。（OR）
-m, --multi-thread | 各テストケースを新しいスレッドで実行します。
--test-case-order=[none|name|name-desc] | 各テストケースの実行順を並び替えます。デフォルトでは並び 替えません。（none） nameを指定するとテストケース名で昇順に並び替えます。 name-descを指定するとテストケース名で降順に並び替えます。
-u=[console|gtk], --ui=[console|gtk] | UIを指定します。デフォルトはコンソールUIです。
-v[s|silent|n|normal|v|verbose], --verbose=[s|silent|n|normal|v|verbose] | 出力の詳細さを指定します。 このオプションはコンソールUIを使用する場合だけ有効です。
-c[yes|true|no|false|auto], --color=[yes|true|no|false|auto] | yesまたはtrueが指定された場合はCutterはエスケープシーケン スで色付けして出力します。noまたはfalseが指定された場合は 色付けしません。autoあるいは値が省略された時は、可能なら 色付けをします。 このオプションはコンソールUIを使用する場合だけ有効です。
--xml-report=FILE | FILEにXML形式でテスト結果を出力します。
-?, --help | UIやテスト結果レポート機能に依存しないオプションを表示し ます。
--help-all | すべてのオプションを表示します。

## テストの仕方

テストの実行は以下のような流れになります．

1. テストを作成する

2. コンパイルし、test_*.soを作成する

3. cutterを起動し、test_*.soを読み込ませ、テストをする

詳しくはTUTORIAL.jaとsample/stack/を参考にしてください。

## テスト結果

テスト結果は例えば以下のようになります。

    ..........F.................................................

    1) Failure: test_test_case_count
    <1 == cut_test_case_get_n_tests(test_object, NULL)>
    expected: <1>
     but was: <0>
    test/test-cut-test-case.c:143: test_test_case_count()

    Finished in 0.020857 seconds

    60 test(s), 253 assertion(s), 1 failure(s), 0 error(s), 0 pending(s), 0 notification(s)

### 進行状況

一番上にある「.」と「F」の部分がテストの進行状況を示していま す。

    ..........F.................................................

各「.」、「F」が1つのテストケース（テスト関数）を表していま す。「.」が成功したテストケース、「F」が失敗したテストケース を表しています。他にも「E」、「P」、「N」があり、それぞれエ ラー、保留、通知を表しています。まとめると以下のようになりま す。

. | 成功したテスト
F | 表明が失敗したテスト
E | 異常終了したテスト
P | 保留マークがついているテスト
N | 通知が行われたテスト

上記のテストを表す印はテストが実行される毎に出力されます。テ スト実行中は、この出力で実行状況を確認できます。

### テスト結果のまとめ

テストが終了すると、テスト結果のまとめを出力します。まとめは、 まず、成功しなかったテストの詳細をそれぞれ表示します。例では 1つ失敗があったのでそれを表示しています。

    1) Failure: test_test_case_count
    <1 == cut_test_case_get_n_tests(test_object, NULL)>
    expected: <1>
     but was: <0>
    test/test-cut-test-case.c:143: test_test_case_count()

この例ではtest_test_case_countテストケースが失敗し、 cut_test_case_get_n_tests(test_object, NULL)が1になって欲し かったのに実際は0になっていることを表しています。また、この 失敗した表明はtest/test-cut-test-case.cの143行目、 test_test_case_count()関数内で起こったことがわかります。

テスト結果の詳細一覧の後はテストにかかった時間が表示されます。

    Finished in 0.020857 seconds

最後にテスト結果の要約が表示されます。

    60 test(s), 253 assertion(s), 1 failure(s), 0 error(s), 0 pending(s), 0 notification(s)

それぞれは以下のような意味です。

n test(s) | n個のテストケース（テスト関数）を実行した
n assertion(s) | n個の表明にパスした
n failure(s) | n個の表明に失敗した
n error(s) | n個の異常事態が発生した（cut_error()を使用した）
n pending(s) | n個のテストケースを保留にした（cut_pending()を使用した）
n notification(s) | n個の通知が発生した（cut_notification()を使用した）

この例では60個のテストケースを実行し、253個の表明にパスし、1 個の表明に失敗したということになります。異常事態や保留にした テストケースなどはありませんでした。

### XML出力

--xml-reportオプションを指定することでテスト結果をXML形式で出 力することができます。出力されるXMLは以下のような構造になって います。

    <report>
      <result>
        <test-case>
          <name>テストケース名</name>
          <description>テストケースの説明（もしあれば）</description>
        </test-case>
        <test>
          <name>テスト名</name>
          <description>テストの説明（もしあれば）</description>
          <option><!-- 属性情報（もしあれば） -->
            <name>属性名（例: bug）</name>
            <value>属性値（例: 1234）</value>
          </option>
          <option>
            ...
          </option>
        </test>
        <status>テスト結果（[success|failure|error|pending|notification]）</status>
        <detail>テスト結果の詳細（もしあれば）</detail>
        <backtrace><!-- バックトレース（もしあれば） -->
          <entry>
            <file>ファイル名</file>
            <line>行</line>
            <info>付加情報</info>
          </entry>
          <entry>
            ...
          </entry>
        </backtrace>
        <elapsed>実行時間（例: 0.000010）</elapsed>
      </result>
      <result>
        ...
      </result>
      ...
    </report>

### テストカバレッジ

システムに LTP tools がイ ンストールされている場合は、Cutterを使ったテストを用いてコー ドカバレッジを出力することができます。カバレッジを出力するに はconfigure.acに以下を追加して、"make coverage"を実行してくだ さい。

    AC_CHECK_COVERAGE

## リファレンス

### 表明

cutter/cut-assertions.hあるいは cutter-cut-assertions.html を見てください。

### 属性

テストに属性を加えて、テスト失敗時により有益な情報を利用する ことができます。例えば、以下のようにテストにBug IDの情報を付 加することができます。

    const char *bug_invalid_input(void);
    void test_invalid_input(void);

    const char *
    bug_invalid_input (void)
    {
         return "123";
    }

    void
    test_invalid_input (void)
    {
         cut_assert_equal("OK", get_input());
    }

この例では、test_invalid_inputテストがBug #123のテストである という情報を付加しています。

属性は"「属性名」_「テスト名からtest_を除いたもの」"という名 前のconst char *を返す関数を定義することで追加できます。上記 の例では「bug」属性を「test_invalid_input」テストに追加する ために「bug_invalid_input」という属性設定関数を定義していま す。

### 雛型

テストの雛型は以下のようになります．

    #include <cutter.h>

    #include "自分のプログラムのヘッダファイル"

    void test_condition(void);
    void test_strstr(void);

    static int condition = 0;

    void
    setup (void)
    {
        /* 初期化用コード */
        condition = 1;
    }

    void
    teardown (void)
    {
        /* 後片付け用コード */
        condition = 0;
    }

    void
    test_condition(void)
    {
        cut_assert_equal_int(1, condition,
                             "conditionの値はsetup()で1に設定されているはず");
      ...
    }

    void
    test_strstr(void)
    {
        cut_assert_equal_string("sub-string",
                                strstr("string sub-string", "sub"));
        ...
    }