テストコードを書いていると、どれくらいテストコードを書くべきか迷うことがあります。
その時に有効なのが、カバレッジです。
カバレッジとは、開発したプログラムに対するテストのカバー率のことを言います。カバレッジが高いとテストの網羅率が高いと判断ができます。
今回の記事では、「pytestでカバレッジを出力する方法」について解説します。
カバレッジが出力できると、どれくらいテストコードを書けばいいか、客観的に評価できるので、品質の向上につながります。
ちなみに、私の環境のバージョン情報は以下の通りです。
項目 | バージョン |
---|---|
Python | 3.10.6 |
pytest | 7.1.3 |
coverage | 6.5.0 |
pytest-cov | 4.0.0 |
それでは、最後までよろしくお願いします。
Pythonを勉強する時、何から勉強するか分からず、挫折します。初心者でも、中級者でも、レベルに合わせた勉強方法を分かりやすくまとめています。
今回のサンプルプログラム
例題にするプログラムは以下のfizzbuzz問題のプログラムです。
def fizzbuzz(num):
if num % 15 == 0:
return 'FizzBuzz'
elif num % 3 == 0:
return 'Fizz'
elif num % 5 == 0:
return 'Buzz'
else:
return str(num)
フォルダ構成は以下のようになります。
pytest-coverage
L src
L fizzbuzz.py
L test
L unit
L test_fizzbuzz.py
L requirements.txt
L setup.py
setup.pyの作成方法
今回は、setup.pyを作成します。
setup.pyは以下のように実装します。
from setuptools import setup, find_packages
setup(name="PACKAGENAME", packages=find_packages())
そして、コマンドプロンプトやターミナルで以下のコマンドを打ちます。
pip install -e .
これで、importエラーが発生することなく、モジュールを使うことができます。
setup.pyの詳しい使い方は以下の記事で詳しく解説しています。
カバレッジの出力方法
ここからはカバレッジを出力する方法を解説します。やることは以下の3つです。
- カバレッジの出力に必要なモジュールをインポート
- テストコードを書く
- コマンドを利用して、カバレッジを出力する
それぞれ、詳しく解説します。
カバレッジの出力に必要なモジュールをインポート(coverage、pytest-cov)
カバレッジを出すためには、以下をインストールします。
$ pip install coverage
$ pip install pytest-cov
pip installしたモジュールは環境差異をなくすために、requirements.txtにまとめましょう。やり方は以下の記事で詳しく解説しています。
FizzBuzzを検証するテストコードを書く
テストコードのtest_fizzbuzz.pyは、以下のようにします。
import pytest
from src.fizzbuzz import fizzbuzz
@pytest.mark.parametrize(
"num, result",
[
(15, 'FizzBuzz')
],
)
def test_fizzbuzz(num, result):
"""
関数をパラメータ化して、FizzBuzzを検証
"""
assert result == fizzbuzz(num)
‘FizzBuzz’と出力されることを期待したテストコードとなります。
ちなみにテストデータはパラメータ化して、テストメソッドに渡しています。パラメータ化することで、簡単に複数のデータパターンで検証することができます。
パラメータを使うと、カバー率を簡単に上げれます。
pytestのパラメータ化テストのやり方は、以下の記事で詳しく解説しています。
pytestでカバレッジを出力するコマンド
以下のコマンドでカバレッジを出力できます。
pytest --cov=src/ test
コマンドを実行すると、以下のようになります。
=============================================== test session starts ===============================================
platform darwin -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0
rootdir: /Users/XXX/Documents/workspace/python-sample/pytest-coverage
plugins: cov-4.0.0
collected 1 item
test/unit/test_fizzbuzz.py . [100%]
---------- coverage: platform darwin, python 3.10.6-final-0 ----------
Name Stmts Miss Cover
-------------------------------------
src/fizzbuzz.py 8 5 38%
-------------------------------------
TOTAL 8 5 38%
================================================ 1 passed in 0.11s ================================================
現状では、カバー率が38%となっています。
では、テストコードにデータパターンを追加して、カバレッジ率100%を目指します。
import pytest
from src.fizzbuzz import fizzbuzz
@pytest.mark.parametrize(
"num, result",
[
(15, 'FizzBuzz'),
(6, 'Fizz'), # 追加
(10, 'Buzz'), # 追加
(1, '1'), # 追加
],
)
def test_fizzbuzz(num, result):
"""
関数をパラメータ化して、FizzBuzzを検証
"""
assert result == fizzbuzz(num)
もう一度、カバレッジを出力してみましょう。
$ pytest --cov=src/ test
=============================================== test session starts ===============================================
platform darwin -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0
rootdir: /Users/xxx/Documents/workspace/python-sample/pytest-coverage
plugins: cov-4.0.0
collected 4 items
test/unit/test_fizzbuzz.py .... [100%]
---------- coverage: platform darwin, python 3.10.6-final-0 ----------
Name Stmts Miss Cover
-------------------------------------
src/fizzbuzz.py 8 0 100%
-------------------------------------
TOTAL 8 0 100%
================================================ 4 passed in 0.09s ================================================
狙い通り、カバー率が100%になっています。
カバレッジをHTML形式で出力する方法
プロジェクトでテストコードを書いている時、カバレッジレポートをメンバーと共有したい時があります。
その時に便利なのが、HTML形式でカバレッジを出力することです。
HTML形式でのカバレッジの出力方法は以下の通りです。
$ pytest --cov=src/ --cov-report=html test
コマンドを入力すると、htmlcovというフォルダが出来上がります。その中にあるindex.htmlをブラウザで開くと、レポートを見れます。
カバレッジレポートの見方
ここからはカバレッジレポートの見方を解説します。
- カバー率
- テストの網羅率
カバレッジレポートでカバー率を確認する
カバー率は以下のように、htmlcovフォルダ内のindex.htmlをブラウザで開くとすぐに確認できます。
闇雲にカバー率100%を目指すのは効率が悪いため、プロジェクトごとにカバー率の目標を立てることが多いと思います。
そのカバー率に達するまで、テストコードにテストケースを追加して、カバー率を順次チェックするという流れで現場では確認することになります。
カバレッジレポートでテストの網羅率を確認する
カバレッジレポートでテスト対象のソースコードの網羅率を確認するには、以下のように確認したいソースコードのリンクをクリックします。
先程実装していたテストコードはカバー率が100%だったので、全てのソースコードでテストが網羅されていることが分かります。
これを確認しながら、足りないテストケースを特定して、カバー率を上げるのが、現場での作業の流れとなります。
では、テストコードに書いているテストケースをわざと削除して、カバー率を下げてみます。
import pytest
from src.fizzbuzz import fizzbuzz
@pytest.mark.parametrize(
"num, result",
[
(15, 'FizzBuzz'),
(6, 'Fizz'),
(10, 'Buzz'),
# 削除 (1, '1'),
],
)
def test_fizzbuzz(num, result):
"""
関数をパラメータ化して、FizzBuzzを検証
"""
assert result == fizzbuzz(num)
すると、カバー率が下がったので、テストが実施されていないコードが赤くなります。
こんな感じで、足りていないテストケースを特定します。
Python学習におすすめのコンテンツ
現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル
Udemyの講座でPythonなら、文句なしにおすすめ
- 分かりやすい言葉や具体的なコードで工夫して説明しているので、初心者でも理解できる。
- 初心者でも挫折しないように、丁寧に詳しく手順を説明している。
- 講座内で取り扱う課題は実践的なものが多く、書籍では身につかない応用力を身につけられる。
- 情報量が多いのに、講座の進み方が速いので、一回では理解が追いつかない。
- 課題の難易度が高すぎる場合がある。
- 講師のアクセントが特殊で、聞き取りにくいと感じたことがある。
テスト駆動Python 第2版
日本語で唯一、pytestだけに焦点を当てて、詳細に書かれた書籍です。
- 日本語でpytestの全てについて、解説されている唯一の書籍
- 段々とステップアップして、深くなるので、初心者でも、中級者でも、上級者でも、学びがある
- サンプルコードには、サンプルアプリが含まれているため、実践的に学べる工夫あり
- 章末にまとめがあり、復習の役に立つ
- 第7章に「どのようなテストを書くのか」についての解説があり、テストに対する考え方が深まる
- 後半になると、かなり高度な内容になるため、初心者には難しい
- タイトルに「テスト駆動開発」と書かれているが、該当部分の記述が少なく、テスト駆動開発を知りたい人は期待外れになるかも
間違えて、第1版を買わないように注意して下さい。
まとめ:pytestでカバレッジレポートを出力して、品質を上げる
ここまでpytestでカバレッジを出力する方法や見方について解説しました。
- カバレッジの出力に必要なモジュールをインポート
- テストコードを書く
- コマンドを利用して、カバレッジを出力する
- カバー率
- テストの網羅率
HTML形式でカバレッジレポートを出力することができるので、プロジェクト内で共有することも簡単にできます。
テストフェーズに入ったら、毎日カバレッジレポートを出力して、テストコードを書き、品質を上げます。
ということで、カバレッジレポートの出力方法や見方はこの記事でしっかりとマスターしましょう。
あなたが品質の高いコードを書きたいなら、カバレッジレポートが頼もしい味方になります。
Pythonを勉強する時、何から勉強するか分からず、挫折します。初心者でも、中級者でも、レベルに合わせた勉強方法を分かりやすくまとめています。
コメント