「テストを書いているのに、なぜかバグが見つからない…」そんな経験、ありませんか?
Pythonはテストツールが充実しているので、テストをたくさん書くのは簡単です。でも「良いテスト」を書けているかどうかは、また別の話なんですよね。
カバレッジ(テスト網羅率)を追いかけるだけだったり、モックを使いすぎて本物の動作を確認できていなかったり……。CIは通るのに本番でバグが出る、という悲劇はここから生まれます。
今回は Testing Best Practices in Python として、pytestを使った「本当に意味のあるテスト」の書き方を5つのポイントに絞って解説します 🐍
✅ ポイント①:parametrize で重複テストをまとめる

同じテストを「入力値だけ変えてコピペ」していませんか? それ、pytest.mark.parametrize で一発解決できます。
# ❌ こうなりがちなコピペテスト
def test_add_1():
assert add(1, 2) == 3
def test_add_2():
assert add(0, 0) == 0
# ✅ parametrize でスッキリまとめる
import pytest
@pytest.mark.parametrize("a, b, expected", [
(1, 2, 3), # 通常ケース
(0, 0, 0), # ゼロ同士
(-1, 1, 0), # マイナス値
])
def test_add(a, b, expected):
assert add(a, b) == expected
ポイントをまとめるとこんな感じです👇
- 入力パターンをリストで管理できるので追加・修正が楽
- テスト名にパラメータが自動で入るので失敗箇所が一目瞭然
- コードの重複が減り、メンテナンスコストが下がる
✅ ポイント②:fixture で前処理・後処理を共通化する
DBの接続やファイルの準備など、テストの「準備と後片付け」を毎回書くのは非効率です。fixture を使えばその処理を再利用できます。
import pytest
@pytest.fixture
def sample_user():
# テスト前の準備(Arrange)
user = {"name": "田中", "age": 30}
yield user # ← ここでテスト本体に渡す
# テスト後の後片付け(Teardown)があればここに書く
def test_user_name(sample_user):
# fixture を引数として受け取るだけでOK ✨
assert sample_user["name"] == "田中"
def test_user_age(sample_user):
assert sample_user["age"] == 30
✅ ポイント③:モックのしすぎに注意する
外部APIやDBをモック(偽物に差し替え)することは大切ですが、モックしすぎると「コードの形だけテストして、実際の動作を確認していない」 状態になります。
イメージとしては、「実際に料理せずに、レシピを読み上げるだけ」みたいな感じです。
pytestの monkeypatch を使いつつも、モックの範囲は最小限にとどめましょう。
✅ ポイント④:テスト名は「何をテストしているか」が分かる名前に
test_1 や test_func という名前では、失敗したときに原因が分かりません。test_割引後の価格が正しく計算される のように、日本語でも英語でも「意図が伝わる名前」 をつける習慣をつけましょう。
✅ ポイント⑤:カバレッジより「重要なロジックのテスト」を優先
100%カバレッジを目指すより、ビジネスロジックの境界値・エラーケース・副作用のあるコード を重点的にテストする方が実際のバグ検出につながります。
まとめ
Pythonの Testing Best Practices を5つのポイントで整理しました 🎉
parametrizeで重複テストをまとめるfixtureで前後処理を共通化する- モックは最小限にとどめる
- テスト名は意図が伝わるものにする
- カバレッジより重要ロジックを優先する
「テストを書く」から「良いテストを書く」へ。この5つを意識するだけで、テストの質がぐっと上がりますよ。ぜひ今日のコードから試してみてください!💪





