【初心者〜現場で活躍まで】挫折しないPython勉強方法もっと知る

【初心者OK】pytestの使い方をやさしく解説

【初心者OK】pytestの使い方をやさしく解説
エソラ

「テストコードが書けたら良いな」と思いながらも、学習コストが高いため、習得を諦めた人も多いと思います。

メリットデメリット
一度作れば、自動テストができて、作業量が激減する
リファクタリング(一度書いたコードの修正)がしやすくなり、保守性が上がる
デグレーション(修正時に、意図しない不具合が発生)を防げるので、かっこ悪い謝罪が少なくなる
学習コストが高い
テストコードを書く工数が余計にかかる
テストしやすいように、コードを修正する場合がある
単体テストを書くメリット・デメリット

この記事ではpytestについて、現場で使えるように徹底的に解説します。

具体的には、インストールから始めて、assert文の書き方、fixtureを使った前処理・後処理の実装方法、パラメーター化テストなど、初心者レベルから、中級者レベルまでをカバーした内容となります。

エソラ

pytestをマスターすれば、品質の高いソフトウェアを開発できて、現場で重宝されると思います。

この記事を書いた人

エソラ
  • エンジニア歴10数年
  • SIerでDX推進を仕事に
  • Python、AWSを使ったアーキテクチャ設計・アプリ開発が得意
  • 30代、2児の父でサウナ好き
  • [icon-class=”icon-twitter”]Twitter

ちなみに、私の環境のバージョン情報は以下の通りです。

項目バージョン
Python3.10.6
pytest7.1.3
バージョン情報

それでは、最後までよろしくお願いします。

目次

pytestのインストール方法

pytestはPythonの標準ライブラリではないため、pipを利用して、インストールが必要です。

Windowsなら、コマンドプロンプト、Macなら、ターミナルを開いて、以下のコマンドを入力します。

$ pip install pytest

これで、pytestのインストールが完了しました。

エソラ

実際の現場では、環境差異をなくすため、requirements.txtを使って、モジュールをインストールすることが多いです。

requirements.txtでインストールする方法は以下の記事で詳しく解説しています。

pytestの書き方:命名規則

pytestには、テストコードと認識させるため、命名規則があります。

対象ルール
テストファイル名test_ hoge.py or hoge_test.py
テストメソッド名test_hoge
テストクラス名TestHoge
pytestの命名規則

このルールに従うと、test_ hoge.pyの内容は以下となります。

# テストクラス名
class TestHoge():

    # テストメソッド名
    def test_hoge(self):
        assert "test" == "test"

テストコードを動かすと、テストに成功します。

$ pytest
================================================= test session starts ==================================================
platform darwin -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0
rootdir: (省略)
collected 1 item                                                                                                       

test_ hoge.py .                                                                                                  [100%]

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

ちなみに、ルールを破って実装すると、

# テストクラス名
class testHoge(): # <= TestHoge()をtestHoge()に変更した

    # テストメソッド名
    def test_hoge(self):
        assert "test" == "test"

テストコードが見つからないと、以下のように警告されます。

$ pytest
================================================= test session starts ==================================================
platform darwin -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0
rootdir: (省略)
collected 0 items                                                                                                      

================================================ no tests ran in 0.01s =================================================

コンソールに「no tests ran」と表示されたら、命名規則に誤りがないか確認しましょう。

assert文の書き方

Pythonでテストをする時は、assert文を利用して、値の正当性を検証します。

エソラ

assert文を基本として、テストコードを組み立てます。

pytestで使えるasset文の一覧は以下の表の通り。

pytestunittest意味
assert hogeassertTrue(hoge)hogeがTrueか検証
asser not hogeassertFalse(hoge)hogeがFalseか検証
assert hoge == fugaassertEqual(hoge, fuga)hogeとhugaが同じか検証
assert hoge != fugaassertNotEqual(hoge, fuga)hogeとhugaが異なるか検証
assert hoge is NoneassertIsNone(hoge, fuga)hogeがNoneか検証
assert hoge is not NoneassertIsNotNone(hoge, fuga)hogeがNoneではないか検証
assert hoge <= fugaassertLessEqual(hoge, fuga)hoge <= fugaか検証
assert hoge < fugaassertLess(hoge, fuga)hoge < fugaか検証
assert hoge >= fugaassertGreaterEqual(hoge, fuga)hoge >= fugaか検証
assert hoge > fugaassertGreater(hoge, fuga)hoge > fugaか検証
assert文の種類と意味

Pythonの標準ライブラリであるunittestで比べて、pytestの方が直感的に書けると感じると思います。

エソラ

unittestだとメソッド名を忘れてググったりしますが、pytestはやりたいことをそのまま書けるなので、忘れにくいですね。

実装例は以下です。

