【Python】pytestとは?その基本から具体例まで丁寧に解説

※本サイトにはプロモーション・広告が含まれています。

(最終更新日:2023年9月)

✔このような方へ向けて書かれた記事となります

「pytestってどのような機能があるのだろうか?」
「pytestの使い方をもっと理解したい」
「pytestを使ったテストの実例を学びたい」

✔当記事を通じてお伝えすること

  • pytestの基本概念
  • pytestを使ったテストの作成方法や応用事例
  • pytestを活用した実践的なテスト例

当記事では、pytestの基本から応用までを、具体的なテストケースを通じてわかりやすく解説しています。

最後までお読みいただき、pytestの活用をマスターしましょう。

筆者プロフィール

筆者プロフィールアイコン

【現職】プロダクトマネージャー

【副業】ブログ(月間17万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

はじめに: pytestの概要

こちらでは、pytestについての基本的な情報を提供し、テストの重要性とpytestの役割を解説します。

  • テストの重要性
  • pytestとは
  • pytestの特徴とメリット

テストの重要性とpytestの役割

ソフトウェア開発において、テストはコードが期待通りに動作することを保証し、バグや不具合を早期に見つけるための重要なプロセスです。

例として、オンラインショッピングサイトの開発を考えましょう。

正しく機能するショッピングカートや支払い処理は、顧客満足度に直結します。

pytestとは

pytestは、Pythonで書かれたコードをテストするための強力なフレームワークです。

pytestを使用することで、自動化されたテストスイートを作成し、コードの品質を確保できます。

pytestの特徴とメリット

pytestは、Pythonでのソフトウェアテストを書くときに非常に人気のあるフレームワークです。

以下が、pytestの主な特徴と利点になります。

  1. 簡潔な記述
    pytestを使用すると、テストケースを簡潔に、しかも非常に読みやすく記述できます。特別なクラスやセットアップ/ティアダウンメソッドなしで、シンプルな関数としてテストを記述できます。
  2. 強力なアサート
    pytestでは、assert文を使用してアサーションをおこなえます。失敗したアサートは自動的に詳細な情報を提供します。
  3. プラグインアーキテクチャ
    既存の多くのプラグインがあり、独自のプラグインを簡単に作成できます。特定のニーズに合わせてテスト環境をカスタマイズが可能です。
  4. マーカー
    テスト関数やクラスにメタデータを追加するための方法として、マーカーを使用できます。これを使用して、特定のテストをスキップしたり、条件付きで実行することができます。
  5. パラメータ化されたテスト
    同じテストロジックを異なる入力値で複数回実行するための方法として、テストのパラメータ化がサポートされています。
  6. 自動テスト検出
    pytestは、特定の命名規則に従っているテストを自動的に検出し、実行します。
  7. 豊富なプラグインと統合
    pytest-djangopytest-flaskなど、多くの人気のあるPythonライブラリやフレームワークとの統合がサポートされています。

使い方の基本例はこちら。

def test_example():
    assert 1 == 1

このように、pytestはPythonのテストの世界で非常に強力であり、多くの開発者にとってデファクトスタンダードとなっています。

スタートアップ: インストール&セットアップ

こちらでは、pytestをインストールし、プロジェクトで使うためのセットアップ方法を解説します。

  • pytestのインストール方法
  • プロジェクトでのセットアップ

pytestのインストール方法

pytestをインストールするために、Pythonのパッケージマネージャーであるpipを使用します。

コマンドラインやターミナルを開き、次のコマンドを入力してください。

pip install pytest

インストールが完了したら、pytest --versionを実行して、インストールされたバージョンを確認しましょう。

プロジェクトでのセットアップ

pytestをプロジェクトで使用するには、テストファイルを作成します。

pytestは、ファイル名がtest_で始まるか、_testで終わるPythonファイルを自動的にテストファイルとして認識します。

たとえば、test_example.pyという名前のファイルを作成しましょう。

このファイル内にテスト関数を記述していくことで、pytestがそれらを実行します。

基本的なテストの書き方

こちらでは、pytestを使用して基本的なテストを書く方法を解説します。

  • 単純な関数のテスト
  • クラスのメソッドのテスト

単純な関数のテスト

最初に、単純な関数のテストを書く方法を見ていきましょう。

例として、2つの数値を加算する関数addをテストします。

まずはこの関数を作成します。

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

次に、この関数をテストするためのテストファイルtest_mymath.pyを作成します。

# test_mymath.py
from mymath import add

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

上記のテスト関数test_addは、add関数を異なる引数で呼び出し、結果が期待通りであることをassert文で確認しています。

クラスのメソッドのテスト

次に、クラスのメソッドをテストする方法を見ていきましょう。

例として、簡単な計算機能を持つCalculatorクラスを作成し、そのメソッドをテストします。

# calculator.py
class Calculator:
    def __init__(self, value=0):
        self.value = value

    def add(self, x):
        self.value += x
        return self.value

テストファイルtest_calculator.pyを作成します。

# test_calculator.py
from calculator import Calculator

def test_calculator_add():
    calc = Calculator()
    assert calc.add(2) == 2
    assert calc.add(3) == 5

ここでは、Calculatorクラスのaddメソッドをテストしています。

新しいCalculatorオブジェクトを作成し、メソッドを呼び出して結果をassert文で検証しています。

テストの実行と結果確認

こちらでは、テストの実行方法と結果の解釈を学びます。

  • テストの実行方法
  • テスト結果の解釈

テストの実行方法

pytestを使ってテストを実行するのは非常に簡単です。

コマンドラインまたはターミナルで、プロジェクトのディレクトリに移動し、単純にpytestと入力して実行します。

これにより、pytestは自動的にテストファイルを探し、テストを実行します。

特定のファイルのみをテストする場合は、以下のとおり。

pytest <file_name>

たとえば、先程作成したtest_mymath.pyだけを実行する場合は、pytest test_mymath.pyとします。

テスト結果の解釈

pytestは、テスト結果を簡潔な形式で出力可能です。

各テストはドットで表示され、成功すると緑のドットが表示されます。

失敗したテストはFと表示され、詳細なエラーメッセージが提供されます。

これにより、何が失敗したのかを迅速に把握し、問題を解決するための情報を得られます。

パラメータ化されたテスト

こちらでは、パラメータ化されたテストの作成方法と、その注意点や活用例を解説します。

  • 複数の引数組み合わせのテスト方法
  • 注意点と活用例

複数の引数組み合わせのテスト方法

パラメータ化されたテストは、同じテストケースを異なるデータセットで実行するための強力な機能です。

例として、前述のadd関数を使用して、複数の引数組み合わせでテストを行う方法を見てみましょう。

import pytest
from mymath import add

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

ここで@pytest.mark.parametrizeデコレータを使用して、複数の引数の組み合わせ(a, b)と期待される結果(expected)を指定しています。

注意点と活用例

パラメータ化されたテストを使用する際の注意点として、データセットが多くなるとテストの実行時間が増加することがあります。

そのため、実際の状況に応じて適切なデータセットを選択することが重要です。

また、パラメータ化テストの活用例としては、境界値分析(テストケースが境界を横断するかどうかをテストする)や、異常値(例外を引き起こす可能性のある入力)のテストなどが挙げられます。

フィクスチャの活用

こちらでは、pytestのフィクスチャを活用してテストデータやオブジェクトの準備、前処理と後処理、フィクスチャの連携とスコープ、およびconftest.pyの活用について説明します。

  • テストデータやオブジェクトの準備
  • 前処理と後処理
  • フィクスチャの連携とスコープ
  • conftest.pyの活用

テストデータやオブジェクトの準備

フィクスチャは、テスト実行前にテストデータやオブジェクトを準備するための仕組みです。

例として、データベース接続を準備するフィクスチャを作成しましょう。

import pytest

@pytest.fixture
def db_connection():
    conn = create_connection() # 仮の接続作成関数
    yield conn
    conn.close()

前処理と後処理

上記の例では、yieldを使って、テストが終了した後に接続を閉じる後処理をおこなっています。

フィクスチャを使うと、テストの前後で必要な設定や後処理をおこなえます。

フィクスチャの連携とスコープ

フィクスチャはほかのフィクスチャと連携でき、スコープを指定して再利用が可能です。

たとえば、sessionスコープを使用すると、テストセッション全体でフィクスチャを一度だけ実行し、その結果を全テストで再利用できます。

conftest.pyの活用

conftest.pyは、プロジェクト内の複数のテストファイルでフィクスチャを共有するための特別なファイルです。

このファイル内にフィクスチャを定義することで、テストファイル間で簡単にフィクスチャを共有できます。

まずは、conftest.pyを作成し、以下のようなデータベース接続のフィクスチャを定義しましょう。

# conftest.py

import pytest

@pytest.fixture(scope='session')
def database_connection():
    # この部分で実際のデータベース接続の設定を行います。
    connection = "your_database_connection_here"
    yield connection
    # テストセッション後にリソースをクリーンアップするコード
    connection.close()

テストファイル test_example1.py を作成します。

# test_example1.py

def test_database_query_1(database_connection):
    # ここでは 'database_connection' フィクスチャを使用してデータベースクエリをテストします。
    result = database_connection.query("SELECT * FROM table1")
    assert result is not None

別のテストファイル test_example2.py も作成します。

# test_example2.py

def test_database_query_2(database_connection):
    # ここでも 'database_connection' フィクスチャを使用してデータベースクエリをテストします。
    result = database_connection.query("SELECT * FROM table2")
    assert result is not None

標準出力とキャプチャ

こちらでは、pytestを使用して処理時間を測定する方法と、標準出力をキャプチャする方法について説明します。

  • 処理時間の測定
  • 標準出力のキャプチャ方法

処理時間の測定

pytestでは、テストの実行時間を簡単に測定できます。

機能のテストの一環で、パフォーマンスのチェックができるのです。

--durationsオプションを使用して、最も時間のかかるテストを表示します。

pytest --durations=5

これは、最も遅い上位5つのテストの時間を表示します。

標準出力のキャプチャ方法

テスト中にコードが出力する内容をキャプチャし、テスト結果として表示できます。

これにより、printステートメントやロギング出力が確認可能です。

-sオプションを使用して、出力をキャプチャします。

pytest -s

モックを使ったテスト

こちらでは、モックオブジェクトを使用してテストする方法と、モックの使い方のメリットについて説明します。

  • モックの使い方と利点
  • 呼び出し履歴の確認と戻り値の定義

モックの使い方と利点

モックは、実際のオブジェクトの代わりにテストで使用される偽のオブジェクトです。

これは、外部サービスへの依存を排除するのに役立ちます。

pytestでは、unittest.mockを使用してモックを作成できます。

from unittest.mock import Mock

def test_example():
    mock = Mock()
    mock.method.return_value = "mocked data"
    # モックオブジェクトを使用してテストを行う

呼び出し履歴の確認と戻り値の定義

モックを使用すると、そのメソッドがどのように呼び出されたか、何回呼び出されたかを確認できます。

モックの戻り値も設定可能です。

mock.method.assert_called_once_with("argument")

methodが一度だけ呼び出され、引数として"argument"が使用されたことを確認できます。

便利な機能と拡張

こちらでは、pytestで特定のテストグループを実行する方法と、テストケースの管理方法について説明します。

  • 特定のグループの処理だけを実行
  • テストケースの管理方法

特定のグループの処理だけを実行

pytestでは、マーキング機能を利用してテストケースにタグを付けます。

これにより特定のタグを持つテストケースのみを実行可能です。

例えば、slowというマークを持つテストケースのみを実行したい場合、以下のようにします。

pytest -m slow

また、テスト関数に@pytest.mark.slowデコレータを使ってタグを付けられます。

import pytest

@pytest.mark.slow
def test_example():
    # このテストは時間がかかる可能性がある
    ...

テストケースの管理方法

大規模なプロジェクトでは、テストケースの数が増えて管理が難しくなることがあります。

pytestでは、テストケースを複数のファイルに分割して、構造化されたディレクトリ内に配置することがおすすめです。

また、pytest.iniファイルを使用して、プロジェクトのテストに関するさまざまな設定を管理できます。

まとめ

当記事を通じて、pytestの基本的な機能とその活用方法について学びました。

pytestは、Pythonプロジェクトの品質を確保し、開発プロセスを効率化するための強力なツールです。

pytestを積極的に活用することで、テスト駆動開発(TDD)を採用しやすくなり、品質が高く、メンテナンスしやすいコードを書けるようになります。

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