This file is indexed.

/usr/share/gtk-doc/html/cutter/ja/features.html is in cutter-testing-framework-doc 1.1.7-1.1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>機能</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="index.html" title="Cutterリファレンスマニュアル">
<link rel="up" href="overview.html" title="Cutterの概要">
<link rel="prev" href="readme.html" title="はじめに">
<link rel="next" href="users.html" title="利用者">
<meta name="generator" content="GTK-Doc V1.15 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2"><tr valign="middle">
<td><a accesskey="p" href="readme.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
<td><a accesskey="u" href="overview.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">Cutterリファレンスマニュアル</th>
<td><a accesskey="n" href="users.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
</tr></table>
<div class="refentry" title="機能">
<a name="features"></a><div class="titlepage"></div>
<div class="refnamediv"><table width="100%"><tr>
<td valign="top">
<h2><span class="refentrytitle"><a name="features.top_of_page"></a>機能</span></h2>
<p>機能 — Cutterの機能</p>
</td>
<td valign="top" align="right"></td>
</tr></table></div>
<div class="refsect1" title="はじめに">
<a name="id549211"></a><h2>はじめに</h2>
<p>Cutterは以下のような単体テストフレームワークの基本的な機能を持っています。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>フィクスチャ</p></li>
<li class="listitem"><p>テスト登録コード不要</p></li>
<li class="listitem"><p>デバッグに便利な結果出力</p></li>
<li class="listitem"><p>豊富な検証機能</p></li>
</ul></div>
<p>Cutterは以下のようなテスト環境をもっと便利にする高度な機能もあります。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>複数のプラットフォーム対応</p></li>
<li class="listitem"><p>データ駆動テストのサポート</p></li>
<li class="listitem"><p>カバレッジのサポート</p></li>
<li class="listitem"><p>クラッシュ時のバックトレース出力</p></li>
<li class="listitem"><p>テスト結果の保存・復元</p></li>
<li class="listitem"><p>マルチプロセス・マルチスレッドのサポート</p></li>
<li class="listitem"><p>画像差分</p></li>
<li class="listitem"><p>...</p></li>
</ul></div>
</div>
<div class="refsect1" title="基本機能">
<a name="id554244"></a><h2>基本機能</h2>
<p>単体テストフレームワークが一般的に提供している機能について、Cutterがどのようにその機能を提供しているかについてを説明します。</p>
<div class="refsect2" title="フィクスチャ">
<a name="id554256"></a><h3>フィクスチャ</h3>
<p>単体テストフレームワークでいうフィクスチャとは、各テストを実行する前にテスト用データを用意するための仕組みのことです。これは、一般的には各テスト毎にsetup/teardownと呼ばれる初期化処理/終了処理を実行することによって実現します。</p>
<p>Cutterでは以下のようにテストプログラム中にcut_setup()/cut_teardown() 関数を定義すると、それらの関数が初期化処理/終了処理として扱われます。</p>
<pre class="programlisting">void
cut_setup (void)
{
   /* 初期化処理 */
}

void
cut_teardown (void)
{
   /* 終了処理 */
}</pre>
<p>また、Cutterではテストケース毎の初期化処理/終了処理のためにcut_startup()/cut_shutdown()もサポートしてます。</p>
<pre class="programlisting">void
cut_startup (void)
{
   /* テストケースの初期化処理 */
}