class TestAssert():

    def test_asserts(self):
        # hogeがTrueか検証
        hoge = True
        assert hoge

        # hogeがFalseか検証
        hoge = False
        assert not hoge

        # hogeとhugaが同じか検証
        assert "hoge" == "hoge"

        # hogeとhugaが異なるか検証
        assert "hoge" != "fuga"

        # hogeがNoneか検証
        hoge = None
        assert hoge is None

        # hogeがNoneではないか検証
        hoge = "hoge"
        assert hoge is not None

        # hoge <= fugaか検証
        hoge = 1
        fuga = 2
        assert hoge <= fuga

        # hoge < fugaか検証
        hoge = 1
        fuga = 2
        assert hoge < fuga

        # hoge >= fugaか検証
        hoge = 2
        fuga = 1
        assert hoge >= fuga

        # hoge > fugaか検証
        hoge = 2
        fuga = 1
        assert hoge > fuga

上記の実装例では、全てのテストケースがpassします。

$ pytest test_assert.py 
================================================= test session starts ==================================================
platform darwin -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0
rootdir: (省略)
collected 1 item                                                                                                       

test_assert.py .                                                                                                 [100%]

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

pytestで例外を発生させる方法

pytestでは例外の発生についても、検証が可能です。

例えば、以下のようなFizzBuzzを単純化したプログラムがあるとします。

def fizzbuzz(num):
    if num % 15 == 0:
        return 'FizzBuzz'
    elif num % 3 == 0:
        return 'Fizz'
    elif num % 5 == 0:
        return 'Buzz'
    else:
        return str(num)

この関数はint型で入力されることを期待していますが、文字列型を渡して、例外を発生させるコードを書いてみます。

import pytest
from src.fizzbuzz import fizzbuzz


@pytest.mark.parametrize(
    "num, expected",
    [
        ("15", 'not all arguments converted during string formatting'),
    ],
)
def test_fizzbuzz_fail(num, expected):
    """
    文字列型を渡して、例外を発生
    """
    with pytest.raises(TypeError) as exc_info:
        fizzbuzz(num)
    assert expected in str(exc_info.value)

with pytest.raises(TypeError)はTypeErrorが発生する予定であることを意味します。

もしも、TypeErrorが発生しない場合は、テストケースが失敗します。

例外が出力するエラーメッセージの検証をする場合は、with句に対して、asで別名(今回はexc_info)をつけて、exc_info.valueでメッセージを取得できます。

fixture(フィクスチャ)の使い方

fixture(フィクスチャ)を使えば、テストの前処理、後処理を書けます。

pytest以外のxUnitに詳しいなら、fixtureはsetup()、teardown()に相当すると考えると理解しやすいです。

fixtureを使うと、テスト関数から前処理・後処理を分離できて、シンプルで保守性の高いテストコードが書けます。

エソラ

fixtureの前処理・後処理でよくやる処理例は以下の通り

項目よくやる処理例
前処理DBのセットアップ
モック化
パラメータ化
後処理DBのクローズ処理
tempファイルの削除処理
fixtureの前処理・後処理でよくやる処理例

fixtureの使い方を知りたいなら、以下の記事にまとめています。簡単に前処理・後処理が書けるようになります。

パラメーター化

テストを書いていると、同じ処理を異なるデータで検証したい時があります。何も考えないと、似たコードが量産されますが、パラメータ化をすると解決できます。

パラメータ化すれば、短くシンプルなコードで、一つのテスト関数を複数のテストデータで検証できます。

pytestでのパラメータ化には、3つの方法があります。

パラメータ化する3つの方法
  • テスト関数をパラメータ化:最もスタンダード
  • fixtureをパラメータ化:前処理、後処理を書きたい時に利用
  • フック関数(pytest_generate_tests)で、パラメータ化:複雑なデータセットを書きたい時に利用

pytestでパラメータテストをする方法は、以下の記事で詳しく解説しています。様々なデータセットで検証できます。

カバレッジの出力方法

テストコードを書いていると、どれくらいテストコードを書くべきか迷うことがあります。その時に有効なのが、カバレッジです。

カバレッジとは、開発したプログラムに対するテストのカバー率のことを言います。カバレッジが高いとテストの網羅率が高いと判断ができます。

pytestなら、カバレッジも簡単に出力することができます。

カバレッジを見れば、どんなテストをどれくらい書いたら良いのかすぐに分かるので、品質の向上につながります。

こんな感じで、カバレッジレポートが見れます

エソラ

カバレッジを見ない現場はないと言ってもいいかも知れません。

HTML形式で出力可能なので、現場でチームメンバーと共有したい時も便利です。

品質の高いコードを書きたいなら、カバレッジが頼もしい味方になります。

具体的なpytestでカバレッジを出力する方法については、以下の記事で詳しく解説しています。

コマンドオプションの使い方

pytestを実行する時に、引数に様々なオプションを指定することができます。

pytestでよく使うオプションは以下の通りです。

