📝

プロパティ・ベースド・テスト(PBT)を入門せずに恩恵に預かろう

2023/03/26に公開

ソフトウェア開発におけるテスト技術は急速に進化しています。中でも、プロパティ・ベースド・テスト(Property-Based Testing、略称PBT)が注目されていますが、まだ十分に普及していないと感じられます。

この記事では、プロパティ・ベースド・テストの基本概念や特徴については触れず、実践から入ります。簡単な使い方を学んで、プロパティ・ベースド・テストの効果を実感してみましょう。本格的な理解はその後でも問題ありません。

今回は、OpenAPIのインターフェースに従って自動的にテストを行うSchemathesisを使用します

OpenAPIとSchemathesis

OpenAPIは、WebAPIのURLやデータ型を記述する形式です。通常、openapi.jsonというファイルに記載されます。共通規格であるため、言語に関係なく対応するモジュールが存在するのが特徴です。Pythonの場合、FastAPIがよく知られており、openapi.jsonをGUIで表示してテストすることもできます。以下に、FastAPIでルートパスにPOSTリクエストを送信する設定を行った場合の画面例を示します。

FastAPI example

Schemathesisは、openapi.jsonを読み込んで自動テストを実行するPythonツールです。この自動テストでは、プロパティ・ベースド・テストの技術が使用されています。

Schemathesisのインストールは以下のコマンドで行えます。

pip install schemathesis

プロパティ・ベースド・テストの実行

プロパティ・ベースド・テストを実行するには、以下のコマンドを使用します。

st run http://localhost:8000/openapi.json

このコマンドでは、先程作成したopenapi.jsonが置かれているURLを指定します。Schemathesisは、指定されたURLからopenapi.jsonを解析し、適切なテストを実行してくれます。

テストが成功すると、以下のような結果が表示されます。

$ st run http://localhost:8000/openapi.json
======== Schemathesis test session starts =======
Schema location: http://localhost:8000/openapi.json
Base URL: http://localhost:8000/
Specification version: Open API 3.0.2
Workers: 1
Collected API operations: 1

POST / .                                                   [100%]

==================== SUMMARY ====================

Performed checks:
    not_a_server_error                    100 / 100 passed          PASSED 

=============== 1 passed in 6.88s ===============

プロパティ・ベースド・テストの特徴は、少ないテストケースで効果的に問題点を見つける戦略を採用している点です。Schemathesisでは、デフォルトで約100件のテストケースが実行されます。

テストが失敗した場合、以下のようにエラー情報と、同じテストを再現するためのcURLコマンドが表示されます。

_____________________ POST / ____________________
1. Received a response with 5xx status code: 500

Response status: 500
Response payload: `Internal Server Error`

Run this cURL command to reproduce this failure: 

    curl -X POST -H 'X-Schemathesis-TestCaseId: acee303a2cad43679f6d3045ca95ae18' -d '{"name": "~\""}' http://localhost:8000/

Or add this option to your command line parameters: --hypothesis-seed=53395269705890779247189765810423542745

簡単ですね。OpenAPIを使用している場合、テストの実行にそれほど時間がかかりません。ぜひ一度、試してみてください。

Discussion