void
cut_shutdown (void)
{
   /* テストケースの終了処理 */
}</pre>
<p>これらの関数は以下のような順番で呼ばれます。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<p>cut_startup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
<p>cut_setup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="square"><li class="listitem"><p>テスト1実行</p></li></ul></div>
</li>
<li class="listitem"><p>cut_teardown()</p></li>
<li class="listitem">
<p>cut_setup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="square"><li class="listitem"><p>テスト2実行</p></li></ul></div>
</li>
<li class="listitem"><p>cut_teardown()</p></li>
<li class="listitem"><p>...</p></li>
</ul></div>
</li>
<li class="listitem"><p>cut_shutdown()</p></li>
</ul></div>
<p>また、実験的な機能ですが、テスト全体を実行する前、テスト全体を実行した後に呼び出す関数を登録することもできます。これらの関数をそれぞれwarmup/cooldownと呼んでいます。呼び出し順序はこうなります。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem">
<p>warmup実行</p>
<div class="itemizedlist"><ul class="itemizedlist" type="circle">
<li class="listitem">
<p>テストケース1のcut_startup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="square">
<li class="listitem">
<p>テストケース1のcut_setup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>テスト1-1実行</p></li></ul></div>
</li>
<li class="listitem"><p>テストケース1のcut_teardown()</p></li>
<li class="listitem">
<p>テストケース1のcut_setup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>テスト1-2実行</p></li></ul></div>
</li>
<li class="listitem"><p>テストケース1のcut_teardown()</p></li>
<li class="listitem"><p>...</p></li>
</ul></div>
</li>
<li class="listitem"><p>テストケース1のcut_shutdown()</p></li>
<li class="listitem">
<p>テストケース2のcut_startup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="square">
<li class="listitem">
<p>テストケース2のcut_setup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>テスト2-1実行</p></li></ul></div>
</li>
<li class="listitem"><p>テストケース2のcut_teardown()</p></li>
<li class="listitem">
<p>テストケース2のcut_setup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>テスト2-2実行</p></li></ul></div>
</li>
<li class="listitem"><p>テストケース2のcut_teardown()</p></li>
<li class="listitem"><p>...</p></li>
</ul></div>
</li>
<li class="listitem"><p>テストケース2のcut_shutdown()</p></li>
<li class="listitem"><p>...</p></li>
</ul></div>
</li>
<li class="listitem"><p>cooldown実行</p></li>
</ul></div>
<p>この機能は、テスト対象のライブラリがライブラリ初期化関数・終了関数を用意している場合に有用です。ただ、この機能は実験的な機能なのでここでその使い方を紹介するのは控えておきます。もし、使いたい場合は聞いてください。</p>
</div>
<hr>
<div class="refsect2" title="テスト登録コード不要">
<a name="id555565"></a><h3>テスト登録コード不要</h3>
<p>動的な言語用の単体テストフレームワークの多くでは明示的にテストを登録する必要はありません。自動的にテストメソッド・テスト関数などを見つけて実行します。しかし、C言語用の単体テストフレームワークの多くでは明示的にテストを登録する必要があります。</p>
<p>Cutterはテストを簡単に書けるようにするため、多くの動的な言語用の単体テストフレームワークのように自動的にテスト関数を見つけます。そのため、以下のように名前が「test_」からはじまる公開関数を定義するだけでその関数がテスト関数として認識されます。</p>
<pre class="programlisting">void test_my_function (void);

void
test_my_function (void)
{
    /* テスト関数 */
}</pre>
</div>
<hr>
<div class="refsect2" title="デバッグに便利な結果出力">
<a name="id555592"></a><h3>デバッグに便利な結果出力</h3>
<p>Cuterは迅速に問題の確認・修正が行えるようにテスト結果を出力します。具体的には以下のように出力を行います。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>問題がない部分はシンプルに</p></li>
<li class="listitem"><p>問題がある部分は冗長に</p></li>
</ul></div>
<p>まず、問題がない部分をシンプルに表示する(時には何も表示しない)ことにより大事な情報が埋もれてしまうことを防ぎます。</p>
<p>また、問題がある部分はどのような問題があるかを判断するために、知っている情報をできるだけ多く表示します。</p>
<p>例えば、文字列が同じ内容かを比較するテストで文字列が異なって場合を考えます。Cutterは期待値と実測値を並べて表示します。これによりどの部分が異なるかを目視で確認しやすくなります。</p>
<pre class="programlisting">expected: &lt;abc def ghi jkl&gt;
 but was: &lt;abc DEF ghi jkl&gt;</pre>
<p>もし、これがずれて表示されていたり、同じ行に表示されているとどこが異なるかを見つけるのは大変になります。</p>
<pre class="programlisting">expected: &lt;abc def ghi jkl&gt;
but was: &lt;abc DEF ghi jkl&gt;