pytestでよく使うオプション
  • –collect-only:実行される予定のテストケースを表示
  • -x:テストが失敗した時点で終了する
  • -s:print文を出力させる
  • –lf:失敗しているテストだけを実行する
  • -q:出力する情報を少なくする
  • -k:指定した文字列で検索して、テスト実行する

pytestでオプションを使った場合の実行結果については、以下の記事で詳しくまとめています。

pytestのおすすめ勉強法

もっと深くpytestを勉強したいなら、以下がおすすめです。

pytestのおすすめ勉強法

公式ページ

pytestの公式ページは以下です。

pytestの最新情報はこの公式ページで確認しましょう。

エソラ

ただし、残念ながら全て英語となっていますので、初心者には難しいかもです。

Pythonテスト駆動開発 第2版

初心者がpytestを学ぶなら、「Pythonテスト駆動開発 第2版」がおすすめです。

テスト駆動Python第2版
総合評価
( 5 )
メリット
  • 日本語でpytestの全てについて、解説されている唯一の書籍
  • 段々とステップアップして、深くなるので、初心者でも、中級者でも、上級者でも、学びがある
  • サンプルコードには、サンプルアプリが含まれているため、実践的に学べる工夫あり
  • 章末にまとめがあり、復習の役に立つ
  • 第7章に「どのようなテストを書くのか」についての解説があり、テストに対する考え方が深まる
デメリット
  • 後半になると、かなり高度な内容になるため、初心者には難しい
  • タイトルに「テスト駆動開発」と書かれているが、該当部分の記述が少なく、テスト駆動開発を知りたい人は期待外れになるかも

pytestについて、必要な全ての知識を解説している唯一の日本語で書かれた技術書となります。

エソラ

公式ページを読んで諦めた人でも、この書籍であれば、pytestに入門できると思います。

2022年に第2版が出版されて、内容がかなりパワーアップしました。

著:Brian Okken, 翻訳:株式会社クイープ, 監修:株式会社クイープ, 監修:安井 力
¥2,970 (2022/11/24 04:05時点 | Amazon調べ)

pytestをマスターして、品質高いプログラムを開発したいなら、必読書です。

よくある質問

よくある質問をまとめています。

pytestの特徴は?

pytestはPythonでテストコードを書く時に使うテスト・ライブラリです。最大の特徴はシンプルで分かりやすいコードなのに、高機能です。

pytestの利点は?

とにかく直感的に書くことができるので、他のテストフレームワークと比べてもコード量が減り、読みやすいです。また柔軟性があり、unittestで書かれたテストコードもpytestで実行できます。

Pythonでテストコードを書くなら、pytestとunittestどっちを利用すべきか?

個人的には、pytest一択です。理由はunittestよりも直感的に書ける(例えば、unittestはassert文のメソッド名が複雑)ので、学習コストが低いこと、テスト結果の出力が優れており、デバックがしやすいことが挙げられます。

Pythonに標準的に入っているunittestを使いたい場合、以下の記事が参考になります。

まとめ:pytestで品質の高いPythonコードを書く

ここまでpytestの使い方をサンプルを交えながら、初心者でも入門できるように解説してきました。

ここで紹介した内容は以下の通りです。

この記事で解説したpytestの使い方
  • pytestのインストール方法
  • pytestの書き方:命名規則
  • assert文の書き方
  • pytestで例外を発生させる方法
  • fixture(フィクスチャ)の使い方:前処理・後処理が書ける
  • パラメーター化:複数のデータセットでの検証が簡単に書ける
  • カバレッジの出力方法:品質の評価で使える
  • コマンドオプションの使い方:効率UP

この内容を使えたら、あなたが書くコードの品質は必ず上がります。品質を上げたいなら、pytestでテストコードを書くことは必須です。

エソラ

ぜひとも、この記事の内容をしっかりと理解して、品質の高いコードが書けるようになりましょう。

テストコードが書けたら、現場でも活躍ができると思います。

もっとpytstの使い方を学びたい場合は、以下の書籍がおすすめです。

日本語で唯一、pytestだけに焦点を当てて、詳細に書かれた書籍です。

著:Brian Okken, 翻訳:株式会社クイープ, 監修:株式会社クイープ, 監修:安井 力
¥2,970 (2022/11/24 04:05時点 | Amazon調べ)

Pythonの勉強方法は、まとめ記事があります。

Pythonを勉強する時、何から勉強するか分からず、挫折します。初心者でも、中級者でも、レベルに合わせた勉強方法を分かりやすくまとめています。

ここまでお読みいただき、ありがとうございました。

役に立った、面白かったと思ったら、SNSでシェアしてくれると嬉しいです。

エソラ

もし分からないことがあれば、お問い合わせTwitterにご連絡をいただけると嬉しいです。(Twitterの方が返信早いかも…)

\ 更新の励みになるので、ポチッとしてね /

エソラ

他にもスキルアップやキャリアアップの役に立つ情報が満載です。他の記事も読んで、ゆっくりしていってね!

【初心者OK】pytestの使い方をやさしく解説

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次