ストレステスト

ストレステストは、設定したシナリオに応じて、現実的な条件または極端な条件下でのアプリケーションの安定性と信頼性を検査するテストの一種です。たとえば、ストレステストを使用して、アプリケーションが大量のリクエストを処理できることや、大量のデータを処理できることを検証できます。

Pestでは、ストレステストの機能を期待値APIと組み合わせることで、時間の経過に伴う安定性と信頼性の低下を防ぐことができます。これは、新しいリリース後や新しいデプロイ後に、アプリケーションが安定していて信頼できることを検証するのに役立ちます。

内部的には、このプロジェクトは、API、マイクロサービス、およびWebサイトのパフォーマンスを評価するための強力なオープンソースの負荷テストツールであるk6を利用しています。k6はAGPL-3.0ライセンスの下でライセンスされており、プラグインを初めて使用するときにk6バイナリがダウンロードされます。

Pestのストレステストプラグイン(一般にStresslessとして知られています)の使用を開始するには、Composerを介してstresslessプラグインをrequireする必要があります。

1composer require pestphp/pest-plugin-stressless --dev

プラグインをrequireした後、次の2つの異なる方法で使用を開始できます

  • stressコマンドの使用:結果に期待値を設定せずに、URLのストレステストをすばやく実行したい場合に便利です。
  • stress()関数の使用:URLのストレステストを実行し、結果に期待値を設定したい場合に便利です。

外部ドメインまたはローカルIPアドレスのテスト? 外部ネットワークからドメインの負荷テストを行う場合、一般的なユーザー負荷下でアプリケーションがどのように実行されるかについて、現実的な図が得られます。これには、ネットワーク遅延や実際のインターネットトラフィックなどの要因が含まれます。ただし、ネットワーク内のローカルIPアドレスをテストする場合、焦点は、インターネットやDNS解決時間などの外部変数を含まずに、制御された環境で内部インフラストラクチャのパフォーマンスを理解することにあります。これは、独自のネットワークまたはサーバー内の潜在的なボトルネックを特定し、内部アプリケーションまたはサーバーのパフォーマンスを調整するのに特に役立ちます。これには、PHP FPMをより効果的に構成するなどのタスクが含まれます。

stressコマンド

stressコマンドは、URLのストレステストをすばやく実行し、結果を分析したいが、結果に期待値を設定したくない場合に便利です。これはストレステストを開始する最も速い方法であり、ターミナルで直接実行されます。

まず、stressコマンドを使用し、ストレステストを実行するURLを指定します

1./vendor/bin/pest stress example.com

デフォルトでは、ストレステストの継続時間は5秒です。ただし、--durationオプションを使用してこの値をカスタマイズできます

1./vendor/bin/pest stress example.com --duration=5

さらに、同時リクエストの数は1になります。ただし、--concurrencyオプションを使用してこの値をカスタマイズすることもできます

1./vendor/bin/pest stress example.com --concurrency=5

同時実行値は、指定されたURLに対して行われる同時リクエストの数を表します。たとえば、同時実行を5に設定した場合、Pestはストレステストの継続時間に達するまで、指定されたURLに対して常に5つの同時リクエストを行います。

構成する同時リクエストの数には注意が必要です。同時リクエストが多すぎると、アプリケーション、サーバーに過負荷がかかったり、レート制限/ファイアウォールに達したりする可能性があります。

ストレステストに使用されるHTTPメソッドを指定する場合は、提供されているdeletegetheadoptionspatchput、またはpostオプションのいずれかを使用できます。optionspatch、およびputオプションを使用すると、リクエストで使用するオプションのペイロード引数を指定できます。postオプションを使用する場合、ペイロード引数を指定する必要があります。

1./vendor/bin/pest stress example.com/articles
2# or
3./vendor/bin/pest stress example.com/articles --get
4# or
5./vendor/bin/pest stress example.com/articles --head
6# or
7./vendor/bin/pest stress example.com/articles --options
8# or
9./vendor/bin/pest stress example.com/articles --options='{"name": "Nuno"}'
10# or
11./vendor/bin/pest stress example.com/articles/1 --patch
12# or
13./vendor/bin/pest stress example.com/articles/1 --patch='{"name": "Nuno"}'
14# or
15./vendor/bin/pest stress example.com/articles --put
16# or
17./vendor/bin/pest stress example.com/articles --put='{"name": "Nuno"}'
18# or
19./vendor/bin/pest stress example.com/articles --post='{"name": "Nuno"}'
20# or
21./vendor/bin/pest stress example.com/articles/1 --delete

ストレステストが完了すると、Pestはストレステスト結果の概要を表示します。

stress関数

ストレステストの仕組みを理解し始めたら、ストレステストの結果に期待値を設定したくなるかもしれません。たとえば、平均応答時間が常に100ms未満であることを検証したい場合があり、ここでstress()関数が役立ちます。

まず、通常のテストを作成し、stress()関数を使用して指定されたURLをストレステストします

1<?php
2 
3use function Pest\Stressless\stress;
4 
5it('has a fast response time', function () {
6 $result = stress('example.com');
7 
8 expect($result->requests()->duration()->med())->toBeLessThan(100); // < 100.00ms
9});

