Webアプリケーションのパフォーマンステスト概要

この記事は [ユニークビジョン株式会社 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/uniquevision) 6日目の記事です。

# はじめに

パフォーマンステストはシステムがビジネス目標を達成できるかを判断するなど、開発プロセスの中でも重要な役割を持ちます。
一方で、パフォーマンステストは正しく目的を設定して適切な手法を選択しなければあまり効果のない結果だけが得られるだけです。


そこで本記事ではパフォーマンステスト実施の際の最初の議論の助けとなることを目的に、「[Performance Testing Guidance for Web Applications](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/bb924375(v=pandp.10))」を元にWebアプリケーションのパフォーマンステストの目的と種類を紹介します。


「[Performance Testing Guidance for Web Applications](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/bb924375(v=pandp.10))」は8部18章からなるWebアプリケーションのパフォーマンステスト実施の手引きです。
このドキュメントには計画・実施・評価をはじめとするパフォーマンステストのあらゆる要素についてのプラクティスがまとまっており、パフォーマンステストの担当者は必ず読むべきドキュメントとなっています。


無料とは思えない非常に素晴らしいドキュメントなので、是非こちらもご参照下さい。


# パフォーマンステストとは

パフォーマンステストとは、特定の条件下におけるシステムの応答性、スループット、信頼性、および拡張性を判断することを目的としたテストの一種です。一般に、パフォーマンステストは

- システムのボトルネックの特定
- 将来のテストのためのベースラインの確立
- パフォーマンスのチューニング作業の支援
- パフォーマンスの目標や要件への適合性の判断
- その他のパフォーマンス関連データの収集

を目的として実施され、例えば本番運用時のハードウェア構成など、様々な意思決定に活用されます。

また、パフォーマンステストはある種の重大なビジネスリスクを管理するために不可欠です。例えば、ウェブサイトが大量のトラフィックを処理できなければ顧客は他のサイトで買い物をしてしまうでしょう。パフォーマンステストは他の種類のテストに取って代わるものではありませんが、ユーザビリティ、機能性、セキュリティと言った他の方法では確認が難しい情報を明らかにすることが出来ます。


# パフォーマンステストを通して対処されうるリスク

前述の通り、ユーザーの満足度やアプリケーションがビジネス目標を達成できるかどうかなど、アプリケーションやビジネスに関するほとんどすべてのリスクはパフォーマンステストによって対処することができます。

一般に、パフォーマンステストで対処するリスクは速度、スケーラビリティ、安定性の観点から分類されます。速度はエンドユーザの関心事、スケーラビリティはビジネス上の関心事であり、安定性は技術的またはメンテナンス上の関心事です。

## 速度に関するリスク

速度に関するリスクとして多くの人が最初に思い浮かべるのはエンドユーザーの満足度ですが、ビジネスやデータに関連したリスクの要因にもなります。
パフォーマンステストで対処できる速度に関するリスクには次のようなものがあります。

- アプリケーションはエンドユーザーを満足させるだけの速度がありますか？
- アプリケーションは収集したデータが古くなる前に処理して利用することができますか？
- アプリケーションはユーザーに最新の情報を提示することができますか？
- アプリケーションはエラーが発生するまでの最大予想応答時間内に応答していますか？


## スケーラビリティに関するリスク

スケーラビリティに関するリスクはアプリケーションがサポートできるユーザー数だけでなく、アプリケーションが保存・処理できるデータ容量が限界に近づいたことを識別する能力にも関係してきます。
パフォーマンステストで対処できるスケーラビリティに関するリスクには次のようなものがあります。

- アプリケーションは全ユーザーに対して一貫して許容時間内に応答できますか？
- アプリケーションは使用期間中に収集されるすべてのデータを保存できますか？
- アプリケーションのデータ容量が限界に近づいていることを示す警告はありますか？
- 高負荷時にもアプリケーションのセキュリティは維持されますか？
- 高負荷時にもアプリケーションの機能性は維持されますか？
- アプリケーションは予期せぬ負荷に耐えられますか？

## 安定性に関するリスク

安定性は、信頼性、稼働率、回復性などを包括する用語です。
パフォーマンステストで対処できる安定性に関するリスクには次のようなものがあります。


- データの欠損や速度の低下、サーバーの再起動が必要になることなく長時間アプリケーションを実行できますか？
- アプリケーションが不意に停止した場合、部分的に完了したトランザクションはどうなりますか？
- 予定の有無に関わらず、アプリケーションが停止状態から回復した際にユーザは期待通り操作をすることができますか？
- 予定外の停止からアプリケーションが回復した際に、適切に再開されますか？特に、キャンセルされたトランザクションを再開しようとしませんか？
- エラーの組み合わせや機能エラーの繰り返しがシステム・クラッシュの原因になることはありますか？
- システム全体の副作用を引き起こすトランザクションはありますか？
- 負荷分散された環境の片系が停止してもユーザーにサービスを提供できますか？
- システムを停止させることなくパッチやアップデートを行うことができますか？

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

パフォーマンステストは、様々な形態をとり、様々なリスクに対処し、組織に幅広い価値を提供することができる、広範かつ複雑な活動です。

リスクを減らし、コストを最小限に抑え、特定のパフォーマンス・テスト・プロジェクトの過程でいつ適切なテストを適用するかを知るためには、さまざまなパフォーマンス・テスト・タイプを理解することが重要です。パフォーマンス・テストの過程で異なるテスト・タイプを適用するには、以下のキーポイントを評価する必要があります。

