pytestを使ったFlaskのテスト
はじめに
普段のデータ分析や機械学習モデリングをやっているのでテストコードを書くことは多くなかったので、Flaskでアプリケーションを作り出すとテストをどう具体的に書いていいのかわからなかった。基本的なことはTesting Flask Applicationsを参考にしたものの、Pytestを使っていて気になったテストの書き方をまとめる。基本的なテストの書き方やpytestの使い方については、テスト駆動Python(翔泳社、2018)で学んだ。
- 作者: Brian Okken,株式会社クイープ,安井力
- 出版社/メーカー: 翔泳社
- 発売日: 2018/08/29
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
pytestを使っていて気になった点
カバレッジの出し方
pytest-covを使う。カバーできていない部分を把握するためにterm-missing
を使うのが良い。
pytest -v --cov=source-dir --cov-report=term-missing
出力結果は下のようになる。Missingの絡むがカバーしきれていない行数として表される。
-------- coverage: platform linux, python 3.6.7-final-0 ----------- Name Stmts Miss Cover Missing ------------------------------------------- __init__.py 0 0 100% conftest.py 9 0 100% test_app.py 29 10 66% 70-85 ------------------------------------------- TOTAL 38 10 7
flake8によるコードチェックの実行
ソースコードやテストコードの中にflake8非準拠なコードがあると検出してくれるpytest-flakes。念の為やっておく感じ。
pytest --flakes [dev]
もし準拠していないコードがあると指摘してくる。
========================================================== test session starts ========================================================== platform linux -- Python 3.6.7, pytest-4.4.0, py-1.8.0, pluggy-0.9.0 rootdir: /root/work/podcast2text plugins: flakes-4.0.0, cov-2.6.1 collected 9 items __init__.py s [ 11%] conftest.py s [ 22%] test_app.py F....s. [100%] =============================================================== FAILURES ================================================================ ____________________________________________________________ pyflakes-check _____________________________________________________________ /root/work/podcast2text/tests/test_app.py:73: UndefinedName undefined name 'storage' ============================================= 1 failed, 5 passed, 3 skipped in 0.99 seconds =============================================
POSTメソッドでデータを送る場合
test_client
にPOSTメソッドでdata
をもたせればよかっただけだった。
from io import BytesIO def test_post_upload_with_file(test_client): """ GIVEN a Flask application WHEN the '/upload' page is requested (POST) with files THEN check the response is valid """ response = test_client.post( '/upload', data={ 'file': (BytesIO(b'my file contents'), 'file.txt') } ) assert response.status_code == 200