検証作成の補助

検証作成の補助 — このセクションにあるシンボルは独自検証を作成することを補助します。

概要

#define             CUT_RELATIVE_PATH
const char *        cut_append_diff                     (const char *message,
                                                         const char *from,
                                                         const char *to);
cut_boolean         cut_equal_double                    (double double1,
                                                         double double2,
                                                         double error);
#define             cut_equal_sockaddr                  (address1,
                                                         address2)
cut_boolean         cut_equal_string                    (const char *string1,
                                                         const char *string2);
const char *        cut_get_source_directory            (void);
const char *        cut_get_test_directory              (void);
#define             cut_inspect_sockaddr                (address)
const char *        cut_inspect_string_array            (const char **strings);
void                cut_pop_backtrace                   (void);
void                cut_push_backtrace                  (const char *expression);
#define             cut_set_actual                      (actual)
#define             cut_set_expected                    (expected)
void                cut_test_fail                       (const char *system_message,
                                                         ...);
void                cut_test_fail_va_list               (const char *system_message,
                                                         const char *user_message_format);
void                cut_test_pass                       (void);
#define             cut_trace                           (expression)
#define             cut_trace_with_info_expression      (expression,
                                                         info_expression)

説明

読みやすいテストを書くために独自の検証を作成する必要があるでしょう。このセクションのシンボルは独自の検証作成を補助します。

例:

my-assertions.h:

#ifndef __MY_ASSERTIONS_H__
#define __MY_ASSERTIONS_H__

#include <cutter.h>

