Python pytestの使い方

Pythonで書かれたコードをテストできるライブラリpytestの使い方について説明します。
この記事での実行環境は Python 3.9.0, pytest 6.2.1 です。

公式ドキュメント 👉 pytest: helps you write better programs


インストール

pytestはpipでインストールすることができます。以下のコマンドでインストールしてください。

pip install pytest

テストコード用ファイルの作成

テストしたい対象のコードが書かれたファイル名が xxxx.py だった場合、test_xxxx.py (test_<対象ファイル名>.py)というファイルを作成し、そこにテストコードを記載します。

  • 対象ファイル : xxxx.py
  • テストファイル : test_xxxx.py

また、複数のテストファイルを作りたい場合は tests というフォルダを作成し、そこにまとめておきましょう。


テストコードの作成

テストをする対象のクラスや関数を呼び出して、assert文で値を評価します。

テスト対象コード
2つの値を合算した値を返すadd関数を作成します。

def add(x, y):
    return x + y


テストコード
作成したadd関数を呼び出して、返ってきた値をassert文で評価します。

from study import add

def test_01():
    assert add(10, 15) == 25

テストの実行

テストファイルが置いてあるディレクトリ、もしくはそれより上位のディレクトリで、pytest コマンドを叩くと結果が出力されます。

$ pytest // テスト実行
======================================== test session starts ========================================
 platform darwin -- Python 3.9.0, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
 rootdir: /Users/xxxxx/Documents/PythonSup/xxxxx/tests
 collected 1 item                                                                                    
 

 test_study.py .                                                                               [100%]
 ========================================= 1 passed in 0.02s ========================================= 


エラーの場合
テストコードを assert add(10, 15) == 24 に変更して実行するとエラーが出力されます。どのファイルのどの行でエラーとなったのかが表示されるので、コードが間違っているのか、テストコードが間違っているのかを確認し、修正します。

$ pyteset
======================================== test session starts ========================================
 platform darwin -- Python 3.9.0, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
 rootdir: /Users/xxxx/Documents/PythonSup/xxxx/tests
 collected 1 item                                                                                    
 

 test_study.py F                                                                               [100%]
============================================= FAILURES ==============================================
 ______________________________________________ test_01 ______________________________________________
 

     def test_01():
 >       assert add(10, 15) == 24
 E       assert 25 == 24
 E        +  where 25 = add(10, 15)
 

 test_study.py:4: AssertionError
 ====================================== short test summary info ======================================
 FAILED test_study.py::test_01 - assert 25 == 24
 ========================================= 1 failed in 0.04s =========================================


例外発生テスト

ある条件で、ある例外が発生することをテストする時は pytest.raises で確認します。

with pytest.raises(ValueError):
    例外が発生するコード


例外処理の記載の仕方はこちらを参考にしてみてください。
👉 Python 例外処理の書き方


テスト対象コード

def sum_number(x, y):
    return sum([x, y])


テストコード

from error_study import sum_number
import pytest

def test_01():
    with pytest.raises(TypeError):
        # sum()の引数に文字列は使えない
        sum_number('100', '200')

テスト実行

$ pyteset
======================================== test session starts ========================================
 platform darwin -- Python 3.9.0, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
 rootdir: /Users/xxxx/Documents/PythonSup/xxxx/tests
 collected 1 item                                                                                    
 
 test_error_study.py .                                                                         [100%]
========================================= 1 passed in 0.02s =========================================

テストのパラメータ化

同じ関数・クラスをいくつもの値のパターンでテストしたい場合、何度も同じようなコードを書くのは手間です。そのため、 @pytest.mark.parametrize() というデコレーターを使います。

  • デコレーターの第一引数に、テスト関数の引数名をタプルで指定
  • デコレーターの第二引数に、テスト関数の引数の値のタプルをリスト形式で指定

テスト対象コード

def add(x, y):
    return x + y


テストコード

from mark_study import add
import pytest


@pytest.mark.parametrize(
    ('x', 'y', 'add_result'), # 引数名
    [
        (10, 20, 30), # パターン1
        (10, -20, -10) # パターン2
    ]
)
def test_01(x, y, add_result):
    assert add(x, y) == add_result


テスト実行

$ pytest
======================================== test session starts ========================================
 platform darwin -- Python 3.9.0, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
 rootdir: /Users/xxxx/Documents/PythonSup/xxxxx/tests
 collected 2 items                                                                                   
 
 test_mark_study.py ..                                                                         [100%]
========================================= 2 passed in 0.03s ========================================= 

関連記事

このエントリーをはてなブックマークに追加