1
1
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

pytest をさわりながらよく使いそうなものまとめてみた

Last updated at Posted at 2024-06-20

はじめに

pytestに触れてみたので本記事は備忘録を兼ねてその学習内容をまとめたものになります。

対象の方

とりあえずコピペで動かしながらざっくりpytestの書き方を把握されたい方

インストール

pytestをインストールします。

pip install pytest

環境

  • python:3.12.2
  • pytest:8.2.2

とりあえず動かしてみる

足し算を行うシンプルな関数を準備します。

sample.py
def add(a, b):
    return a + b

足し算を行う上記の関数をテストするためのテストコードを作成します。

test_sample.py
from sample import add

def test_add():
    assert add(1, 2) == 3
    assert add(-1, 1) == 0
    assert add(0, 0) == 0

テストコードのファイル名、メソッド名は test~ で記載する。

https://docs.pytest.org/en/8.2.x/explanation/goodpractices.html#test-discovery

下記のコマンドでテスト実行します。

pytest test_sample.py

テストを実行した結果は次の通りです。テストが1つ通っている事が確認できました。

test_sample.py .                                                                                                           [100%] 

======================================================= 1 passed in 0.01s =======================================================

テストコード内でprint()出力の内容を見たい時には、以下のように「--capture=no」オプションを設定するとログの内容を確認可能。

pytest test_sample.py --capture=no

参考:https://qiita.com/yyyyy__/items/59507d041458829fb39a

よく使いそうなもの

1. assert文

以下に使用例を記載。assertの後にテストしたい条件を記述する。

test_sample.py
def test_example():
    assert 1 == 1  # 成功するテスト
    assert 1 == 2  # 失敗するテスト

動かしてみると次のように 1==2 で失敗していることを確認。

    def test_example():
        assert 1 == 1  # 成功するテスト
>       assert 1 == 2  # 失敗するテスト
E       assert 1 == 2

test_sample.py:3: AssertionError

2. pytest.mark

◆ pytest.mark.parametrize

同じテストを異なるデータセットで複数回実行したい場合は @pytest.mark.parametrize を使用するとまとめてテストができて便利です。

sample.py
def add(a, b):
    print('テスト開始')
    return a + b
test_sample.py
import pytest
from sample import add

@pytest.mark.parametrize("a,b,expected", [
    (1, 2, 3),
    (-1, 1, 0),
    (0, 0, 0),
])

def test_add(a, b, expected):
    assert add(a, b) == expected

動かしてみるとデータセットの回数実行されていることを確認。(今回は3回)

test_sample.py テスト開始
.テスト開始
.テスト開始
.

======================================================= 3 passed in 0.01s ======================================================= 

◆ pytest.mark.skip

一部の処理をスキップしたい場合に使用します。

test_sample.py
import pytest

@pytest.mark.skip(reason="このテストはまだ実装されていません")
def test_not_implemented_yet():
    print('エラー')
    assert False

def test_ready_to_run():
    print('実行')
    assert True

実行するとテストが1件passしており、もう1件はスキップされている事を確認。

test_sample.py s実行
.

================================================= 1 passed, 1 skipped in 0.01s ==================================================

実行結果の略称について

  • s:テストがスキップされたことを示す
  • .:テストがパスしたことを示す

3. pytest.raises

意図的に例外を発生させてみます。エラーが発生すればテストはpass、エラーが発生しなければfailedになります。

test_sample.py
import pytest

def test_raises_exception():
    with pytest.raises(ValueError):
        int("a")  #  エラーを発生させる

動かしてみるとテストがpassしており、想定通りエラーを起こせていたことを確認。

test_sample.py .

======================================================= 1 passed in 0.01s =======================================================

4. Fixtures

fixtureを利用する事でテストの前後に処理を設けることができます。

test_sample.py
import pytest

@pytest.fixture
def temp_file(tmpdir):
    # テストの前処理:ファイルを一時的に作成
    print('テスト開始')
    temp_file = tmpdir.join("temp_file.txt")
    temp_file.write("Hello, World!")
    
    # テスト実行:テストには作成したファイルを渡す
    yield temp_file
    
    # テストの後処理:ファイルを削除
    temp_file.remove()
    print('テスト終了')

def test_temp_file(temp_file):
    # テスト: ファイルに書き込まれた文字の一致、ファイルの存在
    assert temp_file.read() == "Hello, World!"
    assert temp_file.check()

動かしてみるとテストがpassしている事を確認。

test_sample.py テスト開始
.テスト終了

======================================================= 1 passed in 0.02s =======================================================

参考

1
1
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
1
1