Cutter

Cutter — C言語・C++言語用単体テストフレームワーク

Functions

Types and Values

#define CUT_EXPORT

説明

Cutterは以下のような特徴をもったC言語・C++言語用の単体テストフレームワークです。<placeholder-1></placeholder-1>

  • Easy to use. Cutter doesn't introduce any magic macros like CUTTER_DEFINE_TEST_START and CUTTER_DEFINE_TEST_END into your test program. You can write your test program like normal program. You only use cut_assert_XXX() to check that your program works as you expect.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include <cutter.h>
    #include "my-stack.h"
    
    void
    test_my_stack (void)
    {
        MyStack *stack = my_stack_new();
    
        cut_assert_not_null(stack);
        cut_assert(my_stack_is_empty(stack));
        cut_assert_equal_int(0, my_stack_get_size(stack));
    
        my_stack_push(stack, 10);
        cut_assert(!my_stack_is_empty(stack));
        cut_assert_equal_int(1, my_stack_get_size(stack));
    
        my_stack_push(stack, 20);
        cut_assert_equal_int(2, my_stack_get_size(stack));
    
        cut_assert_equal(20, my_stack_pop(stack));
        cut_assert(!my_stack_is_empty(stack));
        cut_assert_equal_int(1, my_stack_get_size(stack));
    
        cut_assert_equal(10, my_stack_pop(stack));
        cut_assert(my_stack_is_empty(stack));
        cut_assert_equal_int(0, my_stack_get_size(stack));
    }

  • Simple but useful output. Cutter works quietly if tests are running without any problems by default. The following is an output of self test:

    1
    2
    3
    4
    5
    ...........................................................
    
    Finished in 0.213021 seconds
    
    59 test(s), 246 assertion(s), 0 failure(s), 0 error(s), 0 pending(s), 0 notification(s)

    Cutter just outputs "." for a passed test and a summary at the end. Cutter doesn't output each test name, how many assertions are used for a test and so because we don't need the information on success.

    Cutter outputs many information on failure:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    .....................F.....................................
    
    1) Failure: test_error
    <"Strange" == cut_test_result_get_test_name(result)>
    expected: <Strange!!!>
     but was: <dummy-error-test>
    test/test-cut-assertions.c:240: cut_assert_test_result()
    
    Finished in 0.223657 seconds
    
    59 test(s), 242 assertion(s), 1 failure(s), 0 error(s), 0 pending(s), 0 notification(s)

    The above result is happened because I add a strange expected staring in Cutter's self test:

    1
    cut_assert_equal_string("Strange!!!", cut_test_result_get_test_name(result));

    The strange assertion is written in the 240th line in test/test-cut-assertions.c and the line is in the cut_assert_test_result() function. The function is called in test_error test. We expected cut_test_result_get_test_name(result) should return "Strange!!!" but got "dummy-error-name". We can get the above information from Cutter output. This will help your debug.

    Cutterの出力形式は実用的です。' but was:'はその上の'expected:'と並ぶようにインデントされています。これは期待値と実測値をパッと見て簡単に比較できるようにするためです。問題のあった行は「ファイル名:行: 関数」というように整形されています。これはEmacsと連携するためです。Emacsのcompilation-modeではこの形式が*compilation*バッファに表れると、next-errorコマンド(C-x `)で「ファイル名」の「行」へジャンプすることができます。これは問題行を素早く見つける手助けをします。

    Cutterは簡単にテストを書くことを支援するだけではなく、簡単にデバッグをできることも支援します。

Functions

setup ()

void
setup (void);

GCutEggは非推奨です。新しいコードでは使わないでください。

cut_set_actual()も見てください。

テストプログラム中でsetup()を定義していたら、cutterは各テストが実行される前に定義されたsetup()を呼びだします。cut_setup()が定義されていた場合は、setup()は無視されます。


cut_setup ()

void
cut_setup (void);

テストプログラム中でcut_setup()を定義していたら、cutterは各テストが実行される前に定義されたcut_setup()を呼びだします。cut_setup()setup()が定義されていた場合はcut_setup()だけが使われます。

Since: 1.0.6


teardown ()

void
teardown (void);

GCutEggは非推奨です。新しいコードでは使わないでください。

cut_set_expected()も見てください。

テストプログラム中でteardown()を定義していたら、cutterは各テストの後に、たとえテストが失敗していた時でも、teardown()を呼びだします。cut_teardown()が定義されていた場合は、teardown()は無視されます。


cut_teardown ()

void
cut_teardown (void);

テストプログラム中でcut_teardown()を定義していたら、cutterは各テストの後に、たとえテストが失敗していた時でも、cut_teardown()を呼びだします。cut_teardown()teardown()が定義されていた場合はcut_teardown()だけが使われます。

Since: 1.0.6


cut_startup ()

void
cut_startup (void);

テストプログラム中でcut_startup()を定義していたら、cutterは各テストケースが実行される前に定義されたcut_startup()を呼びだします。cut_startup()startup()が定義されていた場合はcut_startup()だけが使われます。

Since: 1.0.6


cut_shutdown ()

void
cut_shutdown (void);

テストプログラム中でshutdown()を定義していたら、cutterは各テストケースが実行された後に定義されたshutdown()を呼びだします。cut_shutdown()shutdown()が定義されていた場合はcut_shutdown()だけが使われます。

Since: 1.0.6


cut_add_data()

#define             cut_add_data(first_data_name, ...)

データ駆動テストで使うデータを追加します。

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <cutter.h>

void data_translate (void);
void test_translate (const void *data);

static const char*
translate (int input)
{
   switch(input) {
   case 1:
       return "first";
   case 111:
       return "a hundred eleven";
   default:
       return "unsupported";
   }
}

typedef struct _TranslateTestData
{
    char *translated;
    int input;
} TranslateTestData;

static TranslateTestData *
translate_test_data_new (char *translated, int input)
{
    TranslateTestData *data;

    data = malloc(sizeof(TranslateTestData));
    data->translated = strdup(translated);
    data->input = input;

    return data;
}

static void
translate_test_data_free (TranslateTestData *data)
{
    free(data->translated);
    free(data);
}

void
data_translate(void)
{
    cut_add_data("simple data",
                 translate_test_data_new("first", 1),
                 translate_test_data_free,
                 "complex data",
                 translate_test_data_new("a hundred eleven", 111),
                 translate_test_data_free,
                 NULL);
}

void
test_translate(const void *data)
{
     const TranslateTestData *test_data = data;

     cut_assert_equal_string(test_data->translated,
                             translate(test_data->input));
}

Parameters

最初のデータ名。

最初のデータ名。

 

...

最初のデータとデータ破棄関数。続けて任意の数の「名前・データ・データ破棄関数(CutDestroyFunction)」の三つ組を指定します。1.0.6から可変長の引数はNULL終端しなければいけなくなりました。

 

Since: 1.0.3


cut_add_data_backward_compatibility()

#define             cut_add_data_backward_compatibility(context, ...)

cut_add_data_backward_compatibilityは非推奨です。新しいコードでは使わないでください。


cut_set_attributes()

#define             cut_set_attributes(first_attribute_name, ...)

テストの属性を設定します。

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cutter.h>

void attributes_repeat (void);
void test_repeat (void);

void
attributes_repeat(void)
{
    cut_set_attributes("description", "a test for repeat function",
                       "bug", "111",
                       "priority", "high",
                       NULL);
}

void
test_repeat(void)
{
     cut_assert_equal_string_with_free("XXX", repeat("X", 3));
}

Parameters

最初の属性名。

最初の属性名。

 

...

最初の属性値です。その後に任意個数の名前と値のペアが続きます。1.0.7からNULL終端が必須になりました。

 

Since: 1.0.4


cut_get_current_test_context

#define             cut_get_current_test_context()

現在のテストコンテキストを返します。「現在のテストコンテキスト」はスレッドローカルなオブジェクトです。もしテストの中で新しいスレッドを作らない場合はテストコンテキストを気にする必要はありません。新しいスレッドを作る場合だけ必要になります。テストのスレッドが持っている「現在のテストコンテキスト」を新しく作ったスレッドに渡す必要がありません。

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int
your_thread_function(void *data)
{
    CutTestContext *test_context = data;
    cut_set_current_test_context(test_context);
    ...
}

void
run_your_thread(void)
{
    int result;
    pthread_t your_thread;

    result = pthread_create(&your_thread, NULL,
                            your_thread_function,
                            cut_get_current_test_context());
    ...
}

Returns

CutTestContextオブジェクト。

Since: 1.0.4


cut_set_current_test_context()

#define             cut_set_current_test_context(test_context)

現在のテストコンテキストをtest_contextにします。詳細はcut_get_current_test_context()を見てください。

Parameters

test_context

現在のテストコンテキストになるCutTestContext

 

Since: 1.0.4


cut_set_message ()

void
cut_set_message (const char *format,
                 ...);

CPPCUT_END_TEST_DECLSはバージョン1.1.0から非推奨になりました。新しく書くコードでは使わないでください。代わりにnamespaceを使ってください。

追加メッセージ(省略可能)。詳細はcut_message()を見てください。

次の検証で使われるメッセージです。

Parameters

format

整形文字列。printf()のドキュメントを見てください。

 

...

整形文字列に挿入されるパラメータ。

 

Since: 1.0.6


cut_set_message_va_list ()

void
cut_set_message_va_list (const char *format,
                         va_list args);

CPPCUT_END_TEST_DECLSはバージョン1.1.0から非推奨になりました。新しく書くコードでは使わないでください。代わりにnamespaceを使ってください。

追加メッセージ(省略可能)。詳細はcut_message()を見てください。

次の検証で使われるメッセージです。

Parameters

format

整形文字列。printf()のドキュメントを見てください。

 

args

整形文字列に挿入されるパラメータ。

 

Since: 1.0.6


cut_keep_message ()

void
cut_keep_message (void);

CPPCUT_END_TEST_DECLSはバージョン1.1.0から非推奨になりました。新しく書くコードでは使わないでください。代わりにnamespaceを使ってください。

追加メッセージ(省略可能)。詳細はcut_message()を見てください。

cut_set_message()またはcut_set_message_va_list()で設定した現在のメッセージを次の検証の後でも維持します。

Since: 1.0.6


cut_message ()

void
cut_message (const char *format,
             ...);

追加の検証メッセージを指定します。

例:

1
2
cut_assert_equal_string("abc", "def",
                        cut_message("should fail!"));

Parameters

format

整形文字列。printf()のドキュメントを見てください。

 

...

整形文字列に挿入されるパラメータ。

 

Since: 1.1.0

Types and Values

CUT_EXPORT

#  define CUT_EXPORT __declspec(dllexport)

公開関数であるというしるしをつけます。このしるしはWindows環境上でだけ必要です。Windows上でもテストを実行したい場合はこのマクロを使う必要があります。そうでなければ使う必要はありません。

例:

1
2
3
4
5
CUT_EXPORT void
test_add (void)
{
  ...
}

Since: 1.1.2

参考

検証