/* -*- Indented-Text -*- */
/* Copyright (C) 2003, 2010 TSUTSUMI Kikuo.
This file is part of the CCUnit Library.
The CCUnit Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
The CCUnit Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the CCUnit Library; see the file COPYING.LESSER.
If not, see
*/
/* $Id$ */
/**
@english
@page cookbook CCUnit Cookbook
@japanese
@page cookbook CCUnit クックブック
@endif
@~english
Here is a short cookbook to help you get started.
@~japanese
これは CCUnit を使い始めるにあたって、
理解の助けとなるような短いクックブックです。
@~
@english
[see also Japanese documents]
@japanese
[see also English documents]
@endif
@english
@section simple_test_case Simple Test Case
@japanese
@section simple_test_case シンプルなテストケース
@endif
@~english
Tests in CCUnit can be run automatically. They are
easy to set up and once you have written them, they are
always there to help you keep confidence in the quality of
your code.
@~japanese
CCUnitを使ったテストは自動的に実行することができます。
CCUnit のテストは簡単にセットアップすることができ、
一度テストを書いてしまえば、
いつでもプログラムの品質を信頼できるものに保つことができるでしょう。
@~
@~english
To make a simple test, here is what you do:
@~japanese
単純なテストを作るには、次のようにします。
@~
- @~english Create a test function
@~japanese テスト関数を作る
@~
- @~english When you want to check a value, call
@~japanese 値をチェックしたい場合は、@~
@link CCUNIT_ASSERT() CCUNIT_ASSERT(bool) @endlink
@~english and pass a bool that is true if the test succeeds
@~japanese を呼び出して、
もしテストが成功するなら真を返すような真偽値を渡します@~
@~english ASSERT macro is listed in others as well in
@link Assertions Making assertions @endlink.
@~japanese ASSERT 関係のマクロは他にも
@link Assertions Making assertions @endlink
にリストしてあります。
@~
@~english
For example, to test that the sum of two complex number
which is the sum of the values of two complex numbers,
write:
@~japanese
例えば、二つの複素数の合計が、
二つの複素数の値を加算した値と同じであることをテストするとします。
(ここで使用するサンプルプログラムは
examples/complex ディレクトリにあります。)
@~
@~english
This sample program is in the examples/complex directory.
@~
@code
void test_complex_add ()
{
complex_t c10_1 = { 10.0, 1.0 };
complex_t c1_1 = { 1.0, 1.0 };
complex_t result;
complex_t c11_2 = { 11.0, 2.0 };
CCUNIT_ASSERT (complex_equals (&c11_2, complex_add (&result, &c10_1, &c1_1)));
}
@endcode
@~english
That was a very simple test. Ordinarily, you'll have many
little test cases that you'll want to run on the same set of
objects. To do this, use a fixture.
@~japanese
これは大変単純なテストです。
通常、同じデータのセットで走らせるために、
たくさんの小さなテストケースを作らなければならないでしょう。
そこでフィクスチャ(備品)を使います。
@~
@english
@section fixture Fixture
@japanese
@section fixture フィクスチャ
@endif
@~english
What if you have two or more tests that operate on the same
similar set of objects?
@~japanese
もし二つ以上のテストがあるなら、
同じ類似のデータのセットで操作するのではないでしょうか。
@~
@~english
Tests need to run against the background of a known set of
objects. This set of objects is called a test fixture. When
you are writing tests you will often find that you spend
more time writing the code to set up the fixture than you do
in actually testing values.
@~japanese
テストは周知のデータのセットを背景にして実行される必要があります。
このデータのセットをフィクスチャと呼ぶことにします。
テストを書いていると、
実際のテストする値をフィクスチャにセットアップするコードを書く方に、
より時間をかけていることに気づくことがよくあります。
@~
@~english
Often, you will be able to use the same fixture for several
different tests. Each case will send slightly different
messages or parameters to the fixture and will check for
different results.
@~japanese
多くの場合、いくつかの異なったテストのために同じフィクスチャを使うことができます。
それぞれのテストケースは少し異なったメッセージ、
あるいはパラメータをフィクスチャに送り、
異なる結果を調べます。
@~
@~english
When you have a common fixture, here is what you do:
@~japanese
もし共通するフィクスチャがあれば、こんなふうにすることになります。
@~
- @~english
Create a @link CCUnitTestCase TestCase @endlink object
@~japanese
@link CCUnitTestCase TestCase @endlink 構造体にメモリを割り当てます
(以降、構造体に割り当てたメモリを、オブジェクトと呼ぶことにします)
@~
- @~english
Add an global variable for each part of the fixture
@~japanese
フィクスチャのそれぞれの部分に大域変数を追加します
@~
- @~english
Write
setUp()
function to initialize the valiables
@~japanese
setUp()
関数を書いて変数を初期化します
@~
- @~english
Write
tearDown()
to release any permanent
resources you allocated in setUp
@~japanese
tearDown()
関数を書いてsetUp
で割り当てた永続的リソースを解放します
@~
- @~english
Create a @link CCUnitTestFixture TestFixture @endlink object
@~japanese
@link CCUnitTestFixture CCUnitTestFixture @endlink
構造体にメモリを割り当てます
@~
- @~english
Add @link CCUnitTestCase TestCase @endlink objects to fixture object
@~japanese
@link CCUnitTestCase TestCase @endlink オブジェクトを
@link CCUnitTestFixture TestFixture @endlink
フィクスチャオブジェクトに登録します。
@~
@~english
For example, to write several test cases, first create a
fixture:
@~japanese
例えば、いくつかのテストケースを書く場合、
最初にフィクスチャを作成します。
@~
@code
//** TEST CASE: complex number test *\/
#include "complex.h"
static complex_t* s10_1;
static complex_t* s1_1;
static complex_t* s11_2;
void setUp_complex_test ()
{
s10_1 = complex_new (10, 1);
s1_1 = complex_new (1, 1);
s11_2 = complex_new (11, 2);
}
void tearDown_complex_test ()
{
complex_delete (s10_1);
complex_delete (s1_1);
complex_delete (s11_2);
}
...
CCUnitTestFixture* fixture;
fixture = ccunit_newTestFixture ("complex test",
CCUNIT_NEWTESTFUNC(setUp_complex_test),
CCUNIT_NEWTESTFUNC(tearDown_complex_test));
@endcode
@~english
Once you have the Fixture in place, you can write as complex
Test Cases as you'd like.
@~japanese
一度決まったところにフィクスチャを書いてしまえば、
あなたが好きなように複素数のテストケースを書くことができます。
@~
@english
@section test_case Test Case
@japanese
@section test_case テストケース
@endif
@~english
How do you write and invoke an individual test case when you
have a Fixture?
@~japanese
フィクスチャを一つ書いたとして、
どうやって個々のテストケースを書いて実行すれば良いでしょうか。
@~
@~english
For example, to test the equality of two complex number,
write:
@~japanese
例えば、二つの複素数が等しい(または等しくない)ことをテストするには、
次のように書きます。
@~
@code
void test_complex_equals ()
{
CCUNIT_ASSERT_TEST_OBJ (s10_1, complex_equals, s10_1, complex_to_string);
CCUNIT_ASSERT_TEST_OBJ (s10_1, !complex_equals, s1_1, complex_to_string);
}
...
ccunit_addNewTestCase (fixture,
"test_complex_equals",
"complex equals test",
test_complex_equals);
@endcode
@~english
One may create and run objects for each test case like this:
@~japanese
一つには次のように、
フィクスチャを作成してそれぞれのテストケースを実行させることができます。
@~
@code
CCUnitTestResult* result;
result = ccunit_runTestFixture (fixture);
@endcode
@~english
When the test fixture is run, that specific test functions
will be run. This is not a useful thing to do, however, as
no diagnostics will be displayed. One will normally use a
@link ExecutingTest TestRunner @endlink (see below) to
display the results.
@~japanese
テストフィクスチャが実行されると、
特定のテスト関数が呼び出されます。
これはあまり便利ではありません、
なぜなら、診断が表示されないからです。
通常は @link ExecutingTest TestRunner @endlink
(@ref test_runner 後述)
で結果を表示します。
@~
@~english
Once you have several tests, organize them into a suite.
@~japanese
一度いくつかのテストを作ったら、
それらをスーツに整理します。
@~
@english
@section suite Suite
@japanese
@section suite スーツ
@endif
@~english
How do you set up your tests so that you can run them all at once?
@~japanese
一度にテストを実行することができるように準備するには、
どのようにしたらいいでしょうか?
@~
@~english
CCUnit provides a @link CCUnitTestSuite TestSuite @endlink
module that runs any number of TestCases together.
@~japanese
CCUnit はいくつもの @link CCUnitTestCase TestCases @endlink
を一緒に実行する
@link CCUnitTestSuite TestSuite @endlink モジュールを提供します。
@~
@~english
You saw, above, how to run test fixture.
@~japanese
テストフィクスチャを実行する方法は上述しました。
@~
@~english
To create a suite of two or more tests, you do the following:
@~japanese
二つ以上のテストを含む一つのスーツを作るには、次のようにします。
@~
@code
CCUnitTestSuite* suite;
CCUnitTestFixture* fixture;
CCUnitTestResult* result;
suite = ccunit_newTestSuite ("Complex test suite");
fixture = ccunit_newTestFixture ("Complex Tests",
CCUNIT_NEWTESTFUNC(setUp_complex_test),
CCUNIT_NEWTESTFUNC(tearDown_complex_test));
ccunit_addNewTestCase (fixture, "test_complex_equals", "complex equals test",
test_complex_equals);
ccunit_addNewTestCase (fixture, "test_complex_add", "complex add test",
test_complex_add);
ccunit_addNewTestCase (fixture, "test_complex_sub", "complex sub test",
test_complex_sub);
ccunit_addTestFixture (suite, fixtuer);
result = ccunit_runTestSuite (suite, NULL);
@endcode
@~english
@link CCUnitTestSuite TestSuites @endlink don't only have to
contain @link CCUnitTestFixture TestFixtures @endlink. They
can contain any object that implements the @link CCUnitTest
Test @endlink interface. For example, you can create a
@link CCUnitTestSuite TestSuite @endlink
(complex_add_sub_suite ()
) in your code and I
can create one in mine
(complex_mul_div_suite ()
), and we can run them together by
creating a @link CCUnitTestSuite TestSuite @endlink that
contains both:
@~japanese
@link CCUnitTestSuite TestSuites @endlink は
@link CCUnitTestFixture TestFixtures @endlink
を含むだけではありません。
@link CCUnitTestSuite TestSuites @endlink 自身を含むこともできます。
例えば、あなたはあなたのコードに @link CCUnitTestSuite TestSuite @endlink
(complex_add_sub_suite ()
)
を作ることができ、
そして私は私のスーツ
(complex_mul_div_suite ()
)
を作ることができます、
そして私達は両方ともを含んでいる @link CCUnitTestSuite TestSuite @endlink
を作って一緒にそれぞれのスーツを動かすことができるのです。
@~
@code
CCUnitTestSuite* suite;
CCUnitTestResult* result;
suite = ccunit_newTestSuite ("Complex add/sub/mul/div test suite");
ccunit_addTestSuite (suite, complex_add_sub_suite ());
ccunit_addTestSuite (suite, complex_mul_div_suite ());
result = ccunit_runTestSuite(suite, NULL);
@endcode
@english
@section test_runner TestRunner
@japanese
@section test_runner テストランナー
@endif
@~english
How do you run your tests and collect their results?
@~japanese
どうやってテストを実行し、その結果を集めたら良いでしょうか。
@~
@~english
Once you have a test suite, you'll want to run it. %CCUnit
provides tools to define the suite to be run and to display
its results. You make your suite accessible to a @link
CreatingTestSuite ccunit_makeSuite @endlink tool that generate a
creating test suite code.
@~japanese
一つテストスーツを書いたら、
それを実行したいでしょう。
CCUnit はスーツを実行するために定義し、
結果を表示するためのツールを提供します。
スーツを @link CreatingTestSuite ccunit_makeSuite @endlink
ツールに入力できるような形式で書くことで、
テストスーツを作成するコードを自動的に生成することができます。
@~
@~english
For example, to make a ComplexTest suite available to a
@link CreatingTestSuite ccunit_makeSuite @endlink,
excute the following tool to
testComplex.c:
@~japanese
例えば、ComplexTest スーツを
@link CreatingTestSuite ccunit_makeSuite @endlink
を使って使用できるようにするには、
以下のツールを testComplex.c に実行します。
@~
@code
$ ccunit_makeSuite -f complex_suite -o suiteComplex.c testComplex.c
@endcode
@anchor test_runner_code
@~english
@~japanese
complex_suite
という関数が定義された、
suiteComplex.c
というファイルが作成されます。
@~
@~english
To use the TestRunner, include the header files for the tests in runTest.c:
@~japanese
TestRunner を使用するには、
例えば runTest.c でテストのためのファイルのヘッダをインクルードします。
@~
@code
#include
#include
@endcode
@~english
And call to
@link ccunit_runTestRunner()
ccunit_runTestRunner (CCUnitTestRunner*, CCUnitTestSuite *) @endlink
in the main()
function:
@~japanese
そして@link ccunit_runTestRunner()
ccunit_runTestRunner (CCUnitTestRunner*, CCUnitTestSuite *) @endlink
をmain()
関数で実行します。
@~
@code
extern CCUnitTestSuite* complex_suite(const char* name);
int main( int argc, char **argv)
{
CCUnitTestRunner* runner;
CCUnitTestSuite* suite;
runner = ccunit_newTestRunner (stdout);
suite = complex_suite ("complex test suite");
return ccunit_runTestRunner (runner, suite);
}
@endcode
@~english
The @link ExecutingTest TestRunner @endlink will run the tests.
If all the tests pass, you'll get an informative message.
If any fail, you'll get the following information:
@~japanese
@link ExecutingTest TestRunner @endlink はテストを実行します。
もしすべてのテストがパスすれば、その情報のメッセージが表示されます。
もしどれかが失敗すれば、それについて以下のような情報が表示されます。
@~
- @~english
The name of the source file that contains the test
@~japanese
テストを含んでいるソースファイル名
@~
- @~english
The line number where the failure occurred
@~japanese
失敗が起こった行番号
@~
- @~english
The name of the test case that failed
@~japanese
失敗したテストケースの名前
@~
- @~english
All of the text inside the call to
CCUNIT_ASSERT ()
which detected the failure
@~japanese
失敗を検知したCCUNIT_ASSERT ()
が呼び出された時の条件の文字列。
@~
@english
@section helper_macros Helper Tool
@japanese
@section helper_macros ヘルパーツール
@endif
@~english
As you might have noticed, implementing the suite
()
function of fixture is a repetitive and error
prone task. A @ref CreatingTestSuite set of functions and
command have been created to automatically implements the
suite()
function.
@~japanese
お気づきのように、フィクスチャの suite ()
関数を実装するのは、
反復的で間違いやすい作業です。
@ref CreatingTestSuite の関数のセットとコマンドはsuite ()
関数の実装を自動的に作成することができます。
@~
@dontinclude complex/testComplex.c
@~english
The following code is a rewrite of ComplexTest using those command:
@~japanese
以下のコードはそれらのコマンドが使うようにComplexTestを書換えたものです。
@~
@code
#include
@endcode
@~english
First, you declare the fixture, passing the test fixture
name to the javaDoc style comment, which consist of a
C-style comment block starting with two *'s:
@~japanese
最初に、フィクスチャを宣言します。
これはjavaDocスタイルのコメント内にフィクスチャの名前を記述します。
javaDocスタイルのコメントとは C スタイルのコメントブロックの開始が
二つのアスタリスク ** になっているものです。
@~
@code
//** test case: complex number test *\/
@endcode
@~english
The function to make @link CCUnitTestSuite TestSuite
@endlink is ccunit_suite
.
But, it can be changed to another
name by the -f
option of the
ccunit_makeSuite
command, too.
Then, you define each test case of the fixture with prefix
test
, setUp
,
tearDown
:
@~japanese
@link CCUnitTestSuite TestSuite @endlink
を作成する関数は ccunit_suite
です、
しかし ccunit_makeSuite
コマンドの
-f
オプションで別の名前に変えることもできます。
そして、フィクスチャのテストケースにはそれぞれ名前の先頭に、
test
, setUp
,
tearDown
をつけてください。
@~
@code
#include
static complex_t* s10_1;
static complex_t* s1_1;
static complex_t* s11_2;
void setUp_complex_test ()
{
s10_1 = complex_new (10, 1);
s1_1 = complex_new (1, 1);
s11_2 = complex_new (11, 2);
}
void tearDown_complex_test ()
{
complex_delete (s10_1);
complex_delete (s1_1);
complex_delete (s11_2);
}
//** test equals *\/
void test_complex_equals ()
{
CCUNIT_ASSERT_TEST_OBJ (s10_1, complex_equals, s10_1, complex_to_string);
CCUNIT_ASSERT_TEST_OBJ (s10_1, !complex_equals, s1_1, complex_to_string);
}
//** test add *\/
void test_complex_add ()
{
complex_t c10_1 = { 10.0, 1.0 };
complex_t c1_1 = { 1.0, 1.0 };
complex_t result;
complex_t c11_2 = { 11.0, 2.0 };
CCUNIT_ASSERT (complex_equals (&c11_2, complex_add (&result, &c10_1, &c1_1)));
}
//** test sub *\/
void test_complex_sub ()
{
complex_t c9_0 = { 9, 0 };
complex_t result;
CCUNIT_ASSERT_TEST_OBJ (&c9_0, complex_equals,
complex_sub (&result, s10_1, s1_1),
complex_to_string);
}
@endcode
@~english
Finally, you end the fixture declaration:
@~japanese
最後に、フィクスチャの終りを宣言します。
@~
@code
//** end test case *\/
@endcode
@~english
To generate creating suite function code, run
ccunit_makeSuite
tool.
@~japanese
スーツ作成関数のコードを生成するには、
ccunit_makeSuite
ツールを実行します。
@~
@code
$ ccunit_makeSuite -f complex_suite -o suiteComplex.c testComplex.c
$ cat suiteComplex.c
#include
#include
#include
//* test fixture: complex number test *\/
//* setUp_complex_test *\/
extern void setUp_complex_test ();
//* tearDown_complex_test *\/
extern void tearDown_complex_test ();
//* test_complex_equals *\/
extern void test_complex_equals ();
//* test_complex_add *\/
extern void test_complex_add ();
//* test_complex_sub *\/
extern void test_complex_sub ();
static CCUnitTestFunc fx_001_cases[] = {
{
"test_complex_equals",
"test equals",
test_complex_equals
},
{
"test_complex_add",
"test add",
test_complex_add
},
{
"test_complex_sub",
"test sub",
test_complex_sub
},
{
NULL, NULL, NULL
},
};
static CCUnitTestFixtureDfn fx_001 = {
{ ccunitTypeFixture },
"complex number test",
{
"setUp_complex_test",
"setUp_complex_test",
setUp_complex_test
},
{
"tearDown_complex_test",
"tearDown_complex_test",
tearDown_complex_test
},
fx_001_cases,
};
static CCUnitTestDfn* suite_001_test[] = {
&fx_001.test,
NULL,
};
static CCUnitTestSuiteDfn suite_001 = {
{ ccunitTypeSuite },
"",
suite_001_test
};
CCUnitTestSuite* complex_suite (const char* name)
{
if (!suite_001.name[0])
suite_001.name = name;
return ccunit_newTestSuiteFromDfn (&suite_001);
}
$
@endcode
@english
@section post_build_check Post-build check
@japanese
@section post_build_check ビルド後のチェック
@endif
@~english
Now that we have our unit tests running, how about
integrating unit testing to our build process ?
@~japanese
さあユニットテストを実行する準備ができました。
ではビルドプロセスにユニットテストを統合するにはどうしたらい
いでしょう。
@~
@~english
To do that, the application must returns a value different than 0 to indicate that
there was an error.
@~japanese
そうするには、アプリケーションは、エラーが発生したことを示す
0以外の値を返さなければなりません。
@~
@~english
@link ccunit_runTestRunner() ccunit_runTestRunner() @endlink returns
a integer indicating if the run was successful.
@~japanese
@link ccunit_runTestRunner() ccunit_runTestRunner() @endlink
は、実行が成功したかどうかを示す整数を返します。
@~
@~english
Updating our main programm, we obtains:
@~japanese
次のようにメインプログラムを更新します。
@~
@code
#include
int main (int argc, char** argv)
{
CCUnitTestRunner* runner;
CCUnitTestSuite* suite;
int wasSucessful;
runner = ccunit_newTestRunner (stdout);
suite = ccunit_suite ();
wasSucessful = ccunit_runTestRunner (runner, suite);
return wasSucessful;
}
@endcode
@~english
Now, you need to run your application after compilation.
The sample program made in the above is in the examples/complex directory.
@~japanese
それではアプリケーションをコンパイルした後に実行してみましょう。
以上で作成したサンプルプログラムは examples/complex ディレクトリにあります。
@~
*/