【Python】unittestとpytestの違い・使い分け

Python

こんにちは、かつコーチです。

Pythonでテストを書こうとすると、必ず出てくる疑問があります。

「標準ライブラリのunittestと、外部ライブラリのpytest、どっちを使えばいいの?」

ネット上のサンプルコードでも、両方の書き方が混在していて迷いやすいポイントです。

この記事では、unittestpytestの構文の違いを比較しながら、どちらを選ぶべきかの判断軸を解説します。

読み終える頃には、自分のプロジェクトに合ったテストツールを選べるようになります。

unittestとpytestとは?

unittestとは

unittestは、Pythonに標準で組み込まれているテストフレームワークです。

追加インストール不要で、import unittestとするだけですぐに使えます。

クラスベースでテストを書き、専用のメソッド(assertEqualなど)を使って検証します。

pytestとは

pytestは、外部ライブラリとして提供されているテストフレームワークです。

pip install pytestのインストールが必要ですが、標準のassert文だけでテストが書け、記述量が少なく済みます。

構文比較:同じテストを両方で書いてみる

手順1:テスト対象の関数

税込価格を計算する、同じ関数を対象にします。

# calc.py
def add_tax(price, tax_rate=0.1):
    if price < 0:
        raise ValueError("価格は0以上である必要があります")
    return int(price * (1 + tax_rate))

手順2:unittestで書く場合

unittestでは、TestCaseを継承したクラスの中にテストメソッドを定義します。

# test_calc_unittest.py
import unittest
from calc import add_tax


class TestAddTax(unittest.TestCase):
    def test_normal(self):
        self.assertEqual(add_tax(1000), 1100)

    def test_negative_price(self):
        with self.assertRaises(ValueError):
            add_tax(-100)


if __name__ == "__main__":
    unittest.main()

実行はpython -m unittestで行います。

python -m unittest test_calc_unittest.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.00s

OK

手順3:pytestで書く場合

同じ内容をpytestで書くと、クラスもメソッド名の縛りも不要になります。

# test_calc_pytest.py
import pytest
from calc import add_tax


def test_normal():
    assert add_tax(1000) == 1100


def test_negative_price():
    with pytest.raises(ValueError):
        add_tax(-100)
pytest test_calc_pytest.py
..                                                                      [100%]
2 passed in 0.01s

構文比較表

観点unittestpytest
インストール不要(標準ライブラリ)pip install pytestが必要
テストの単位TestCaseを継承したクラス関数だけでOK
値の比較self.assertEqual(a, b)assert a == b
例外の検証self.assertRaises(...)pytest.raises(...)
実行コマンドpython -m unittestpytest
記述量やや多い少ない

どちらを選ぶべきかの判断軸

判断軸1:外部ライブラリを追加できるか

社内規定やセキュリティポリシーで、外部ライブラリの追加が制限されている現場もあります。

そうした環境では、標準ライブラリだけで完結するunittestが確実な選択肢になります。

判断軸2:記述量とチームの学習コスト

個人開発や、新規にテスト文化を導入する場合はpytestがおすすめです。

assert文だけで書けるため、初めてテストを書くメンバーにも説明しやすい構文です。

判断軸3:既存プロジェクトとの整合性

すでにunittestベースのテストが大量にある場合、無理にpytestへ書き換える必要はありません。

実は、pytestのコマンドはunittest形式のテストコードもそのまま実行できます。

既存のunittestテストを残しつつ、新規テストだけpytestスタイルで書く、という併用も可能です。

よくあるつまずきポイント・エラー対処

unittest形式のクラスをpytestで実行しようとして混乱する

筆者が実際に経験したのが、unittest.TestCaseを継承したクラスに、pytest.raisesを混ぜて書いてしまったケースです。

❌ Before(混在させて動かない書き方)

import unittest
import pytest
from calc import add_tax


class TestAddTax(unittest.TestCase):
    def test_negative_price(self):
        pytest.raises(ValueError, add_tax(-100))

実行すると、次のエラーメッセージが表示されます。

ValueError: 価格は0以上である必要があります

pytest.raiseswithブロックの中で使う前提の構文です。

add_tax(-100)を先に評価してしまっているため、例外の捕捉より先にエラーが発生していました。

✅ After(unittest形式に揃えた書き方)

import unittest
from calc import add_tax


class TestAddTax(unittest.TestCase):
    def test_negative_price(self):
        with self.assertRaises(ValueError):
            add_tax(-100)

unittest.TestCaseを使うクラスの中では、self.assertRaisesに統一するのが安全です。

「クラスはunittest、検証だけpytest」のような混在は、思わぬ実行順序のバグを招きやすいので避けましょう。

まとめ

この記事のポイント

  • unittestは標準ライブラリ、pytestは外部ライブラリで記述量が少ない
  • unittestはクラスベース、pytestは関数ベースで書ける
  • 外部ライブラリ制限がある現場はunittest、新規導入はpytestが選びやすい
  • pytestコマンドはunittest形式のテストも実行できるため併用も可能
  • クラス内でunittestpytestの検証構文を混在させるとバグの元になる

次に読むべき記事

  • pytestの基本:テストの書き方入門
  • モックを使ったテストの書き方(unittest.mock)
  • テストカバレッジを計測する方法(pytest-cov)

タグ: Python, 中級者向け, テスト

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