デフォルトでは、ストレステストの継続時間は10秒です。ただし、for()->seconds()メソッドを使用してこの値をカスタマイズできます

1$result = stress('example.com')->for(5)->seconds();

さらに、同時リクエストの数は1になります。ただし、concurrentlyメソッドを使用してこの値をカスタマイズすることもできます

1$result = stress('example.com')->concurrently(requests: 2)->for(5)->seconds();

いつでも、ストレステストの結果をddして、詳細(stressコマンドを使用した場合のように)を確認できます

1$result = stress('example.com')->dd();
2 //->dump();
3 //->verbosely();

ストレステストに使用するHTTPメソッドを指定する場合は、提供されているdeletegetheadoptionspatchput、またはpostメソッドのいずれかを使用できます。optionspatch、およびputメソッドを使用すると、リクエストで使用するオプションのペイロード引数を指定できます。postメソッドを使用する場合、ペイロード引数を指定する必要があります。

1$result = stress('example.com/articles/1')->delete();
2// or
3$result = stress('example.com/articles')->get();
4// or
5$result = stress('example.com/articles')->head();
6// or
7$result = stress('example.com/articles')->options();
8// or
9$result = stress('example.com/articles')->options(["name" => "Nuno"]);
10// or
11$result = stress('example.com/articles/1')->patch();
12// or
13$result = stress('example.com/articles/1')->patch(["name" => "Nuno"]);
14// or
15$result = stress('example.com/articles')->put();
16// or
17$result = stress('example.com/articles')->put(["name" => "Nuno"]);
18// or
19$result = stress('example.com/articles')->post(["name" => "Nuno"]);

stress()関数はストレステストの結果を返し、これを使用して期待値を設定できます。以下は、利用可能なメソッドのリストです

リクエスト時間

全体的なリクエスト時間をミリ秒単位で返します。

1$result->requests()->duration()->med();
2 // ->min();
3 // ->max();
4 // ->p90();
5 // ->p95();

リクエスト数

実行されたリクエストの数を返します。

1$result->requests()->count();

リクエスト レート

1秒あたりに実行されたリクエストの数を返します。

1$result->requests()->rate();

失敗したリクエスト数

失敗したリクエストの数を返します。

1$result->requests()->failed()->count();

失敗したリクエストのレート

1秒あたりに失敗したリクエストの数を返します。

1$result->requests()->failed()->rate();

リクエストの最初のバイトまでの時間 / TTFB

リクエストの最初のバイトまでの時間をミリ秒単位で返します。

1$result->requests()->ttfb()->duration()->med();
2 // ->min();
3 // ->max();
4 // ->p90();
5 // ->p95();

リクエストDNSルックアップ時間

このメトリクスは、クライアントとDNSサーバー間のネットワーク遅延の影響を受けます。

リクエストのDNSルックアップ時間をミリ秒単位で返します。

1$result->requests()->dnsLookup()->duration()->med();
2 // ->min();
3 // ->max();
4 // ->p90();
5 // ->p95();

リクエストTLSハンドシェイク時間

このメトリクスは、クライアントとサーバー間のネットワーク遅延の影響を受けます。

リクエストのTLSハンドシェイク時間をミリ秒単位で返します。

1$result->requests()->tlsHandshaking()->duration()->med();
2 // ->min();
3 // ->max();
4 // ->p90();
5 // ->p95();

リクエストのダウンロード時間

このメトリクスは、クライアントとサーバー間のネットワーク遅延の影響を受けます。

リクエストのダウンロード時間をミリ秒単位で返します。

1$result->requests()->download()->duration()->med();
2 // ->min();
3 // ->max();
4 // ->p90();
5 // ->p95();

リクエストのダウンロードデータ数

リクエストのダウンロードデータ数をバイト単位で返します。

1$result->requests()->download()->data()->count();

リクエストのダウンロードデータ レート

リクエストのダウンロードデータ レートをバイト/秒単位で返します。

1$result->requests()->download()->data()->rate();

リクエストのアップロード時間

このメトリクスは、クライアントとサーバー間のネットワーク遅延の影響を受けます。

リクエストのアップロード時間をミリ秒単位で返します。

1$result->requests()->upload()->duration()->med();
2 // ->min();
3 // ->max();
4 // ->p90();
5 // ->p95();

リクエストのアップロードデータ数

リクエストのアップロードデータ数をバイト単位で返します。

1$result->requests()->upload()->data()->count();

リクエストのアップロードデータ レート

リクエストのアップロードデータ レートをバイト/秒単位で返します。

1$result->requests()->upload()->data()->rate();

テスト実行の同時実行数

ストレステスト中に実行された同時リクエストの数を返します。これは、--concurrencyオプションまたはconcurrentlyメソッドを使用して設定した値です。

1$result->testRun()->concurrency();

テスト実行時間

ストレステストの継続時間を返します。これは、--durationオプションまたはfor()->seconds()メソッドを使用して設定した値です。

1$result->testRun()->duration();

ここでは、Pestのストレステストプラグイン(別名stressless)を使用して、指定されたURLをストレステストし、結果に期待値を設定する方法を見てきました。次に、テストコードのカバレッジをテストする方法を調べてみましょう:テスト カバレッジ