qe-performance-testing について
qe-performance-testingは、性能テストを計画・実行するチーム向けのスキルです。SLOの設定、現実的な負荷シナリオ、テスト中の監視、ボトルネック分析を扱い、複数の性能テストに対応します。
主な機能
- 01性能SLOの定義
- 02現実的なユーザー負荷シナリオの計画
- 03負荷・ストレステストの選択
- 04テスト中のシステムリソース監視
- 05ボトルネックと結果の分析
活用シーン
- 01リリース前の想定トラフィック検証
- 02ストレステストによる容量上限の特定
- 03イベント前の急増トラフィック検証
- 04耐久テストによるメモリリーク調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ proffesor-for-testing/ agentic-qe --skill qe-performance-testingインストール後、Claude Code で/qe-performance-testingを入力して読み込まれたか確認します。
詳細
パフォーマンステスト
<default_to_action> パフォーマンスをテストする場合、または負荷テストを計画する場合:
- SLO を定義します:p95 応答時間、スループット、エラー率の目標
- 重要なパスを特定します:収益につながるフロー、トラフィックの多いページ、主要な API
- 現実的なシナリオを作成します:ユーザージャーニー、思考時間、さまざまなデータ
- モニタリングしながら実行します:CPU、メモリ、DB クエリ、ネットワーク
- ボトルネックを分析し、本番環境に導入する前に修正します
テストタイプのクイック選択:
- 想定負荷の検証 → 負荷テスト
- 限界点の特定 → ストレステスト
- 突発的なトラフィック急増 → スパイクテスト
- メモリリーク、リソース枯渇 → 耐久/ソークテスト
- 水平/垂直スケーリング → スケーラビリティテスト
成功のための重要な要素:
- パフォーマンスは後回しにせず、機能の一部として扱います
- リリース直前だけでなく、早い段階から頻繁にテストします
- ユーザーに影響するボトルネックに注力します </default_to_action>
クイックリファレンスカード
使用するタイミング
- 主要リリースの前
- インフラストラクチャの変更後
- スケーリングイベント(Black Friday)の前
- SLA/SLO の設定時
テストタイプ
| タイプ | 目的 | タイミング |
|---|---|---|
| 負荷 | 想定されるトラフィック | リリースごと |
| ストレス | 容量を超える負荷 | 四半期ごと |
| スパイク | 突発的な急増 | イベントの前 |
| 耐久 | メモリリーク | コード変更後 |
| スケーラビリティ | スケーリングの検証 | インフラストラクチャの変更時 |
主要なメトリクス
| メトリクス | 目標 | 理由 |
|---|---|---|
| p95 応答時間 | < 200ms | ユーザーエクスペリエンス |
| スループット | 10k req/min | 容量 |
| エラー率 | < 0.1% | 信頼性 |
| CPU | < 70% | 余裕 |
| メモリ | < 80% | 安定性 |
ツール
- k6:モダンで、JS ベース、CI/CD に適しています
- JMeter:エンタープライズ向けで、機能が豊富です
- Artillery:シンプルな YAML 設定
- Gatling:Scala を使用し、レポート機能に優れています
エージェントの連携
qe-performance-tester:負荷テストのオーケストレーションqe-quality-analyzer:結果の分析qe-production-intelligence:本番環境との比較
SLO の定義
悪い例:「システムは高速であるべき」 良い例:「1,000 人の同時ユーザーがいる状況で、p95 応答時間が 200ms 未満」
export const options = {
thresholds: {
http_req_duration: ['p(95)<200'], // 95% < 200ms
http_req_failed: ['rate<0.01'], // < 1% failures
},
};
現実的なシナリオ
**悪い例:**すべてのユーザーがホームページに繰り返しアクセスする **良い例:**実際のユーザー行動をモデル化する
// Realistic distribution
// 40% browse, 30% search, 20% details, 10% checkout
export default function () {
const action = Math.random();
if (action < 0.4) browse();
else if (action < 0.7) search();
else if (action < 0.9) viewProduct();
else checkout();
sleep(randomInt(1, 5)); // Think time
}
よくあるボトルネック
データベース
**症状:**負荷時のクエリが遅い、コネクションプールの枯渇 **対策:**インデックスの追加、N+1 クエリの最適化、プールサイズの拡大、リードレプリカの使用
N+1 クエリ
// BAD: 100 orders = 101 queries
const orders = await Order.findAll();
for (const order of orders) {
const customer = await Customer.findById(order.customerId);
}
// GOOD: 1 query
const orders = await Order.findAll({ include: [Customer] });
同期処理
**問題:**リクエスト処理中のブロッキング操作(チェックアウト中のメール送信など) **対策:**メッセージキューを使用し、非同期に処理して、すぐに応答を返します
メモリリーク
**検出:**耐久テスト、メモリプロファイリング **よくある原因:**イベントリスナーのクリーンアップ漏れ、追い出し処理のないキャッシュ
外部依存関係
**対策:**短いタイムアウト、サーキットブレーカー、キャッシュ、グレースフルデグラデーション
k6 CI/CD の例
// performance-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '1m', target: 50 }, // Ramp up
{ duration: '3m', target: 50 }, // Steady
{ duration: '1m', target: 0 }, // Ramp down
],
thresholds: {
http_req_duration: ['p(95)<200'],
http_req_failed: ['rate<0.01'],
},
};
export default function () {
const res = http.get('https://api.example.com/products');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 200ms': (r) => r.timings.duration < 200,
});
sleep(1);
}
# GitHub Actions
- name: Run k6 test
uses: grafana/[email protected]
with:
filename: performance-test.js
結果の分析
良好な結果
Load: 1,000 users | p95: 180ms | Throughput: 5,000 req/s
Error rate: 0.05% | CPU: 65% | Memory: 70%
問題
Load: 1,000 users | p95: 3,500ms ❌ | Throughput: 500 req/s ❌
Error rate: 5% ❌ | CPU: 95% ❌ | Memory: 90% ❌
根本原因の分析
- メトリクスを関連付けます:応答時間が急増したとき、何が変化していますか?
- ログを確認します:エラー、警告、遅いクエリ
- コードをプロファイリングします:どこで時間がかかっていますか?
- リソースをモニタリングします:CPU、メモリ、ディスク
- リクエストをトレースします:エンドツーエンドのフロー
アンチパターン
| ❌ アンチパターン | ✅ より良い方法 |
|---|---|
| テストが遅すぎる | 早い段階から頻繁にテストする |
| 非現実的なシナリオ | 実際のユーザー行動をモデル化する |
| 0 人から 1000 人へ瞬時に増やす | 段階的に負荷を増やす |
| テスト中にモニタリングしない | すべてをモニタリングする |
| ベースラインがない | 傾向を把握し、追跡する |
| 一度きりのテスト | 継続的なパフォーマンステスト |
エージェント支援によるパフォーマンステスト
// Comprehensive load test
await Task("Load Test", {
target: 'https://api.example.com',
scenarios: {
checkout: { vus: 100, duration: '5m' },
search: { vus: 200, duration: '5m' },
browse: { vus: 500, duration: '5m' }
},
thresholds: {
'http_req_duration': ['p(95)<200'],
'http_req_failed': ['rate<0.01']
}
}, "qe-performance-tester");
// Bottleneck analysis
await Task("Analyze Bottlenecks", {
testResults: perfTest,
metrics: ['cpu', 'memory', 'db_queries', 'network']
}, "qe-performance-tester");
// CI integration
await Task("CI Performance Gate", {
mode: 'smoke',
duration: '1m',
vus: 10,
failOn: { 'p95_response_time': 300, 'error_rate': 0.01 }
}, "qe-performance-tester");
エージェント連携のヒント
メモリの名前空間
aqe/performance/
├── results/* - Test execution results
├── baselines/* - Performance baselines
├── bottlenecks/* - Identified bottlenecks
└── trends/* - Historical trends
フリート連携
const perfFleet = await FleetManager.coordinate({
strategy: 'performance-testing',
agents: [
'qe-performance-tester',
'qe-quality-analyzer',
'qe-production-intelligence',
'qe-deployment-readiness'
],
topology: 'sequential'
});
本番前チェックリスト
- 負荷テストに合格(想定トラフィック)
- ストレステストに合格(想定の2~3倍)
- スパイクテストに合格(急激な負荷の増加)
- 耐久テストに合格(24時間以上)
- データベースのインデックスを設定済み
- キャッシュを設定済み
- 監視とアラートを設定済み
- パフォーマンスのベースラインを確立済み
関連スキル
- エージェント型品質エンジニアリング - エージェントの連携
- APIテストパターン - APIパフォーマンス
- カオスエンジニアリングによるレジリエンス - レジリエンステスト
覚えておくこと
パフォーマンスは機能の一つです: 機能と同じようにテストしましょう
継続的にテストしましょう: リリース前だけに限りません
本番環境を監視しましょう: 合成監視と実ユーザー監視を併用します
重要な問題を修正しましょう: ユーザーに影響するボトルネックに注力します
時間の経過に伴う傾向を把握しましょう: 劣化を早期に検知します
エージェントを活用する場合: エージェントは負荷テストを自動化し、ボトルネックを分析して、本番環境と比較します。大規模環境でもパフォーマンスを維持するために、エージェントを活用しましょう。