スポンサーリンク

このドキュメントの内容は、以下の通りです。

はじめに

パソコンやスマホで使われるソフトウェアは、いろいろなテストが行われて、出荷されています。ソフトウェアのテストをしない場合、ソフトウェアにバグがあるまま出荷されてしまいます。ソフトウェアのテストを行っていても、十分なテストを行えていなければ、やはりバグが残っているかもしれません。

ソフトウェアは、たくさんの分岐があり、すべてのパターンをテストするのは難しいかもしれません。

コードカバレッジとは

コードカバレッジ(code coverage)とは、日本語というとコード網羅率(もうらりつ)です。コードカバレッジは、ソフトウェアテストの1つの尺度です。 コードカバレッジは、ソフトウェアテストの対象となるソースコードのテストが実施された割合を意味します。

カバレッジの種類

コードカバレッジ(コード網羅率)の測定には、いくつかの種類があります。以下に種類の例を挙げます。

  • 文網羅
  • 分岐網羅
  • 条件網羅
  • 経路網羅
  • 入口/出口網羅
文網羅 とは、ソースコードの各文がテストで実行されたかで判断します。

分岐網羅とは、 if 文などの制御構造の分岐がそれぞれテストされたかを判断します。

条件網羅は、分岐の真と偽の両方がテストされたかを判断します。

経路網羅は、対象コードのすべての経路のテストが実行されたかで判断します。

入口/出口網羅は、すべての関数呼び出しがテストで実行されたかで判断します。

コードカバレッジを取得する方法

コードカバレッジを取得する方法は、プログラミング言語ごとにツールが用意されています。

C言語では、GNU が開発している gcov と呼ばれるツールがあります。

gcovとは

gcov は、C言語のプログラムのカバレッジを測定するツールです。

gcovのインストール

gcov は、gcc のパッケージで提供されています。

Ubuntu の場合は、以下のパッケージをインストールします。
sudo apt install gcc

FreeBSD の場合は、以下のパッケージをインストールします。
sudo pkg install gcc

FreeBSD で gcc9 をインストールした環境では、 gcov のコマンドは、 gcov9 という名前で提供されています。

gcovのオプション

gcov9には、以下のオプションがあります。
Usage: gcov [OPTION...] SOURCE|OBJ...

Print code coverage information.

  -a, --all-blocks                Show information for every basic block
  -b, --branch-probabilities      Include branch probabilities in output
  -c, --branch-counts             Output counts of branches taken
                                    rather than percentages
  -d, --display-progress          Display progress information
  -f, --function-summaries        Output summaries for each function
  -h, --help                      Print this help, then exit
  -i, --json-format               Output JSON intermediate format into .gcov.json.gz file
  -j, --human-readable            Output human readable numbers
  -k, --use-colors                Emit colored output
  -l, --long-file-names           Use long output file names for included
                                    source files
  -m, --demangled-names           Output demangled function names
  -n, --no-output                 Do not create an output file
  -o, --object-directory DIR|FILE Search for object files in DIR or called FILE
  -p, --preserve-paths            Preserve all pathname components
  -q, --use-hotness-colors        Emit perf-like colored output for hot lines
  -r, --relative-only             Only show data for relative sources
  -s, --source-prefix DIR         Source prefix to elide
  -t, --stdout                    Output to stdout instead of a file
  -u, --unconditional-branches    Show unconditional branch counts too
  -v, --version                   Print version number, then exit
  -w, --verbose                   Print verbose informations
  -x, --hash-filenames            Hash long pathnames

For bug reporting instructions, please see:
<https://gcc.gnu.org/bugs/>.

gcovの使い方


カバレッジを測定するためには、 gcc コマンドでカバレッジを測定するコードを埋め込みます。

gcc --coverage -fstack-protector main.c

サンプルコード main.c は以下の通りです。
#include <stdio.h>
void
f3 ()
{
}
void
f2 ()
{
	int	i;
	for (i = 0; i < 10; ++i)
	{
		int j = i;
		if (j > 100)
		{
			j++;
		}
		if (j < 5)
		{
			j = 0;
		}
	}
}
void
f1 ()
{
	f2 ();
}
int
main ()
{
	f1 ();
	return 0;
}