#ifdef __cplusplus
extern "C" {
#endif

#define my_assert_equal_int(expected, actual)                    \
    cut_trace_with_info_expression(                              \
        my_assert_equal_int_helper((expected), (actual),         \
                                   # expected, # actual),        \
        my_assert_equal_int(expected, actual, __VA_ARGS__))

void my_assert_equal_int_help (long expected,
                               long actual,
                               const char *expression_expected,
                               const char *expression_actual);

#ifdef __cplusplus
}
#endif

#endif

my-assertions.c:

#include "my-assertions.h"

void
my_assert_equal_int_helper (long expected,
                            long actual,
                            const char *expression_expected,
                            const char *expression_actual)
{
    if (expected == actual) {
        cut_test_pass();
    } else {
        cut_test_fail(cut_take_printf("<%s == %s>\n"
                                      "expected: <%ld>\n"
                                      "  actual: <%ld>",
                                      expression_expected,
                                      expression_actual,
                                      expected, actual));
    }
}

Makefile.am:

AM_CFLAGS = $(CUTTER_CFLAGS)
LIBS = $(CUTTER_LIBS)
noinst_LTLIBRARIES = libmy-assertions.la
libmy_assertions_la_SOURCES = my-assertions.c my-assertions.h
AM_LDFLAGS = -module -rpath $(libdir) -avoid-version -no-undefined

詳細

CUT_RELATIVE_PATH

#  define CUT_RELATIVE_PATH NULL

もし、テスト用の補助ライブラリを共有ライブラリとして使っている場合は、補助ライブラリのソースコード中またはビルドオプション(例: -DCUT_RELATIVE_PATH=\""sub/dir/"\")でこのマクロを定義してください。もし、このパスが設定されていない場合はcut_trace()cut_trace_with_info_expression()で正しいパスが得られません。

説明用のディレクト構成例です。

--- core-lib/ --- XXX.c # コアライブラリ
 |             +- ...
 |             +- YYY.c
 +- util-lib/ --- AAA.c # 便利ライブラリ
 |             +- ...
 |             +- BBB.c
 |
 +- test/ --- core/ --- test-XXX.c # コアライブラリのテスト
           |         +- ...
           |         +- test-YYY.c
           +- util/ --- test-AAA.c # 便利ライブラリのテスト
           |         +- ...
           |         +- test-BBB.c
           +- lib/  --- my-assertions.c # テスト用補助ライブラリ
                     +- my-assertions.h # テスト中(
                     |                  # test/core/test-*.soと
                     |                  # test/util/test-*.soの中)
                     |                  # で共有ライブラリとして使われる
                     +- ...

  % cutter --source-directory=test test

上記の構成例では、test/lib/my-assertions.cではCUT_RELATIVE_PATHを"lib"と定義しなければいけません。これは、:source-directoryコマンドラインオプションで指定した"test"ソースディレクトリからみてlib/ディレクトリにmy-assertions.cがあるからです。

コードとビルドオプションの例です。

test/lib/my-assertions.c:
  #define CUT_RELATIVE_PATH "lib"
  #include <cutter.h>

build option:
  % gcc -DCUT_RELATIVE_PATH="\"lib\"" ...

1.0.6から


cut_append_diff ()

const char *        cut_append_diff                     (const char *message,
                                                         const char *from,
                                                         const char *to);

Warning

cut_append_diffはバージョン1.0.9から非推奨になりました。新しく書くコードでは使わないでください。代わりにcut_set_expected()cut_set_actual()を使ってください。

fromtoのdiffを計算し、そのdiffをmessageに追加します。戻り値の文字列の所有者はCutterです。

message :

diffが追加される文字列。

from :

元の文字列。

to :

修正された文字列。

戻り値 :

fromto間のdiff付きのmessage。必要なさそうなdiffであればmessageと同じ。開放しないでください。

1.0.3から


cut_equal_double ()

cut_boolean         cut_equal_double                    (double double1,
                                                         double double2,
                                                         double error);

double1double2を誤差範囲errorで比較します。

double1 :

浮動小数点値。

double2 :

浮動小数点値。

error :

誤差範囲を示す浮動小数点数。

戻り値 :

|double1 - double2| <= errorならCUT_TRUE、そうでなければCUT_FALSE

1.0.5から


cut_equal_sockaddr()

#define cut_equal_sockaddr(address1, address2) CUT_FALSE

address1address2を比較します。

この関数はCUT_DISABLE_SOCKET_SUPPORTを定義すると無効にできます。

address1 :

ソケットアドレス。

address2 :

ソケットアドレス。

戻り値 :

sub_processが異常終了したときはCUT_TRUE、そうでない場合はCUT_FALSE

1.1.1から


cut_equal_string ()

cut_boolean         cut_equal_string                    (const char *string1,
                                                         const char *string2);

string1string2を比較します。string1あるいはstring2、または両方がNULLでもかまいません。

string1 :

文字列。

string2 :

文字列。

戻り値 :

string1string2が両方NULL、あるいは同じ内容の場合はCUT_TRUE、そうでない場合はCUT_FALSE

1.0.5から


cut_get_source_directory ()

const char *        cut_get_source_directory            (void);

コマンドラインで指定されたソースディレクトリ名を返します。

戻り値 :

Cutterが所有する文字列。解放しないで下さい。

1.1.5から


cut_get_test_directory ()

const char *        cut_get_test_directory              (void);

コマンドラインで指定されたテストディレクトリ名を返します。

戻り値 :

Cutterが所有する文字列。解放しないで下さい。

1.1.4から


cut_inspect_sockaddr()

#define             cut_inspect_sockaddr(address)

addressを人が読みやすい文字列に整形します。整形された文字列の所有者はCutterです。

この関数はCUT_DISABLE_SOCKET_SUPPORTを定義すると無効にできます。

address :

詳細化されるソケットアドレス。

戻り値 :

Cutterが所有する整形されたソケットアドレス。解放しないで下さい。

1.1.1から


cut_inspect_string_array ()

const char *        cut_inspect_string_array            (const char **strings);

stringsを人が読みやすい文字列に整形します。整形された文字列の所有者はCutterです。

strings :

整形される文字列の配列。

戻り値 :

Cutterが所有する整形された文字列。解放しないで下さい。

cut_pop_backtrace ()

void                cut_pop_backtrace                   (void);

バックトレーススタックからバックトレースをポップします。

通常は直接使う必要はありません。cut_trace()で十分です。

1.0.6から


cut_push_backtrace ()

void                cut_push_backtrace                  (const char *expression);

expressionと現在のソースの場所をバックトレーススタックにプッシュします。

通常は直接使う必要はありません。cut_trace()で十分です。

expression :

呼び出されたことを記録される式。

1.0.6から


cut_set_actual()

#define             cut_set_actual(actual)

次の検証で使う詳細化した実際値オブジェクトを設定します。

期待値オブジェクトと実際値オブジェクトの両方が設定され、それらのdiffが必要な場合は自動的にdiffを生成します。

cut_set_expected()も見てください。

actual :

実測値オブジェクトの詳細。

1.0.9から


cut_set_expected()

#define             cut_set_expected(expected)

次の検証で使う詳細化した期待値オブジェクトを設定します。

期待値オブジェクトと実際値オブジェクトの両方が設定され、それらのdiffが必要な場合は自動的にdiffを生成します。

cut_set_actual()も見てください。

expected :

期待値オブジェクトの詳細。

1.0.9から


cut_test_fail ()

void                cut_test_fail                       (const char *system_message,
                                                         ...);

検証が失敗したらcut_test_fail()を呼んでください。cut_test_fail()は失敗数を増やし、現在のテストを中断します。

system_message :

テストフレームワーク指定の失敗メッセージ。

... :

省略可能な整形文字列。以降のパラメータが整形文字列に挿入されます。(printf()と同じ。)このパラメータは0.1.6から非推奨となっています。代わりにcut_set_message()を使ってください。

1.0.5から


cut_test_fail_va_list ()

void                cut_test_fail_va_list               (const char *system_message,
                                                         const char *user_message_format);

Warning

cut_test_fail_va_listはバージョン1.0.6から非推奨になりました。新しく書くコードでは使わないで下さい。代わりにcut_test_fail()を使ってください。

cut_test_fail_va_list()の動作についてはcut_test_fail()を見てください。user_message_formatは可変長引数の1つ前の引数です。

例:

void
my_assert(cut_boolean result,
          const gchar *user_message_format,
          ...)
{
    if (result) {
        cut_test_pass();
    } else {
        cut_test_fail_va_list("Fail!", user_message_format);
    }
}

system_message :

テストフレームワーク指定の失敗メッセージ。

user_message_format :

ユーザ指定の失敗メッセージ。

1.0.5から


cut_test_pass ()

void                cut_test_pass                       (void);

検証をパスしたらcut_test_pass()を呼んでください。cut_test_pass()は検証数を増やします。

1.0.5から


cut_trace()

#define             cut_trace(expression)

現在のファイル名、行番号、関数名、expressionを記憶し、expression内で検証が失敗した場合に表示します。expressionの多くは関数呼び出しになるでしょう。

expressionの戻り値を取得できないことに注意してください。

cut_trace()は以下の通りです。もし、cut_assert_not_null(object)が失敗したら、バックトレースには2行含まれます。cut_assert_not_null(object)とcreate_my_object("my-name")です。

例:

static MyObject *object;

static void
create_my_object(const char *name)
{
    object = my_object_new(name);
    cut_assert_not_null(object);
}

void
test_my_object_name(void)
{
    cut_trace(create_my_object("my-name"));
    cut_assert_equal_string("my-name",
                            my_object_get_name(object));
}

テストを読みやすくするためにcut_trace()を使ったマクロを書くかもしれません:

static MyObject *object;

static void
create_my_object_helper(const char *name)
{
    object = my_object_new(name);
    cut_assert_not_null(object);
}

#define create_my_object(...)                        \
    cut_trace(create_my_object_helper(__VA_ARGS__))

void
test_my_object_name(void)
{
    create_my_object("my-name");
    cut_assert_equal_string("my-name",
                            my_object_get_name(object));
}

expression :

呼び出されたことを記録される式。

1.0.5から


cut_trace_with_info_expression()

#define             cut_trace_with_info_expression(expression, info_expression)

cut_trace()cut_trace_with_info_expression()の違いは記録される式がexpressionと同じかどうかです。cut_trace_with_info_expression()はバックトレースの読みやすさのためにexpressionから情報を隠したいときに便利です。

cut_trace_with_info_expression()の例です。cut_assert_not_null(object)が失敗すると以下の2行を含んだバックトレースが得られます:

  • cut_assert_not_null(object)

  • create_my_object_helper("my-name")ではなくcreate_my_object("my-name")

もし、cut_trace_with_info_expression()ではなくcut_trace()を使った場合はcreate_my_object_helper("my-name")になります。もし、create_my_object_helper("my-name")が得られたら以下のように混乱してしまうかもしれません。「create_my_object_helper("my-name")はどこからきたんだ?test_my_object_name()はcreate_my_object("my-name")は使っているけど、create_my_object_helper("my-name")は使っていないぞ。」

例:

static MyObject *object;

static void
create_my_object_helper(const char *name)
{
    object = my_object_new(name);
    cut_assert_not_null(object);
}

#define create_my_object(...)                        \
    cut_trace_with_info_expression(                  \
        create_my_object_helper(__VA_ARGS__),        \
        create_my_object(__VA_ARGS__))

void
test_my_object_name(void)
{
    create_my_object("my-name");
    cut_assert_equal_string("my-name",
                            my_object_get_name(object));
}

expression :

呼び出されたことを記録される式。

info_expression :

呼び出されたと記録される式。

1.0.5から