カバレッジの空白を埋める
目標
テストの書き方ではなく、何をテストするかを選ぶ方法を身につけます。 カバレッジを目標ではなく地図として使います。
なぜ重要なのか
カバレッジ100%は何も保証しません。assert x is not Noneだけでも100%になります。
逆に、本当に危険な場所(エラー処理、境界値)は、テストを書くのが面倒で空いたままになっていて、
まさにそのためにバグが潜んでいます。
このラボでは、その空白を数字で見つけて埋め、最後に埋めない場所を決めることで終わります。
環境
pytest --cov=<모듈> --cov-report=term-missing
pytest --cov-branch 분기 커버리지
pytest --durations=5 느린 테스트 다섯 개
このコードブロックの2つの韓国語コメントは、順に、分岐カバレッジと、遅いテスト5件の表示を述べています。プレースホルダーはモジュール名です。
ネットワークはありませんが、pytest・coverage・hypothesisはイメージに含まれています。
ステップ
- 分岐が3つの関数 →
/root/work/tt/billing.py - 正常経路だけをテスト →
test_billing.py - 抜けている行の確認 →
/root/work/tt/03-cov.txt - エラー経路を埋める
- 分岐カバレッジ →
/root/work/tt/05-branch.txt - hypothesisで性質を検証
- 遅いテスト →
/root/work/tt/07-slow.txt - テストしないもの →
/root/work/tt/08-verdict.md
参考
- テストファイルの名前は
test_で始める必要があります。そうでないとpytestが見つけられません。 --cov=billingの名前はファイル名であり、パスではありません。- hypothesisは、失敗する入力を見つけると、もっとも小さい反例に絞り込んで見せてくれます。
テスト対象のコードを作成する
分岐が3つの関数 → /root/work/tt/billing.py
/root/work/tt/billing.pyを作成します。関数は1つで十分です。discount(price, rate)が、(1)rateが0–1の範囲外ならValueError、(2)priceが負の数ならValueError、(3)それ以外なら四捨五入した整数を返すようにします。分岐が3つなので、カバレッジを読みやすくなります。
最初のテスト
正常経路だけをテスト → test_billing.py
同じフォルダーにtest_billing.pyを作成し、正常経路を1つだけテストします。pytest -qで成功させてください。まだエラー経路には触れません。次のステップで、カバレッジがそこを指摘してくれます。
抜けている行を見る
抜けている行の確認 → /root/work/tt/03-cov.txt
pytest --cov=billing --cov-report=term-missing -qを実行し、結果を/root/work/tt/03-cov.txtに保存してください。Missing列にエラー処理の行番号が表示されるはずです。数字ではなく、その行番号が答えです。
空白を埋める
エラー経路を埋める
エラー経路2つにテストを追加します。pytest.raises(ValueError)を使います。もう一度測ると、カバレッジが100%になるはずです。
分岐カバレッジは別物
分岐カバレッジ → /root/work/tt/05-branch.txt
pytest --cov=billing --cov-branch --cov-report=term-missing -qでもう一度測り、/root/work/tt/05-branch.txtに保存してください。行カバレッジが100%でも、分岐は100%ではない場合があります。その違いを見ることが目的です。
人が思いつかない入力
hypothesisで性質を検証
hypothesisでプロパティベーステストを1つ書きます。@given(st.integers(min_value=0, max_value=10**6), st.floats(min_value=0, max_value=1))で、「結果は常にprice以下」のような性質を検証してください。例を並べる代わりに、ルールを書くことが違いです。
遅いテストを洗い出す
遅いテスト → /root/work/tt/07-slow.txt
pytest --durations=5 -qでもっとも遅い5件を確認します。結果を/root/work/tt/07-slow.txtに保存してください。遅いテストは実行されなくなり、実行されないテストは、ないことよりも悪いものです。
何をテストしないかを決める
テストしないもの → /root/work/tt/08-verdict.md
/root/work/tt/08-verdict.mdに3行を書きます。(1)このモジュールで必ずテストすべきもの、(2)テストしないと決めたもの、(3)その理由です。100%を目標にしないことが、このラボの結論です。