コンテンツにスキップ

2.4. パフォーマンステスト規定

このドキュメントは、パフォーマンステスト(性能テスト)の実装に関する具体的な規約を定めます。パフォーマンステストは、システムの応答性、安定性、スケーラビリティが、要求される水準を満たしていることを保証します。

1. パフォーマンステストの定義と目的

  • 定義:
    • パフォーマンステストとは、システムに対して特定の負荷(リクエスト数、同時ユーザー数など)を与え、その際の性能指標(応答時間、スループット、リソース使用率など)を測定・評価するテストです。
  • 目的:
    • 性能要件の検証: システムが、非機能要件で定義された性能目標(例: 「通常時、API応答時間は200ms以内」)を達成していることを確認します。
    • 性能リグレッションの検出: コードの変更によって、意図せず性能が低下していないかを継続的に監視します。
    • ボトルネックの特定: システムの性能を最も制限している箇所(コード、クエリ、インフラなど)を特定し、改善の指針を得ます。
    • キャパシティプランニング: システムがどの程度の負荷まで耐えられるかを把握し、将来のインフラ増強計画の参考にします。

2. パフォーマンステストの種類

目的に応じて、以下の種類のテストを使い分けます。

  • ロードテスト(負荷テスト):
    • 目的: 通常時およびピーク時に想定される負荷をシステムに与え、その際の応答時間やスループットが要件を満たすかを確認します。
  • ストレステスト(限界テスト):
    • 目的: 想定を大幅に超える負荷をシステムにかけ続け、どこで、どのようにシステムが破綻するか(限界点)を特定します。また、過負荷状態から正常に回復できるかも検証します。
  • マイクロベンチマーク:
    • 目的: 特定の関数やアルゴリズムの実行速度やメモリ消費量を、ナノ秒単位で精密に測定します。ライブラリ開発や、性能クリティカルな箇所のコード改善に用います。

3. 推奨ツール

テストの種類や対象に応じて、適切なツールを選択します。

  • API/Webサイトのロードテスト:
    • k6 (推奨): JavaScriptでテストシナリオを記述できる、モダンで開発者フレンドリーな負荷テストツール。Grafana社が開発。
    • JMeter: GUIでテストシナリオを構築できる、高機能で実績のあるJavaベースのツール。
  • コードレベルのマイクロベンチマーク:
    • C#: BenchmarkDotNet を使用します。統計的に信頼性の高い、詳細なベンチマーク結果を生成します。
    • Python: pytest-benchmark や、標準ライブラリの timeit を使用します。
    • JavaScript/TypeScript: Benchmark.js などのライブラリを使用します。

4. パフォーマンステストの実装パターン

4.1. ロードテストのシナリオ作成

  • 現実的なシナリオ: 実際のユーザー行動を模倣した、現実的なシナリオを作成します。単一のエンドポイントを攻撃するのではなく、複数のAPIを順番に呼び出す(例: ログイン→商品一覧取得→商品詳細取得)といった、現実的なワークフローをシミュレートします。
  • Think Timeの導入: ユーザーが次の操作に移るまでの思考時間をシミュレートするため、リクエストの間にランダムな待機時間(Think Time)を挿入します。
  • 段階的な負荷: 負荷は、ゼロから徐々に目標値まで上げていく(Ramp-up)ように設定します。

k6でのテストシナリオ例:

import http from 'k6/http';
import { sleep, check } from 'k6';

export const options = {
    stages: [
        { duration: '30s', target: 20 }, // 30秒かけて20VUまで増やす
        { duration: '1m', target: 20 }, // 20VUで1分間維持
        { duration: '10s', target: 0 }, // 10秒かけて0VUまで減らす
    ],
    thresholds: {
        // 95%のリクエストが200ms以内に完了すること
        http_req_duration: ['p(95)<200'],
    },
};

export default function () {
    const res = http.get('<https://test-api.example.com/public/crocodiles/1/>');
    check(res, { 'status was 200': r => r.status == 200 });
    sleep(1); // 1秒待機
}

4.2. マイクロベンチマークの実施

  • 隔離された環境: 正確な測定のため、他のプロセスの影響を極力受けない、安定した環境で実行します。
  • ウォームアップ: JITコンパイルなどの影響を避けるため、本測定の前に十分なウォームアップ(予備実行)を行います。BenchmarkDotNetなどの専門ツールは、これを自動で行います。

5. 注意事項

  • 本番環境での実行禁止: パフォーマンステストはシステムに高い負荷をかけるため、原則として本番環境で直接実行してはいけません。 本番環境と全く同じ構成の、独立した性能検証環境を準備します。
  • ベースラインの測定: 最初のテスト結果を「ベースライン(基準値)」として保存し、以降のテスト結果は常にこのベースラインと比較します。これにより、性能の向上や低下を客観的に判断できます。
  • CIへの統合:
    • マイクロベンチマークは、変更によって性能がリグレッションしていないかを確認するため、CIプロセスに組み込むことが有効です。
    • 大規模なロードテストは実行に時間がかかり、専用環境も必要なため、CIに組み込む場合は夜間バッチなどで定期実行するのが一般的です。