&lt;abc def ghi jkl&gt; is expected but was &lt;abc DEF ghi jkl&gt;</pre>
<p>また、必要ならば期待値と実測値のdiffを表示して具体的にどこが異なるのかも示します。</p>
<pre class="programlisting">expected: &lt;abc def ghi jkl&gt;
 but was: &lt;abc DEF ghi jkl&gt;

diff:
- abc def ghi jkl
?     ^^^
+ abc DEF ghi jkl
?     ^^^</pre>
<p>このように、Cutterにはテストが失敗した時に迅速に問題を確認するための工夫が施されています。これにより、開発者が迅速に問題を修正することを支援します。</p>
</div>
<hr>
<div class="refsect2" title="豊富な検証機能">
<a name="id555674"></a><h3>豊富な検証機能</h3>
<p>xUnit系の単体テストフレームワークではテスト対象が期待する動作をしているかを検証するために、assertionと呼ばれる検証機能を提供します。例えば、一般的には以下のような検証機能があります。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>assert: 検証対象が真の値であることを検証</p></li>
<li class="listitem"><p>assert_equal: 実測値が期待値と等しいことを検証</p></li>
</ul></div>
<p>Cutterでは、以下の検証機能が上記の検証機能に対応します。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>cut_assert()</p></li>
<li class="listitem"><p>cut_assert_true(): 機能はcut_assert()と同じだが「真の値」であることを明示(自己記述的なためこちらの利用を推奨)</p></li>
<li class="listitem"><p>cut_assert_equal_int()</p></li>
<li class="listitem"><p>cut_assert_equal_uint()</p></li>
<li class="listitem"><p>cut_assert_equal_string()</p></li>
<li class="listitem"><p>...</p></li>
</ul></div>
<p>Cutterは上記のような一般的な検証機能以外にも様々な検証機能が組み込みで提供しているので、より簡単にテストを書くことができます。例えば、以下のような検証機能を提供しています。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>cut_assert_errno(): errnoが0であることを検証</p></li>
<li class="listitem"><p>cut_assert_match(): 実測値の文字列が指定した正規表現にマッチすることを検証</p></li>
<li class="listitem"><p>cut_assert_path_exist(): 指定したパスが存在することを検証</p></li>
<li class="listitem"><p>...</p></li>
</ul></div>
<p>
  検証機能の一覧はリファレンスマニュアルの
  検証
  や
  GLibサポート付きの検証
  を見てください。
</p>
</div>
</div>
<div class="refsect1" title="高度な機能">
<a name="id555815"></a><h2>高度な機能</h2>
<p>一部の単体テストフレームワークが提供している機能のCutterでの提供の仕方、および、どの単体テストフレームワークも提供していないCutter独特の機能について提供について説明します。</p>
<div class="refsect2" title="複数のプラットフォーム対応">
<a name="id555827"></a><h3>複数のプラットフォーム対応</h3>
<p>現在、以下のプラットフォームでの動作を確認しています。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>GNU/Linux</p></li>
<li class="listitem"><p>FreeBSD</p></li>
<li class="listitem"><p>Mac OS X</p></li>
<li class="listitem"><p>Windows (MinGW)</p></li>
</ul></div>
</div>
<hr>
<div class="refsect2" title="データ駆動テストのサポート">
<a name="id555872"></a><h3>データ駆動テストのサポート</h3>
<p>複数のデータに対して同じテストを実行する場合があります。例えば、以下のような場合が考えられます。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>複数の入力パターンがあり、それらを網羅的にテストする場合</p></li>
<li class="listitem"><p>複数のバックエンドを抽象化し、どのバックエンドを利用している場合でも同じインターフェイスで扱えるライブラリをテストする場合。(cairoやDBIなど)</p></li>
</ul></div>
<p>このような場合、テスト自体は1つだけ定義し、各テストデータに対してそのテストを実行することで効率的にテストを作成することができます。このようなテストの仕方はデータ駆動テストと呼ばれています。</p>
<p>
  Cutterでのデータ駆動テストの書き方については
  cut_add_data()
  を見てください。
