## はじめに はじめに — C言語・C++言語用単体テストフレームワークCutterの概要 |

## 名前

Cutter

## 作者

### プログラム

- Kouhei Sutou <kou@clear-code.com>

- Hiroyuki Ikezoe <ikezoe@clear-code.com>

- Yuto Hayamizu <y.hayamizu@gmail.com>

### きのたんアイコン

- Mayu & Co.

## ライセンス

- ソースコード: LGPLバージョン3またはそれ以降のバージョン（詳細: license/lgpl-3.txt ）です。

- ドキュメントときのたんアイコン: LGPLとGFDLとクリエイティブ・コモンズ・ライセンスのトリプルライセンス。

  - LGPLバージョン3またはそれ以降のバージョン（詳細: license/lgpl-3.txt ）です。

  - GFDLはバージョン1.3またはそれ以降のバージョン（詳細: license/gfdl-1.3.txt ）です。

  - クリエイティブ・コモンズ・ライセンスは 表示-継承（CC BY-SA） です。

- 例外:

  - glib-compatible/glibintl.h, glib-compatible/gregex.*, glib-compatible/gscripttable.h, glib-compatible/gsequence.*, glib-compatible/gstring.*, glib-compatible/gunicode.h, glib-compatible/guniprop.c: LGPLバージョン2.0またはそれ以降のバージョン（詳細: glib-compatible/COPYING ）

  - glib-compatible/pcre/: PCREライセンス（詳細: glib-compatible/pcre/COPYING ）

  - html/blog.*, html/download.*, html/heading-mark.* html/install.*, html/readme.*, html/reference.*, html/tango-logo.png, html/tutorial.*, html/mini-*.svg:パブリックドメイン。 Tango Desktop Project の成果物を利用しています。（一部改変しているものもある）

  - html/ja.png, html/us.png, html/famfamfam-logo.png:パブリックドメイン。 famfamfam.com が配布している国旗です。

## Cutter?

CutterはC言語・C++言語のためのxUnit系の単体テストフレームワークです。

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

- テストが簡単に書ける

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

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

詳細は 特徴 を見てください。

## 依存ライブラリ

- GLib >= 2.16

## 入手方法

tar.gz:

    % wget http://downloads.sourceforge.net/cutter/cutter-1.1.0.tar.gz

Subversion:

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

## インストール

インストール を見てください。

## 使い方

    % cutter [オプション ...] テストディレクトリ

テストディレクトリにはtest_*.soがあるディレクトリを指定します。cutterはテストディレクトリ以下にあるtest_*.soを再帰的に検索します。

詳細は cutter を見てください。

## テストの仕方

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

1. テストを作成する

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

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

詳しくは チュートリアル と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 を見てください。

### 属性

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

    void attributes_invalid_input(void);
    void test_invalid_input(void);

    void
    attributes_invalid_input (void)
    {
        cut_set_attributes("bug", "123");
    }

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

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

属性は"「attributes_「テスト名からtest_を除いたもの」"という名前の関数を定義し、その関数の中でcut_set_attributes()を使って設定できます。上記の例では「test_invalid_input」テストに「123」という値の「bug」属性を追加するために「attributes_invalid_input」という関数を定義し、その中でcut_set_attributes("bug", "123")を呼び、属性を設定しています。

### 雛型

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

    #include <cutter.h>

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

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

    static int condition = 0;

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

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

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

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

## 感謝

- Kazumasa Matsunagaさん: ビルドの不具合を報告してくれました。

- Daijiro MORIさん: 不具合を報告してくれました。

- 海野さん:

  - チュートリアルの不具合に気づかせてくれました。

  - Solaris用インストールドキュメントの作成を手伝ってくれました。

- グニャラくん: APIについてアドバイスしてくれました。

- 山川さん: Cygwinでの動作を教えてくれました。

- 奥地さん:

  - Localeまわりの不具合を報告してくれました。

  - 新機能を提案してくれました。

- Zed Shawさん: 不具合を報告してくれました。

- Romuald Contyさん: ドキュメントの不具合を報告してくれました。

- Romain Tartièreさん:

  - 不具合を報告してくれました。

  - 改良方法を提案してくれました。

- Ilya Baryginさん:

  - テストの不具合を報告してくれました。

- 中村弘輝さん

  - CentOSでの不具合を報告してくれました。