2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1分でできる!VSCode上でPythonの単体テストのカバレッジを可視化する

Last updated at Posted at 2024-06-03

できること

  • 単体テストのカバレッジがVSCode上で表示される
  • カバレッジ率も計算してくれる
  • Python3, Python2, pytest, unittest(標準ライブラリ)で使えます

こんな感じです↓

スクリーンショット 2024-06-03 18.24.11.png

緑色 = 通ってる
赤色 = 通ってない
(黄色 = 一部通ってる)

ここだと、if分岐の中身を通るケースの検証が全くできていないことが一目で分かります 🎊

また、VSCodeの下の方にCoverage率も表示されます(「71% Coverage」のところ)

事前準備

VSCodeの拡張機能「Coverage Gutters」をインストールしておきます

スクリーンショット 2024-06-03 18.05.21.png

VSCodeの下側に「⚪︎Watch」と表示されればokです。
スクリーンショット 2024-06-03 18.11.56.png

導入してみる

a) pytestの場合

  1. 必要なライブラリをinstallする
    $pip install pytest pytest-cov
  2. ターミナルから以下コマンドでpytestを走らす
    $pytest --cov --cov-branch --cov-report=xml
  3. VSCode下側の「⚪︎Watch」をクリック
  4. 完了!

b) unittestの場合

  1. 必要なライブラリをinstallする
    $pip install coverage
  2. ターミナルから以下コマンドでunittestを走らす
    $python -m coverage run -m unittest
  3. coverage.xmlファイルを生成する
    $python -m coverage xml
  4. VSCode下側の「⚪︎Watch」をクリック
  5. 完了!

感想

  • 単体テストを書く際にめちゃくちゃ便利で感動してます。特に私が担当しているコードはいわゆるレガシーコードで複雑度が高いので、カバレッジの可視化をすることで見落としがないか、重要ロジックは検証できているか、など安心できています。また、レビュワーにとってもどこを通っていて、カバレッジ率が何%で、というのがパッと分かると安心かと思うのでチーム間のコミュニケーションでも重宝しています :smile:

補足

  • Coverage Guttersは単体テスト時に生成されるcoverage.xmlを参照するのでそれを利用しています。coverage.xmlさえあれば良いので、万が一本記事の手順でできなかった場合はコマンド等いじるなどしてみてください!

おまけ(今回使ったお試しコード)

コピペしてぜひ試して見てください〜 (python3.11)
pytestでもunittestでも動きます笑

"""calculate_average.py

与えられた数値の平均値を求めるモジュール"""


def calculate_average(numbers: list[int]) -> float:
    if not _is_valid_input_values(numbers):
        raise ValueError()
    total = sum(numbers)
    average = total / len(numbers)
    return average


def _is_valid_input_values(numbers: list[int]) -> bool:
    # input値がlist型であることを確認
    if not isinstance(numbers, list):
        return False
    # listの中身が全てint型であることを確認
    if not all(isinstance(number, int) for number in numbers):
        return False
    # listの中身が空でないことを確認
    if not numbers:
        return False
    return True
"""test_calculate_average.py"""
from unittest import TestCase

import pytest

from calculate_average import calculate_average


class TestCalculateAverage(TestCase):
    def test_calculate_average(self):
        """calculate_averageメソッドの正常系を確認する"""
        assert calculate_average([1, 2, 3, 4, 5]) == 3.0
        assert calculate_average([10, 20, 30, 40, 50]) == 30.0

    # def test_calculate_average_exception(self):
    #     """calculate_averageメソッドの例外系を確認する 空リストを渡すとValueErrorが発生する"""
    #     with pytest.raises(ValueError):
    #         calculate_average([])

さいごに

ここまで読んでいただきありがとうございました!
本記事が少しでも良いなと思った方は「いいね!」していただけるとめちゃくちゃ喜びますmm

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?