</p>
<p>データ駆動テストの場合はテストは以下のような流れで実行されます。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>テストデータ生成関数呼び出し</p></li>
<li class="listitem">
<p>cut_setup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem"><p>テストデータ1を使ってテスト実行</p></li></ul></div>
</li>
<li class="listitem"><p>cut_teardown()</p></li>
<li class="listitem">
<p>cut_setup()</p>
<div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem"><p>テストデータ2を使ってテスト実行</p></li></ul></div>
</li>
<li class="listitem"><p>cut_teardown()</p></li>
<li class="listitem"><p>...</p></li>
</ul></div>
</div>
<hr>
<div class="refsect2" title="カバレッジのサポート">
<a name="id555994"></a><h3>カバレッジのサポート</h3>
<p>カバレッジ率はどの程度テストを網羅的に行っているかを示す指標になります。</p>
<p>CutterはGCCを使用したカバレッジ測定を支援するためのM4マクロを提供しています。GNU Autoconf/GNU Automakeを利用している場合はこのM4マクロを利用することにより、カバレッジ測定環境を簡単にビルドシステムに組み込むことができます。</p>
<p>
  詳しくは
  <a class="link" href="readme.html" title="はじめに">README.ja</a><a class="link" href="tutorial.html" title="チュートリアル">チュートリアル</a>
  のAC_CHECK_COVERAGEについて書かれている部分を見てください。
</p>
</div>
<hr>
<div class="refsect2" title="クラッシュ時のバックトレース出力">
<a name="id556028"></a><h3>クラッシュ時のバックトレース出力</h3>
<p>C言語・C++言語で実装されたプログラムではSegmentation Faultでプログラムが異常終了することは珍しくありません。この時、CutterはSEGV シグナルが発生した時点でのバックトレースの取得を試みます。取得できた場合はバックトレースを出力してから終了します。もちろん、この時点でテストプロセスがなにかしら破壊されているので、必ずしもバックトレースを取得できるわけではありません。</p>
<p>問題の詳細を調べるには、GDBなどのデバッガで処理を追いかけていく必要がありますが、バックトレースをデバッグの最初の足がかりとして利用することができます。</p>
</div>
<hr>
<div class="refsect2" title="テスト結果の保存・復元">
<a name="id556049"></a><h3>テスト結果の保存・復元</h3>
<p>ソフトウェアの品質を確認する方法として以下のような方法があります。</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc">
<li class="listitem"><p>テスト状況とバグ発見数の推移を測定</p></li>
<li class="listitem"><p>テスト状況とバグ報告数の推移を測定</p></li>
<li class="listitem"><p>テスト状況とソース規模の推移を測定</p></li>
</ul></div>
<p>例えば、テストが増えているのにバグ発見数が少ない場合は、効率の悪いテストを行っている、あるいはもともとテスト対象の品質が高かったということが考えられます。テストが増えているのにバグ報告数が伸びている場合は的外れなテストを行っているかもしれません。ソース規模が大きくなっているのにテストが増えていない場合はテスト不足が考えられます。</p>
<p>このように、その時点でのテスト状況だけではなく、過去のテスト結果も利用して時系列でソフトウェアの開発状況を分析することにより、ソフトウェアの品質向上に役立てることができる場合があります。</p>
<p>Cutterはテスト結果をXMLとしてファイルに保存することができます。また、保存したXMLを読み込んでテスト結果を復元することができます。</p>
<p>まだ実装されていませんが、保存したテスト結果を読み込んで、時系列のグラフとしてレポートを出力する機能の実装を予定しています。</p>
</div>
<hr>
<div class="refsect2" title="マルチプロセス・マルチスレッドのサポート">
<a name="id556110"></a><h3>マルチプロセス・マルチスレッドのサポート</h3>
</div>
</div>
</div>
<div class="footer">
<hr>
          Generated by GTK-Doc V1.15</div>
</body>
</html>