Pytest と Coverage を使った Flask の単体テスト

FlaskFlaskBeginner
今すぐ練習

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Flask アプリケーションの単体テストを書く方法を学びます。pytestcoverage を使ってコードをテストし、測定します。この実験が終わるとき、アプリケーションが期待通りに動作することを確認し、改善が必要な部分を特定できるようになります。

注: コードファイルは自分で作成し、環境で実行する必要があります。Web 5000 で Flask サービスの状態をプレビューできます。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL flask(("Flask")) -.-> flask/DevelopmentToolsGroup(["Development Tools"]) flask(("Flask")) -.-> flask/DataHandlingGroup(["Data Handling"]) flask(("Flask")) -.-> flask/CoreConceptsGroup(["Core Concepts"]) flask/DataHandlingGroup -.-> flask/incoming_request_data("Incoming Request Data") flask/DataHandlingGroup -.-> flask/application_globals("Application Globals") flask/DataHandlingGroup -.-> flask/response_objects("Response Objects") flask/CoreConceptsGroup -.-> flask/application_object("Application Object") flask/CoreConceptsGroup -.-> flask/session_interface("Session Interface") flask/CoreConceptsGroup -.-> flask/test_client("Test Client") flask/CoreConceptsGroup -.-> flask/useful_internals("Useful Internals") flask/DevelopmentToolsGroup -.-> flask/blueprint_objects("Blueprint Objects") flask/DevelopmentToolsGroup -.-> flask/command_line_interface("Command Line Interface") subgraph Lab Skills flask/incoming_request_data -.-> lab-136342{{"Pytest と Coverage を使った Flask の単体テスト"}} flask/application_globals -.-> lab-136342{{"Pytest と Coverage を使った Flask の単体テスト"}} flask/response_objects -.-> lab-136342{{"Pytest と Coverage を使った Flask の単体テスト"}} flask/application_object -.-> lab-136342{{"Pytest と Coverage を使った Flask の単体テスト"}} flask/session_interface -.-> lab-136342{{"Pytest と Coverage を使った Flask の単体テスト"}} flask/test_client -.-> lab-136342{{"Pytest と Coverage を使った Flask の単体テスト"}} flask/useful_internals -.-> lab-136342{{"Pytest と Coverage を使った Flask の単体テスト"}} flask/blueprint_objects -.-> lab-136342{{"Pytest と Coverage を使った Flask の単体テスト"}} flask/command_line_interface -.-> lab-136342{{"Pytest と Coverage を使った Flask の単体テスト"}} end

Pytest と Coverage のインストール

まず、pytestcoverage をインストールする必要があります。これらはそれぞれテストツールとコード測定ツールです。端末で以下のコマンドを実行してインストールします。

pip install pytest coverage

セットアップとフィクスチャ

次に、conftest.py という名前のファイルにテストフィクスチャをセットアップします。フィクスチャは、適用される各テスト関数の前に実行される関数です。

このステップでは、一時的なデータベースを作成し、テスト用のデータを格納します。

tests/conftest.py に追加するコードは以下の通りです。

## tests/conftest.py

import os
import tempfile
import pytest
from flaskr import create_app
from flaskr.db import get_db, init_db

with open(os.path.join(os.path.dirname(__file__), 'data.sql'), 'rb') as f:
    _data_sql = f.read().decode('utf8')

@pytest.fixture
def app():
    db_fd, db_path = tempfile.mkstemp()

    app = create_app({
        'TESTING': True,
        'DATABASE': db_path,
    })

    with app.app_context():
        init_db()
        get_db().executescript(_data_sql)

    yield app

    os.close(db_fd)
    os.unlink(db_path)

@pytest.fixture
def client(app):
    return app.test_client()

@pytest.fixture
def runner(app):
    return app.test_cli_runner()

ファクトリ関数のテストの作成

次に、Flask アプリケーションを作成する責任のあるファクトリ関数のテストを作成します。これらのテストは、渡された設定に基づいてアプリケーションが期待通りに動作することを確認します。

tests/test_factory.py に追加するコードは以下の通りです。

## tests/test_factory.py

from flaskr import create_app

def test_config():
    assert not create_app().testing
    assert create_app({'TESTING': True}).testing

def test_hello(client):
    response = client.get('/hello')
    assert response.data == b'Hello, World!'

データベース接続のテスト

ファクトリ関数のテストの後、データベース接続をテストします。これらのテストは、データベース接続が期待通りに確立され、閉じられることを確認します。

tests/test_db.py に追加するコードは以下の通りです。

## tests/test_db.py

import sqlite3
import pytest
from flaskr.db import get_db

def test_get_close_db(app):
    with app.app_context():
        db = get_db()
        assert db is get_db()

    with pytest.raises(sqlite3.ProgrammingError) as e:
        db.execute('SELECT 1')

    assert 'closed' in str(e.value)

認証のテスト

次に、ユーザー認証のテストを作成します。これらのテストは、ユーザーが期待通りにログインおよびログアウトできること、および必要に応じて適切なエラーメッセージが表示されることを確認します。

tests/test_auth.py に追加するコードは以下の通りです。

## tests/test_auth.py

import pytest
from flask import g, session
from flaskr.db import get_db

def test_login(client, auth):
    assert client.get('/auth/login').status_code == 200
    response = auth.login()
    assert response.headers["Location"] == "/"

    with client:
        client.get('/')
        assert session['user_id'] == 1
        assert g.user['username'] == 'test'

ブログ投稿のテスト

最後に、ブログ投稿のテストを作成します。これらのテストは、ユーザーが期待通りにブログ投稿を作成、更新、および削除できることを確認します。

tests/test_blog.py に追加するコードは以下の通りです。

## tests/test_blog.py

import pytest
from flaskr.db import get_db

def test_create(client, auth, app):
    auth.login()
    assert client.get('/create').status_code == 200
    client.post('/create', data={'title': 'created', 'body': ''})

    with app.app_context():
        db = get_db()
        count = db.execute('SELECT COUNT(id) FROM post').fetchone()[0]
        assert count == 2

テストの実行

これでテストを作成したので、pytest コマンドを使用して実行できます。

pytest

テストのコードカバレッジを測定するには、coverage コマンドを使用して pytest を実行します。

coverage run -m pytest

次のコマンドでターミナルに簡単なカバレッジレポートを表示できます。

coverage report

まとめ

この実験では、pytestcoverage を使用して Flask アプリケーションの単体テストを作成する方法を学びました。これらのツールは、アプリケーションが期待通りに機能することを確認し、改善が必要な部分を特定するのに役立ちます。コードのテストを作成することは、バグが問題になる前にキャッチするのに役立つため、良い慣習です。