パフォーマンステストの目的。
パフォーマンステストの背景：例えば、関係するリソース、コスト、テスト作業に対する潜在的なリターンなど。

## パフォーマンステスト

パフォーマンステストとは、アプリケーションのスピード、スケーラビリティ、安定性などの特性を明らかにするために行われるテストです。


### 特徴

- 速度、スケーラビリティ、安定性を明らかにして、ビジネス上の意思決定の材料とします
- ユーザーがアプリケーションの性能特性に満足するかどうかを判断することに重点を置きます
- パフォーマンスに関する期待値と現実の間のミスマッチを明らかにします
- チューニング、ハードウェア構成の計画、および最適化のサポートします

### 課題

- 高負荷時にのみ現れる問題を検出できない場合があります
- テストの設計次第では限定的な環境での性能特性しか得られない可能性があります
- 本番用ハードウェアでテストを行わない限り、結果には常に不確実性が伴います

## 負荷テスト

負荷テストは、アプリケーションが要求された性能を満たすことができるかどうかを検証するために行われます。この性能は多くの場合、SLA（Service Level Agreement）で規定おり、レスポンスタイム、スループット値、リソース使用率を測定してアプリケーションの限界点を特定することができます。
また、負荷テストの一種である耐久テストは、想定される負荷を長期間に渡って受けた場合の性能特性を明らかにすることに重点を置いたテストです。
耐久テストはMTBF（Mean Time Between Failure）やMTTF（Mean Time To Failure）などの指標を算出するために用いられることがあります。

### 特徴

- 想定されるピーク時の負荷を処理するために必要なスループット値を明らかにします
- ハードウェア構成の妥当性を判断します
- ロードバランサの妥当性を判断します
- 並行性の問題を検出します
- 高負荷時にのみ現れる問題を検出します
- スケーラビリティおよびキャパシティプランニングのためのデータ収集をします
- アプリケーションが何人のユーザを処理できるかを判断するのに役立ちます
- ハードウェアがどれだけの負荷を処理できるかを判断するのに役立ちます

### 課題

・応答速度を主眼に置いたものではありません
・結果は関連する他の負荷試験との比較にのみ使用可能です

## ストレステスト

ストレステストは、同期による問題、レースコンディション、メモリリークなど高負荷時にのみ発生するアプリケーションのバグを発見することを目的としたテストです。ストレステストではアプリケーションの弱点を特定し、極端な負荷条件下でアプリケーションがどのように動作するかを明らかにします。
スパイクテストはストレステストの一種で、想定される本番動作を超える負荷を短期間に繰り返し与えたときのアプリケーションの性能特性を明らかにすることを目的としたテストです。

### 特徴

- システムに負荷をかけることでデータが破損する可能性があるかどうかを判断します
- アプリケーションが目標負荷をどの程度超えれば障害やエラーが発生するかの目安となります
- アプリケーションを監視するためのトリガーを設定し、障害の発生を警告することができます
- ストレス状態によるセキュリティの脆弱性を回避することができます
- 一般的なハードウェアやサポートアプリケーションの障害による副作用を把握できます
- どのような障害を想定することが最も価値があるかを判断するのに役立ちます

### 課題

- ストレステストは非現実的な設計であるため、一部のステークホルダーはテスト結果を否定する可能性があります。
- どの程度のストレスを与えれば良いのか知ることは難しいです
- テスト環境が本番と分離されていない場合、アプリケーションやネットワークの障害が発生する可能性があります

## キャパシティテスト

キャパシティテストは、ユーザー数の増加やデータ量の増加など、将来の成長を計画するためのキャパシティ・プランニングと連動して行われます。例えば、将来の負荷に対応するためには、CPU、メモリ、ディスク容量、ネットワーク帯域幅などのリソースをどれだけ追加する必要があるかを知る必要があります。
キャパシティテストでは、スケールアップすべきかスケールアウトすべきか、スケーリング戦略を明確にすることができます。

### 特徴

- ビジネス要件を満たすためにワークロードをどのように処理できるかを明らかにします
- キャパシティプランナーがモデルや予測を検証、強化するための実データを提供します
- キャパシティプランナーがモデルや予測を比較するための様々なテストを行うことができます
- キャパシティプランニングを支援するために、既存システムの現在の使用量とキャパシティを明らかにします
- キャパシティプランニングに必要な既存システムの使用状況やキャパシティの傾向を提供します

### 課題

- キャパシティモデルの検証テストは作成が複雑です
- キャパシティプランニング・モデルのすべての側面を、最も価値のある時期にテストで検証することはできません

# まとめ

本記事ではパフォーマンステスト実施の際の最初の議論の助けとなることを目指して、

- パフォーマンステストによってどのような情報を得たいのか？
- そのためにはどのような種類のテストを実施すればよいのか？

の判断を助けるための最低限の用語を取りまとめました。

正直に言って、「[Performance Testing Guidance for Web Applications](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/bb924375(v=pandp.10))」を読んでいただくのが一番良いと思います。
一方で、このドキュメントは網羅的ですが必要な情報は方々に散らばっており、必要な時に簡単に参照するには少し向いていないとも感じています。

まずは導入として、この記事が役に立つことがあれば幸いです。