gcc でコンパイルすると a.out 以外に main.gcno が作成されます。
ls main*
main.c main.gcno

a.out を実行すると main.gcda というファイルが生成されます。
./a.out

gcda ファイルに対して、gcov を実行します。
gcov main.gcda

カバレッジが 81.25% だということがわかります。
File '/usr/include/stdio.h'
Lines executed:0.00% of 4
/usr/include/stdio.h:creating 'stdio.h.gcov'

File 'main.c'
Lines executed:81.25% of 16
main.c:creating 'main.c.gcov'


いくつかファイルが増えてます。
Makefile      main.c        main.gcda     stdio.h.gcov
a.out*        main.c.gcov   main.gcno

main.c.gcov に詳しい結果が保存されています。

f1 が1回、f2が1回、f3が0回呼びだされていることがわかります。

        -:    0:Source:main.c
        -:    0:Graph:main.gcno
        -:    0:Data:main.gcda
        -:    0:Runs:1
        -:    0:Programs:1
        -:    1:#include <stdio.h>
        -:    2:void
        -:    3:f3 ()
    #####:    4:{
    #####:    5:}
        -:    6:void
        -:    7:f2 ()
        1:    8:{
        -:    9:	int	i;
       11:   10:	for (i = 0; i < 10; ++i)
        -:   11:	{
       10:   12:		int j = i;
       10:   13:		if (j > 100)
        -:   14:		{
    #####:   15:			j++;
        -:   16:		}
       10:   17:		if (j < 5)
        -:   18:		{
        5:   19:			j = 0;
        -:   20:		}
        -:   21:	}
        1:   22:}
        -:   23:void
        -:   24:f1 ()
        1:   25:{
        1:   26:	f2 ();
        1:   27:}
        -:   28:int
        -:   29:main ()
        1:   30:{
        1:   31:	f1 ();
        1:   32:	return 0;
        -:   33:}

作成された a.out を nm コマンドで調べると、 gcov 用の関数呼び出しが追加されていることがわかります。
00000000006038e0 d __gcov_.f1
0000000000603920 d __gcov_.f2
0000000000603960 d __gcov_.f3
0000000000603820 d __gcov_.main
00000000004016a0 T __gcov_close
00000000004028b0 T __gcov_dump_one
0000000000603a48 B __gcov_error_file
00000000004028e0 T __gcov_exit
0000000000402970 T __gcov_init
00000000006039c0 D __gcov_master
0000000000401130 T __gcov_merge_add
00000000004015b0 T __gcov_open
00000000004017e0 T __gcov_read_counter
00000000004018c0 T __gcov_read_summary
00000000004017b0 T __gcov_read_unsigned
0000000000401580 T __gcov_rewrite
0000000000603a60 B __gcov_root
0000000000401900 T __gcov_seek
0000000000401950 T __gcov_sort_n_vals
0000000000603a80 B __gcov_var
0000000000401720 T __gcov_write_counter
0000000000401760 T __gcov_write_summary
0000000000401740 T __gcov_write_tag_length
0000000000401700 T __gcov_write_unsigned
0000000000603a10 b __gcov0.f1
0000000000603a20 b __gcov0.f2
0000000000603a40 b __gcov0.f3
0000000000603a00 b __gcov0.main
00000000004019f0 t gcov_do_dump
0000000000400c90 t gcov_do_dump.cold
00000000004013b0 t gcov_error
0000000000401210 t gcov_read_words
0000000000401320 t gcov_version_string
00000000004014f0 t gcov_version.isra.0.part.0
0000000000401170 t gcov_write_block
00000000004011c0 t gcov_write_words

スポンサーリンク
スポンサーリンク
 
いつもシェア、ありがとうございます!


もっと情報を探しませんか?

関連記事

最近の記事

人気のページ

スポンサーリンク
 

過去ログ

2020 : 01 02 03 04 05 06 07 08 09 10 11 12
2019 : 01 02 03 04 05 06 07 08 09 10 11 12
2018 : 01 02 03 04 05 06 07 08 09 10 11 12
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12

サイト

Vim入門

C言語入門

C++入門

JavaScript/Node.js入門

Python入門

FreeBSD入門

Ubuntu入門

セキュリティ入門

パソコン自作入門

ブログ

トップ


プライバシーポリシー