| Cutterリファレンスマニュアル | ||||
|---|---|---|---|---|
| Top | 説明 | ||||
void cut_test_pass (void); void cut_test_fail (const char *system_message, ...); void cut_test_fail_va_list (const char *system_message, const char *user_message_format); #define CUT_RELATIVE_PATH void cut_push_backtrace (const char *expression); void cut_pop_backtrace (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
void cut_test_pass (void);
検証をパスしたらcut_test_pass()を呼んでください。cut_test_pass()は検証数を増やします。
1.0.5から
void cut_test_fail (const char *system_message,
...);
検証が失敗したらcut_test_fail()を呼んでください。cut_test_fail()は失敗数を増やし、現在のテストを中断します。
|
テストフレームワーク指定の失敗メッセージ。 |
|
省略可能な整形文字列。以降のパラメータが整形文字列に挿入されます。(printf()と同じ。)このパラメータは0.1.6から非推奨となっています。代わりにcut_set_message()を使ってください。 |
1.0.5から
void cut_test_fail_va_list (const char *system_message,
const char *user_message_format);
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);
}
}
|
テストフレームワーク指定の失敗メッセージ。 |
|
ユーザ指定の失敗メッセージ。 |
1.0.5から
# 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から
void cut_push_backtrace (const char *expression);
expressionと現在のソースの場所をバックトレーススタックにプッシュします。
通常は直接使う必要はありません。cut_trace()で十分です。
|
呼び出されたことを記録される式。 |
1.0.6から
void cut_pop_backtrace (void);
バックトレーススタックからバックトレースをポップします。
通常は直接使う必要はありません。cut_trace()で十分です。
1.0.6から
#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));
}
|
呼び出されたことを記録される式。 |
1.0.5から
#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));
}
|
呼び出されたことを記録される式。 |
|
呼び出されたと記録される式。 |
1.0.5から