pytestを使ったFlaskのテスト

はじめに

普段のデータ分析や機械学習モデリングをやっているのでテストコードを書くことは多くなかったので、Flaskでアプリケーションを作り出すとテストをどう具体的に書いていいのかわからなかった。基本的なことはTesting Flask Applicationsを参考にしたものの、Pytestを使っていて気になったテストの書き方をまとめる。基本的なテストの書き方やpytestの使い方については、テスト駆動Python(翔泳社、2018)で学んだ。

テスト駆動Python

テスト駆動Python

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

参考