ウェブサイト検索

PyTest を使用して Python で単体テストを作成および実行する方法


Python でコードを作成するときは、コードが期待どおりに動作することを確認することが重要です。これを行うための最良の方法の 1 つは、コードの小さな部分 (または単位) が正しく動作しているかどうかを確認するのに役立つ単体テストを使用することです。

この記事では、Python で最も人気のあるテスト フレームワークの 1 つであるPyTest を使用して、Python で効果的な単体テストを作成および実行する方法を学びます。

単体テストとは何ですか?

単体テストは、単一の関数または小さなコード部分のチェックに焦点を当てた小規模で単純なテストです。これらは、コードが期待どおりに動作することを保証し、バグを早期に発見するのに役立ちます。

単体テストは、関数、メソッド、さらにはクラスなど、コードのさまざまな部分に対して作成できます。単体テストを作成すると、プログラム全体を実行せずにコードをテストできます。

PyTest を使用する理由

PyTest は、テストの作成と実行を簡単にする Python の人気のテスト フレームワークです。

使い方は簡単で、次のような便利な機能がたくさんあります。

  • これにより、シンプルかつ明確なテスト ケースを作成できます。
  • フィクスチャ、パラメータ化されたテスト、プラグインなどの高度な機能を提供します。
  • 他のテストツールやライブラリとうまく連携します。
  • 読みやすいテスト結果とレポートを生成します。

Linux での PyTest のセットアップ

テストの作成を開始する前に、PyTest をインストールする必要があります。 PyTest がインストールされていない場合は、pip と呼ばれる Python パッケージ マネージャーを使用してインストールできます。

pip install pytest

PyTest をインストールしたら、テストの作成を開始する準備が整います。

PyTest を使用して最初のテストを作成する

まず簡単な関数を作成してから、その関数のテストを作成しましょう。

ステップ 1: 単純な関数を作成する

まず、テストする Python 関数を作成しましょう。 2 つの数値を加算する関数があるとします。

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

これは、2 つの数値 a と b を受け取り、それらを加算して結果を返す単純な関数です。

ステップ 2: 関数のテストを作成する

次に、add 関数のテストを書いてみましょう。 PyTest では、テストは別のファイルに記述されます。通常は、テスト ファイルを簡単に識別できるように test_*.py という名前が付けられます。

test_add.py という名前の新しいファイルを作成し、次のテスト コードを記述します。

test_add.py
from add import add

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

上記のコードの説明:

  • add.py ファイルから add 関数をインポートします。
  • test_add_numbers() というテスト関数を定義します。 PyTest では、テスト関数は単語 test_ で始まる必要があります。
  • テスト関数内では、assert ステートメントを使用して、add 関数の呼び出し結果が期待値と一致するかどうかを確認します。 assert ステートメントの条件が True の場合、テストは合格します。それ以外の場合は失敗します。

ステップ 3: テストを実行する

テストを実行するには、ターミナルを開き、test_add.py ファイルが存在するディレクトリに移動して、次のコマンドを実行します。

pytest

PyTest は、すべてのテスト ファイル (test_ で始まるファイル) を自動的に検索し、そのファイル内でテストを実行します。すべてが正しく動作している場合は、次のような出力が表示されるはずです。

ドット (.) は、テストが成功したことを示します。問題がある場合、PyTest はエラー メッセージを表示します。

より高度なテストを作成する

基本的なテストを作成して実行する方法がわかったので、PyTest のより高度な機能をいくつか見てみましょう。

予期される例外のテスト

場合によっては、何か問題が発生したときにコードが正しい例外を発生させるかどうかをテストしたいことがあります。これは、pytest.raises() 関数を使用して実行できます。

2 つの数値を除算する関数をテストしたいとします。 2 番目の数値がゼロの場合は例外を発生させたいと考えています (ゼロによる除算エラーを避けるため)。

divide 関数は次のとおりです。

divide.py
def divide(a, b):
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

ここで、ゼロで除算しようとしたときに ValueError が発生するかどうかを確認するこの関数のテストを作成しましょう。

test_divide.py
from divide import divide
import pytest

def test_divide_numbers():
    assert divide(10, 2) == 5
    assert divide(-10, 2) == -5
    assert divide(10, -2) == -5

def test_divide_by_zero():
    with pytest.raises(ValueError):
        divide(10, 0)

コードの説明:

  • test_divide_by_zero() という新しいテスト関数を追加しました。
  • この関数内では、pytest.raises(ValueError) を使用して、2 番目の引数としてゼロを指定して除算関数を呼び出したときに ValueError が発生するかどうかを確認します。

pytest コマンドを使用してテストを再度実行します。すべてが正しく動作している場合は、次の出力が表示されるはずです。

セットアップとクリーンアップにフィクスチャを使用する

場合によっては、テストを実行する前に特定の条件を設定したり、テストの完了後にクリーンアップしたりする必要がある場合があります。 PyTest は、これを処理するためのフィクスチャを提供します。

フィクスチャは、テストの条件を設定または解除するために使用できる関数です。フィクスチャは、オブジェクトを作成したり、テストに必要なデータベースに接続したりするためによく使用されます。

以下は、フィクスチャを使用してファイル操作をテストするための一時ディレクトリを設定する例です。

test_file_operations.py
import pytest
import os

@pytest.fixture
def temporary_directory():
    temp_dir = "temp_dir"
    os.mkdir(temp_dir)
    yield temp_dir  # This is where the test will run
    os.rmdir(temp_dir)  # Cleanup after the test

def test_create_file(temporary_directory):
    file_path = os.path.join(temporary_directory, "test_file.txt")
    with open(file_path, "w") as f:
        f.write("Hello, world!")
    
    assert os.path.exists(file_path)

コードの説明:

  • テスト前に一時ディレクトリを作成し、テスト後にそれを削除する temporary_directory というフィクスチャを定義します。
  • テスト関数 test_create_file() は、このフィクスチャを使用して一時ディレクトリにファイルを作成し、そのファイルが存在するかどうかを確認します。

pytest コマンドを使用してテストを再度実行します。 PyTest はフィクスチャを自動的に検出して使用します。

Pytest を使用してテストをパラメータ化する

場合によっては、異なる入力を使用して同じテストを実行したいことがあります。 PyTest では、parametrize を使用してこれを簡単に行うことができます。

いくつかの数値のペアを使用して add 関数をテストしたいとします。ペアごとに個別のテスト関数を記述する代わりに、pytest.mark.parametrize を使用して、異なる入力で同じテストを実行できます。

test_add.py
import pytest
from add import add

@pytest.mark.parametrize("a, b, expected", [
    (2, 3, 5),
    (-1, 1, 0),
    (0, 0, 0),
    (100, 200, 300)
])
def test_add_numbers(a, b, expected):
    assert add(a, b) == expected

コードの説明:

  • pytest.mark.parametrize デコレーターを使用して、複数の入力セット (ab、および expected) を定義します。 )。
  • テスト function test_add_numbers() は、入力セットごとに 1 回実行されます。

pytest コマンドを使用してテストを再度実行します。これにより、入力セットごとに 1 回ずつ、テストが 4 回実行されます。

結論

この記事では、PythonPyTest を使用して効果的な単体テストを作成および実行し、バグを早期に発見し、コードが期待どおりに動作することを確認する方法を学びました。

PyTest を使用すると、これらのテストの作成と実行が簡単になり、その強力な機能により、Python の学習が進むにつれてより複雑なテストのニーズに対応できます。

関連記事: