pytest備忘録
コードのフォーマットはPEP8で決まっている
最近は自動フォーマットライブラリの「black」がアツい
jupyterにも適用可能
# .py
pip install black
# jupyter
pip install black[jupyter]
# 実行
black .
テストではカバレッジを見ることが大切
「pytest-cov」ライブラリでは、コード全行に対し、テストによる実行で何行分実行されるかを見てカバレッジ判定してくれる
カバレッジが80~90%になれば良い
基本的に関数はinに対してoutが分かる程度のサイズ感や粒度でなければならない
テストを書くときはAAAパターンを意識して書くと良い
【AAA(arrange, act, assert)】
arrange: 準備段階
act: 実行
assert: 挙動の確認
テストはリファクタリング時に活きる
pytestによる異常系テストでのエラーをキャッチする方法は、with句を用いる
def add(num1, num2):
return num1 + num2
def test_2つの数字が足された値が返ること
# arrange
num1 = 2
invalid_arg = str
# act & assert
with pytest.raise(TypeError):
add(num1, invalid_arg)
テストでは副作用関数の扱いが難しい
なぜ副作用がだめなのか?
- 文脈を保持しなければ読めないコードになるため、可読性が最悪になる
- 冪等性が担保されない
副作用関数のテスト方法
- 純粋関数に分けた後にテストする
- モックを使う
テストは冪等性が重要
冪等性:何度実行しても同じ結果が得られること
ファイルレベルの副作用であれば、予めテスト用ファイルを作成する
ファイルを用意できない場合等は、モックやスタブを用意する
モック:
スタブ:
with open("aa.txt", "r+") as f:
result = f.read()
このf
に対してモックを当てることで、副作用的な関数のモックテストが成立する。
例えば、f.read()
が呼び足された際に、引数が123
だった場合は〇〇を返す
等の処理を定義しておく
ゴリゴリの副作用がある関数でも、モックとスタブを効果的に使うことでテストが可能
ただしモックの使いすぎも良くない
プルリクのレビュー時にはテストを重点的に読むと、少なくとも意図した目的の挙動をしていることは確認できる
関数にはdocstringと型ヒント、返り値を適切に書くべき
テスト時に重要なのは、どれだけ純粋性のある処理を関数として切り出すか。
最終的にmainが副作用的になるのは仕方ないが、副作用は1箇所程度に留めるのが望ましい
返り値は -> dictではなく、@dataclassを定義して返したほうが良い
関数は基本的に1つに1つの責務(目的)をもたせるべき。それ以外をすべきではなく、目的を的確に表した関数名にすべき
データの取得等はget~というメソッド名を付けるが、get以外の操作をすべきでない
「驚き最小の原則」
➞ 実装に迷ったときには、そのコードを読んだ人の驚きが最小のものを選択すべき