ATF-C-API(3) | FreeBSD Library Functions Manual | ATF-C-API(3) |
名称
ATF_CHECK, ATF_CHECK_MSG, ATF_CHECK_EQ, ATF_CHECK_EQ_MSG, ATF_CHECK_STREQ, ATF_CHECK_STREQ_MSG, ATF_CHECK_ERRNO, ATF_REQUIRE, ATF_REQUIRE_MSG, ATF_REQUIRE_EQ, ATF_REQUIRE_EQ_MSG, ATF_REQUIRE_STREQ, ATF_REQUIRE_STREQ_MSG, ATF_REQUIRE_ERRNO, ATF_TC, ATF_TC_BODY, ATF_TC_BODY_NAME, ATF_TC_CLEANUP, ATF_TC_CLEANUP_NAME, ATF_TC_HEAD, ATF_TC_HEAD_NAME, ATF_TC_NAME, ATF_TC_WITH_CLEANUP, ATF_TC_WITHOUT_HEAD, ATF_TP_ADD_TC, ATF_TP_ADD_TCS, atf_tc_get_config_var, atf_tc_get_config_var_wd, atf_tc_get_config_var_as_bool, atf_tc_get_config_var_as_bool_wd, atf_tc_get_config_var_as_long, atf_tc_get_config_var_as_long_wd, atf_no_error, atf_tc_expect_death, atf_tc_expect_exit, atf_tc_expect_fail, atf_tc_expect_pass, atf_tc_expect_signal, atf_tc_expect_timeout, atf_tc_fail, atf_tc_fail_nonfatal, atf_tc_pass, atf_tc_skip — ATF に基づいたテストプログラムを書くための C API書式
#include < atf-c.h>ATF_CHECK( expression);
ATF_CHECK_MSG( expression, fail_msg_fmt, ...);
ATF_CHECK_EQ( expression_1, expression_2);
ATF_CHECK_EQ_MSG( expression_1, expression_2, fail_msg_fmt, ...);
ATF_CHECK_STREQ( string_1, string_2);
ATF_CHECK_STREQ_MSG( string_1, string_2, fail_msg_fmt, ...);
ATF_CHECK_ERRNO( exp_errno, bool_expression);
ATF_REQUIRE( expression);
ATF_REQUIRE_MSG( expression, fail_msg_fmt, ...);
ATF_REQUIRE_EQ( expression_1, expression_2);
ATF_REQUIRE_EQ_MSG( expression_1, expression_2, fail_msg_fmt, ...);
ATF_REQUIRE_STREQ( string_1, string_2);
ATF_REQUIRE_STREQ_MSG( string_1, string_2, fail_msg_fmt, ...);
ATF_REQUIRE_ERRNO( exp_errno, bool_expression);
ATF_TC( name);
ATF_TC_BODY( name, tc);
ATF_TC_BODY_NAME( name);
ATF_TC_CLEANUP( name, tc);
ATF_TC_CLEANUP_NAME( name);
ATF_TC_HEAD( name, tc);
ATF_TC_HEAD_NAME( name);
ATF_TC_NAME( name);
ATF_TC_WITH_CLEANUP( name);
ATF_TC_WITHOUT_HEAD( name);
ATF_TP_ADD_TC( tp_name, tc_name);
ATF_TP_ADD_TCS( tp_name);
atf_tc_get_config_var( tc, varname);
atf_tc_get_config_var_wd( tc, variable_name, default_value);
atf_tc_get_config_var_as_bool( tc, variable_name);
atf_tc_get_config_var_as_bool_wd( tc, variable_name, default_value);
atf_tc_get_config_var_as_long( tc, variable_name);
atf_tc_get_config_var_as_long_wd( tc, variable_name, default_value);
atf_no_error();
atf_tc_expect_death( reason, ...);
atf_tc_expect_exit( exitcode, reason, ...);
atf_tc_expect_fail( reason, ...);
atf_tc_expect_pass();
atf_tc_expect_signal( signo, reason, ...);
atf_tc_expect_timeout( reason, ...);
atf_tc_fail( reason);
atf_tc_fail_nonfatal( reason);
atf_tc_pass();
atf_tc_skip( reason);
解説
C ベースのテストプログラムは、常に次のテンプレートに従います:
... C 特有のインクルードは, ここに ... #include <atf-c.h> ATF_TC(tc1); ATF_TC_HEAD(tc1, tc) { ... 最初のテストケースのヘッダ ... } ATF_TC_BODY(tc1, tc) { ... 最初のテストケースの本体 ... } ATF_TC_WITH_CLEANUP(tc2); ATF_TC_HEAD(tc2, tc) { ... 2 番目のテストケースのヘッダ ... } ATF_TC_BODY(tc2, tc) { ... 2 番目のテストケースの本体 ... } ATF_TC_CLEANUP(tc2, tc) { ... 2 番目のテストケースのクリーンアップ ... } ATF_TC_WITHOUT_HEAD(tc3); ATF_TC_BODY(tc3, tc) { ... 3 番目のテストケースの本体 ... } ... 追加のテストケース ... ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tcs, tc1); ATF_TP_ADD_TC(tcs, tc2); ATF_TP_ADD_TC(tcs, tc3); ... 追加のテストケースを追加する ... return atf_no_error(); }
テストケースの定義
テストケースには、識別子があり、3 つの異なる部分からなります: ヘッダ、本体とオプションのクリーンアップルーチンで、それらのすべては、 atf-test-case(4) に記述されています。テストケースを定義するために、テストケースの名前を指定する単一のパラメータを取る、 ATF_TC(), ATF_TC_WITH_CLEANUP() または ATF_TC_WITHOUT_HEAD() マクロを使用することができます。 ATF_TC() は、テストケースのためのヘッダと本体を定義するために必要とされます、 ATF_TC_WITH_CLEANUP() は、テストケースのためのヘッダ、本体とクリーンアップを定義するために必要とされます、そして ATF_TC_WITHOUT_HEAD() は、テストケースのための本体だけに必要とされます。プログラムが実行されるとき、これらが、実行のためにテストケースをセットアップ しない ことに注意することは重要です。そうするために、後の登録は、 プログラムの初期化 で詳述されている ATF_TP_ADD_TC() マクロで必要とされます。後で、3 つの関数の手段によって本体の 3 つの部分を定義しなければなりません。それらのヘッダは、 ATF_TC_HEAD(), ATF_TC_BODY() と ATF_TC_CLEANUP() マクロから与えられ、それらのすべては、 ATF_TC() ATF_TC_WITH_CLEANUP() または ATF_TC_WITHOUT_HEAD() マクロとテストケースのデータへのポインタを保持する変数の名前に提供されるテストケースの名前を取ります。これらの各々に続いて、コードのブロックは、開き角括弧と閉じ角括弧に囲まれることが要求されます。
プログラムの初期化
ライブラリは、テストプログラムの main() 関数を容易に定義する方法を提供しています。利用者は、利用者自身で決して定義すべきではありませんが、利用者のためにそれを行うためにライブラリに依存します。これは、テストケースを保持するオブジェクトの名前が渡される、 ATF_TP_ADD_TCS() マクロを使用することによって行われます。すなわち、テストプログラムのインスタンス。この名前は、それが有効な変数値である限り、望むものは何でも指定できます。マクロの後で、テストプログラムが実行し、成功したエラーコードを返すテストケースを登録するために ATF_TP_ADD_TC() マクロを単に使用するべき、関数の本体を提供するが想定されます。このマクロの最初のパラメータは、前の呼び出しで提供された名前と一致します。 atf_no_error() 関数を使用して成功したステータスを返すことができます。
ヘッダの定義
テストケースのヘッダは、3 つのパラメータを取る、 atf_tc_set_md_var() メソッドを使用することによってメタデータを定義することができます。最初のものは、テストケースのデータへのポインタで、 2 番目のものは、設定されるメタデータの変数を指定し、 3 番目のものは、その値を指定します。それらの両方は、文字列です。設定変数
テストケースは、テストケースの 3 つの部分のうちのいずれでも呼び出すことができる、 bool atf_tc_has_config_var(), const char * atf_tc_get_config_var(), const char * atf_tc_get_config_var_wd(), bool atf_tc_get_config_var_as_bool(), bool atf_tc_get_config_var_as_bool_wd(), long atf_tc_get_config_var_as_long() と long atf_tc_get_config_var_as_long_wd() の手段によって現在の設定変数に読み込み専用のアクセスします。‘_wd’変異型は、変数が定義されないなら、返される変数のためのデフォルト値を取ります。‘_wd’接尾辞のない他の関数は、変数が定義されることを 必要 とします。
ソースディレクトリへのアクセス
‘srcdir’設定変数を問い合わせることによって 3 つの構成要素のうちのいずれかからテストケースのソースディレクトリへのパスを得ることができます。要求プログラム
ヘッダのみで利用可能な require.progs メタデータ変数に加えて、基本的な名前または単一のバイナリのフルパスを取る atf_tc_require_prog() 関数を使用することによってテストケースの本体の追加のプログラムもチェックすることができます。相対的なパスは、禁止されています。それが見つからないなら、テストケースは、自動的にスキップされます。テストケースの終了
テストケースは、本体がその終了に到着するとき、あらゆる致命的でないエラーが atf_tc_fail_nonfatal() を使用してあげられるまで、テストが passed を持っていると仮定されるポイントで、または atf_tc_pass(), atf_tc_fail() または atf_tc_skip() へのあらゆる明示的な呼び出しで、どちらかを終了させます。これらの 3 つの関数は、テストケースの実行を直ちに終了します。クリーンアップルーチンは、テストケースの終了の理由にかかわらず、その後、完全に自動的な方法で処理されます。atf_tc_pass() は、あらゆるパラメータを取りません。 atf_tc_fail(), atf_tc_fail_nonfatal() と atf_tc_skip() は、それぞれ、書式文字列となぜテストケースが失敗したか、または、スキップされたか説明する可変パラメータのリストを取ります。ユーザは、なぜテストが合格しなかったのか素早く知ることができるように、両方の場合で明瞭なエラーメッセージを提供することは非常に重要です。
期待値
前のセクションで説明されたものはすべて、テストケースの期待値がプログラマによって再定義されるとき、変更します。各テストケースは、いずれかの時点でテストケースの期待値が何かを記述する‘expect’と呼ばれる内部状態があります。この特性の値は、次のうちのいずれかによって実行の間に変更されるかもしれません:
- atf_tc_expect_death( reason, ...)
- 終了時の性質にかかわらず時期尚早に終了するとテストケースを予想します。
- atf_tc_expect_exit( exitcode, reason, ...)
- テストケースがきれいに終了すると予想します。 exitcode が‘-1’でないなら、 atf-run(1) は、テストケースの終了コードが、この呼び出しで提供されるものと一致することを確認します。そうでなければ、正確な値は、無視されます。
- atf_tc_expect_fail( reason, ...)
-
このモードで上げられた (致命的または致命的でない) あらゆる失敗は、記録されますが、しかしながら、そのような失敗は、失敗されたテストケースを報告しません。代わりに、テストケースは、きれいに終了し、‘expected failure’ (予期された失敗) として報告されます。この報告は、その一部として提供される
reason (理由) を含んでいます。エラーがこのモードで実行している間に上げられないなら、テストケースは、‘failed’ (失敗) として報告されます。
このモードは、テストでの実際の既知のバグを再現するために役に立ちます。開発者がバグを後で修正するときはいつでも、テストケースを新しい条件に調節しなければならないことを開発者に伝え、テストケースは、失敗を報告し始めます。この状況で、それは、例えば、目的の追跡のためにバグ番号として reason (理由) を設定するために、役に立ちます。
- atf_tc_expect_pass()
- これは、実行の通常のモードです。このモードで、あらゆる失敗は、ユーザにそういうものとして報告され、テストケースは、‘failed’ (失敗した) とマークされます。
- atf_tc_expect_signal( signo, reason, ...)
- シグナルの受け付けのために終了するとテストケースを予想します。 signo が‘-1’でないなら、 atf-run(1) は、テストケースを終了したシグナルが、この呼び出しで提供されるものと一致することを確認します。そうでなければ、正確な値は、無視されます。
- atf_tc_expect_timeout( reason, ...)
- そのタイムアウトより長く実行するテストケースを期待します。
共通のチェックのためのヘルパ関数
ライブラリは、複数の状況でとても手軽ないくつかのマクロを提供しています。これらは、与えられた文実行するか、または与えられた式を処理した後に、基本的にいくつかの条件をチェックし、条件が満たされないなら、それらは、失敗するようなテストケースを報告します。エラー状態になるとすぐにテストケースを直ちにアボートする‘REQUIRE’変異型のマクロは、 atf_tc_fail() 関数を呼び出すことによって検出されます。チェックされた条件が満たされないとき、今、テストケースの実行を継続しても意味がないときはいつでもこの変異型を使用します。他方では、‘CHECK’変異型は、 atf_tc_fail_nonfatal() 関数を使用して、それに遭遇するとすぐに失敗を報告しますが、あたかも何も起こらなかったかのように、テストケースの実行は、継続します。チェックされた条件がテストケースの結果のように重要であるときはいつでもこの変異型を使用しまが、アボートなしで同じの実行で続いてチェックすることができる他の条件があります。
さらに、‘MSG’変異型は、明示的に失敗メッセージを指定するために特別なパラメータのセットを取ります。この失敗メッセージは、 printf(3) フォーマッタ (formatter) によって書式化されます。
ATF_CHECK(), ATF_CHECK_MSG(), ATF_REQUIRE() と ATF_REQUIRE_MSG() は、式を取り、式が偽と評価するなら、失敗します。
ATF_CHECK_EQ(), ATF_CHECK_EQ_MSG(), ATF_REQUIRE_EQ() と ATF_REQUIRE_EQ_MSG() は、2 つの式を取り、2 つの評価された値が等しくないなら、失敗します。
ATF_CHECK_STREQ(), ATF_CHECK_STREQ_MSG(), ATF_REQUIRE_STREQ() と ATF_REQUIRE_STREQ_MSG() は、2 つの文字列を取り、2 つが文字単位で等しくないなら、失敗します。
ATF_CHECK_ERRNO() と ATF_REQUIRE_ERRNO() は、最初に、チェックが errno 変数で見つけることを予想するエラーコードを取り、 2 番目に、失敗した呼び出しと、評価が真なら、 errno が最初の値とチェックされなければならないことを意味するブール式を取ります。
使用例
次は、追加の操作を有効にする単一のテストケースで完全なテストプログラムを示します:
#include <atf-c.h> ATF_TC(addition); ATF_TC_HEAD(addition, tc) { atf_tc_set_md_var(tc, "descr", "Sample tests for the addition operator"); } ATF_TC_BODY(addition, tc) { ATF_CHECK_EQ(0 + 0, 0); ATF_CHECK_EQ(0 + 1, 1); ATF_CHECK_EQ(1 + 0, 1); ATF_CHECK_EQ(1 + 1, 2); ATF_CHECK_EQ(100 + 200, 300); } ATF_TC(string_formatting); ATF_TC_HEAD(string_formatting, tc) { atf_tc_set_md_var(tc, "descr", "Sample tests for the snprintf"); } ATF_TC_BODY(string_formatting, tc) { char buf[1024]; snprintf(buf, sizeof(buf), "a %s", "string"); ATF_CHECK_STREQ_MSG("a string", buf, "%s is not working"); } ATF_TC(open_failure); ATF_TC_HEAD(open_failure, tc) { atf_tc_set_md_var(tc, "descr", "Sample tests for the open function"); } ATF_TC_BODY(open_failure, tc) { ATF_CHECK_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1); } ATF_TC(known_bug); ATF_TC_HEAD(known_bug, tc) { atf_tc_set_md_var(tc, "descr", "Reproduces a known bug"); } ATF_TC_BODY(known_bug, tc) { atf_tc_expect_fail("See bug number foo/bar"); ATF_CHECK_EQ(3, 1 + 1); atf_tc_expect_pass(); ATF_CHECK_EQ(3, 1 + 2); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, addition); ATF_TP_ADD_TC(tp, string_formatting); ATF_TP_ADD_TC(tp, open_failure); ATF_TP_ADD_TC(tp, known_bug); return atf_no_error(); }
December 26, 2010 | FreeBSD |