ブログblog

pytestを使ってみる(基礎編)

Writer: yasuhara 更新日:2023/07/26

現在のプロジェクトで初めてpytestを使用したテストの自動化を行ったので、備忘録としてまとめます。

pytestを使う理由

一口にPythonのテストツールといっても現在いろいろなツールがある。
今回pytestを使用する理由を、例としてPython標準ツールのunittestと比較してみる

その1.直観的に書ける
pytestはassertの後に条件式を書けば結果の検証ができるが
unittestは複数種類のassert関数を覚える必要がある

その2.Classを書かなくていい
unittestはテスト用のClassを作成する必要があるが
pytestはtest_*.pyまたは*_test.pyという名前のファイルに、test_*という関数名を付けるとpytestがテスト関数だと判断してくれる

その3.テストの失敗理由が分かりやすい
unittestどのテストで失敗したかはわかるがテスト中のどの部分で失敗したか、なぜそのテストが失敗したかが示されない
pytestは失敗した箇所のどの値がなぜダメだったかをわかりやすく表示してくれる

assert

assertの後に検証したい内容を書く
引数a,bを足した値を返す関数add_funcをテストしたいとすると

add_func(1, 2)の返り値は3が返ってきて、期待通りの値が返ってきてテストをパスする。
一方で

のようなコードだとadd_func(1, 2)の返り値は-1となり、返り値が期待通りでないのでテストをパスできず、add_funcの実装が間違っていることが分かる。

parametrize

次に引数aから引数bを引いた値を返す関数sub_funcのテストを考える
この場合テストパターンとして(a>b, a=b, a<b)の3通りのテストをしたいとする

としてもよいのだがテスト関数の部分は

と書くことができる。
3通りぐらいなら上の書き方でもよいのだがテストパターンが増えてくると、parametrizeの第二引数を別のファイルで定義して渡すとよい

freeze_time

現在の日付の1週間前の日付を返す関数をテストすることを考える

テストしたい関数の中でdatetime.datetime.now()を扱う場合、テストを行う日時によってnow()の中身が変動してしまう。
そうすると出力される値が特定できないためテストができなくなってしまう。
そこでfreeze_timeを使うとテストを実行する日時を固定することができる