【初心者〜現場で活躍まで】挫折しないPython勉強方法もっと知る

pytestで簡単にカバレッジを出力する方法

pytestで簡単にカバレッジを出力する方法

テストコードを書いていると、どれくらいテストコードを書くべきか迷うことがあります。

エソラ

その時に有効なのが、カバレッジです。

カバレッジとは、開発したプログラムに対するテストのカバー率のことを言います。カバレッジが高いとテストの網羅率が高いと判断ができます。

今回の記事では、「pytestでカバレッジを出力する方法」について解説します。

カバレッジが出力できると、どれくらいテストコードを書けばいいか、客観的に評価できるので、品質の向上につながります。

この記事を書いた人

エソラ
  • エンジニア歴10数年
  • SIerでDX推進を仕事に
  • Python、AWSを使ったアーキテクチャ設計・アプリ開発が得意
  • 30代、2児の父でサウナ好き
  • [icon-class=”icon-twitter”]Twitter

ちなみに、私の環境のバージョン情報は以下の通りです。

項目バージョン
Python3.10.6
pytest7.1.3
coverage6.5.0
pytest-cov4.0.0
バージョン情報

それでは、最後までよろしくお願いします。

Pythonの勉強方法は、まとめ記事があります。

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を作成します。

なぜsetpu.pyを作成するの?

他フォルダのモジュールをimportする時に、ModuleNotFoundError: No module named ‘XXX’になることを防止できるからです。

setup.pyは以下のように実装します。

from setuptools import setup, find_packages

setup(name="PACKAGENAME", packages=find_packages())

そして、コマンドプロンプトやターミナルで以下のコマンドを打ちます。

pip install -e .

これで、importエラーが発生することなく、モジュールを使うことができます。

カバレッジの出力方法

ここからはカバレッジを出力する方法を解説します。やることは以下の3つです。

カバレッジの出力方法
  1. カバレッジの出力に必要なモジュールをインポート
  2. テストコードを書く
  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をブラウザで開くとすぐに確認できます。

pytestのカバレッジレポートでカバー率を確認
pytestのカバレッジレポートでカバー率を確認

闇雲にカバー率100%を目指すのは効率が悪いため、プロジェクトごとにカバー率の目標を立てることが多いと思います。

そのカバー率に達するまで、テストコードにテストケースを追加して、カバー率を順次チェックするという流れで現場では確認することになります。

カバレッジレポートでテストの網羅率を確認する

カバレッジレポートでテスト対象のソースコードの網羅率を確認するには、以下のように確認したいソースコードのリンクをクリックします。

pytestのカバレッジレポートで網羅率を確認
pytestのカバレッジレポートで網羅率を確認

先程実装していたテストコードはカバー率が100%だったので、全てのソースコードでテストが網羅されていることが分かります。

pytestのカバレッジレポートで網羅率が100%の例
pytestのカバレッジレポートで網羅率が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のカバレッジレポートで網羅率が100%以外の例
pytestのカバレッジレポートで網羅率が100%以外の例
エソラ

こんな感じで、足りていないテストケースを特定します。

まとめ:pytestでカバレッジレポートを出力して、品質を上げる

ここまでpytestでカバレッジを出力する方法や見方について解説しました。

カバレッジの出力方法
  1. カバレッジの出力に必要なモジュールをインポート
  2. テストコードを書く
  3. コマンドを利用して、カバレッジを出力する
カバレッジレポートで確認する点
  • カバー率
  • テストの網羅率

HTML形式でカバレッジレポートを出力することができるので、プロジェクト内で共有することも簡単にできます。

テストフェーズに入ったら、毎日カバレッジレポートを出力して、テストコードを書き、品質を上げます。

ということで、カバレッジレポートの出力方法や見方はこの記事でしっかりとマスターしましょう。

エソラ

あなたが品質の高いコードを書きたいなら、カバレッジレポートが頼もしい味方になります。

もっとpytstの使い方を学びたい場合は、以下の書籍がおすすめです。

日本語で唯一、pytestだけに焦点を当てて、詳細に書かれた書籍です。

テスト駆動Python第2版
総合評価
( 5 )
メリット
  • 日本語でpytestの全てについて、解説されている唯一の書籍
  • 段々とステップアップして、深くなるので、初心者でも、中級者でも、上級者でも、学びがある
  • サンプルコードには、サンプルアプリが含まれているため、実践的に学べる工夫あり
  • 章末にまとめがあり、復習の役に立つ
  • 第7章に「どのようなテストを書くのか」についての解説があり、テストに対する考え方が深まる
デメリット
  • 後半になると、かなり高度な内容になるため、初心者には難しい
  • タイトルに「テスト駆動開発」と書かれているが、該当部分の記述が少なく、テスト駆動開発を知りたい人は期待外れになるかも
エソラ

間違えて、第1版を買わないように注意して下さい。

著:Brian Okken, 翻訳:株式会社クイープ, 監修:株式会社クイープ, 監修:安井 力
¥2,970 (2022/11/24 04:05時点 | Amazon調べ)

Pythonの勉強方法は、まとめ記事があります。

Pythonを勉強する時、何から勉強するか分からず、挫折します。初心者でも、中級者でも、レベルに合わせた勉強方法を分かりやすくまとめています。

ここまでお読みいただき、ありがとうございました。

役に立った、面白かったと思ったら、SNSでシェアしてくれると嬉しいです。

エソラ

もし分からないことがあれば、お問い合わせTwitterにご連絡をいただけると嬉しいです。(Twitterの方が返信早いかも…)

\ 更新の励みになるので、ポチッとしてね /

エソラ

他にもスキルアップやキャリアアップの役に立つ情報が満載です。他の記事も読んで、ゆっくりしていってね!

pytestで簡単にカバレッジを出力する方法

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次