coverage combineコマンドで複数の集計結果を結合する
カバレッジ(網羅率)とは?
カバレッジとはテストコードがどれだけテスト対象の内容を網羅しているかを表す割合です。
例えば、以下のファイルにはfoo, bar, bazという3つの関数が定義されていますが、これらのすべての内容をテストで実行済みであればカバレッジは100%となります。
# -*- coding:utf-8 -*- def foo(): return 1 def bar(): return 2 def baz(x): if x < 5: return 3 else: return 4
本当はカバレッジは3種類の評価基準があってそれぞれ評価の仕方が違うのですが、ここではその詳細な説明は割愛します。
Pythonのcoverageモジュール
Pythonでカバレッジを取得するときはcoverageというモジュールを使います。
$ easy_install coverage
インストールするとcoverageというコマンドが利用可能になります。
このコマンドを使ってカバレッジをhtml形式で出力したレポートが以下の図です。
こんな風に、テストで網羅されていない部分は赤くなります。
coverageコマンドの基礎: 集計と出力の2ステップ構成
coverageコマンドは「データの集計」と「レポートの出力」という2つのステップに手順が分けられています。
複数のデータファイルを結合するcoverage combineコマンド
ここまでが基本ですが、カバレッジのデータファイルは複数のファイルを結合することができます。
それがcombineコマンドです。
これはすぐれもので、あるモジュールの中の異なる関数同士の網羅率を結合してくれるだけでなく、同じ関数の中の一部の網羅率もちゃんと結合してくれます。
口で言うと判りにくいので、実際に例を示します。
combineの利用例
coverage combineの利用例
今回のサンプルコードを上記に上げておきました。
これを使ってcombineコマンドの使い方を解説します。
最初の状態ではsample.pyのテストを二つのファイルに分けておきます。
図のように、test_sample.py, test_sample2.pyの両方を実行するとsample.pyのカバレッジは100%になります。
(py27)oyakata@ubuntu:~/Documents/bplt0216$ ls sample.py test_sample2.py test_sample.py
test_sample.pyを実行して生成された.coverageをリネームしておきます。
(py27)oyakata@ubuntu:~/Documents/bplt0216$ coverage run test_sample.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK (py27)oyakata@ubuntu:~/Documents/bplt0216$ mv .coverage .coverage.1
test_sample2.pyも実行してリネームします。
(py27)oyakata@ubuntu:~/Documents/bplt0216$ coverage run test_sample2.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK (py27)oyakata@ubuntu:~/Documents/bplt0216$ mv .coverage .coverage.2
ここまで進めるとカバレッジのデータファイルは以下の通り二つ存在するようになります。
(py27)oyakata@ubuntu:~/Documents/bplt0216$ ls -a . .. .coverage.1 .coverage.2 sample.py sample.pyc test_sample2.py test_sample.py
データファイルを結合します。
(py27)oyakata@ubuntu:~/Documents/bplt0216$ coverage combine
結合の結果、二つに分かれていたデータファイルがひとつの.coverageになります。
(py27)oyakata@ubuntu:~/Documents/bplt0216$ ls -a . .. .coverage sample.py sample.pyc test_sample2.py test_sample.py
これをもとにhtml形式でレポートを出力すると100%になることが判ります。
(py27)oyakata@ubuntu:~/Documents/bplt0216$ coverage html (py27)oyakata@ubuntu:~/Documents/bplt0216$ ls htmlcov sample.py sample.pyc test_sample2.py test_sample.py
用途
combineの用途としてわたしが思いつくものを二つ考えました。
一つは、複数のサーバーに分散してテストを実行した結果をまとめて集計するときです。
大量のテストをいちいちローカル端末で実行するのは時間がかかるので開発サーバーその他に分散して結果だけ一カ所にまとめるという方法です。
Jenkinsを分散してテストを実行するなら特に有用でしょう。
もう一つは、大量のテストのカバレッジをちょっとずつ上げたいときです。
最初にすべてのカバレッジデータを集計しておいて、テストコードを少し書くたびにデータを結合して結果を確認するといったことができます。
いずれにせよ、テストの実行を一度に全部一括して行うのが嫌なときに役に立つコマンドであることは間違いないでしょう。
追記 2/17 coverage run --appendについて
で、coverageはrunに --append という、データファイルの追記モードがあるので、これを使うとcombineをいちいちしなくても良くなる。但し、これはもちろんローカルで何度も繰り返しカバレッジを上げる為にテストを直し&修正するような状況でないと意味がない。
2012-02-17 01:51:53 via web
coverage run --appendというのがあってこれもうまく使うと便利です。
1. 最初に全unittestを実行して .coverageを作っておく。
2. 自分がカバレッジを上げようとしているテストコードを増やす。
3. 2のテストコードだけを以下のコマンドで実行する(coverage run 追記モード)
$ coverage run --append python test_extra.py
4. coverage htmlを実行し、htmlレポートを再出力する。
自分が増やしたカバレッジが反映されていることを確認する。
$ coverage html
- > ./htmlcovの下に出力されたレポートを見る。
この方法でやると、
- 毎度unittestを全部通さなくて良い。
- coverage combineより簡単な手順で作業できる。
というメリットがあるのでおすすめです。