pytestを使って簡単なユニットテスト導入しよう

スポンサーリンク

はじめに

様々なプログラムを作成するうえで品質と担保するためにテストは必須と言えます。今回は、Pythonにて記述したプログラムの関数などをテストする「ユニットテスト」を実施するため、pytestというテストフレームワークを利用することとしました。

pytestを使用して、ユニットテストを高速かつ反復的に実施可能とすることで、機能追加などにおいても品質を一様に担保することを目標としています。

導入

Pythonのインストールされた環境にてpipを用いることで簡単に導入ができます。

pip install pytest

今回のプロジェクトのフォルダ・ファイル構成は以下のようになっています。

/
┣src/
┃┗sample.py
┗tests/
 ┣test_sample.py
 ┗__init__.py

pytestの実行にはrootにてpytestコマンドを実行することでテストが実行できます。

実行例

サンプルコード

テスト対象となるサンプルコードを作成しました。加減乗除が可能な関数セットを作成しました。

""" 加算 """
def add(x, y):
    return x + y

""" 減算 """
def subtract(x, y):
    return x - y

""" 乗算 """
def multiply(x, y):
    return x * y

""" 除算 """
def divide(x, y):
    if y == 0:
        raise ZeroDivisionError("Division by zero is not possible.")
    return x / y

テストコード

各関数に対して正しく算出結果が返ってくるかを確認しています。また、除算においてはゼロで割ることはできません。ゼロで割った際には例外発生を発生させていますので、例外発生の検知テストも実施します。

importにてテスト対象のファイルをインポートしてテストを実施します。assertというヘルパー関数を用いてテストの合否を判定します。assertの比較分がTrueである場合にはテストは合格と判定されます。

import pytest
import src.sample as Sample

def test_sample_add():
    assert Sample.add(1, 2) == 3

def test_sample_subtract():
    assert Sample.subtract(3, 2) == 1
    
def test_sample_multiply():
    assert Sample.multiply(3, 2) == 6

def test_sample_divide():
    assert Sample.divide(10, 2) == 5

def test_sample_divide_by_zero():
    with pytest.raises(ZeroDivisionError) as info:
        Sample.divide(10, 0)

    assert info.type is ZeroDivisionError
    assert str(info.value) == "Division by zero is not possible."

また、例外処理の検知にはpytest.raisesを用いることで判定化が可能です。

実行結果

pytestを実行した結果イメージです。テストに失敗するとエラーが発生します。失敗個所の処理を確認して再度テストを実施しましょう。

> pytest
=================== test session starts ====================
platform win32 -- Python 3.10.11, pytest-8.3.5, pluggy-1.5.0
rootdir: \
collected 6 items

tests\test_sample.py ......                           [100%]

==================== 6 passed in 0.01s =====================

おまけ

Pythonにてコードを記載できますので、分岐・反復でのテストも可能です。

def test_sample_add_zero_to_nine():
    # 0+0, 0+1, ..., 9+8, 9+9 をテストする
    for add in range(10):
        for added in range(10):
            assert Sample.add(add, added) == add + added

そのほか、外部モジュールなどをモック化してさらに高度なテストができます。以下の記事で紹介しているので是非こちらも一読ください!

まとめ

pytestは関数やモジュールを検査するうえで学習コストが低く非常に扱いやすいものとなります。開発が大規模になる上で、コードや関数は増大することが予想されテストの自動化は必須となっていきます。

個人開発・仕事などにおいて、工数の削減や品質を担保を目的としてぜひpytestの導入を検討してみてはいかがでしょうか?

コメント

タイトルとURLをコピーしました