テスト設計
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
# テスト Fixture 仕様
|
||||
|
||||
## 概要
|
||||
|
||||
テスト用 fixture は、実 API のストリーミング応答を JSONL 形式で録画したファイル。
|
||||
`MockLlmClient::from_fixture()` でロードし、API キー不要・決定的なテスト実行を実現する。
|
||||
|
||||
## ファイル形式
|
||||
|
||||
```
|
||||
{メタデータ行: JSON}
|
||||
{イベント行: JSON}
|
||||
{イベント行: JSON}
|
||||
...
|
||||
```
|
||||
|
||||
- **1行目**: メタデータ (`timestamp`, `model`, `description`)
|
||||
- **2行目以降**: 録画イベント (`elapsed_ms`, `event_type`, `data`)
|
||||
- `data` フィールドに `Event` の JSON 文字列が入る
|
||||
|
||||
## ファイル配置
|
||||
|
||||
```
|
||||
crates/llm-worker/tests/fixtures/
|
||||
anthropic/
|
||||
simple_text.jsonl
|
||||
tool_call.jsonl
|
||||
long_text.jsonl
|
||||
openai/
|
||||
simple_text.jsonl
|
||||
tool_call.jsonl
|
||||
long_text.jsonl
|
||||
gemini/
|
||||
simple_text.jsonl
|
||||
tool_call.jsonl
|
||||
long_text.jsonl
|
||||
ollama/
|
||||
simple_text.jsonl
|
||||
tool_call.jsonl
|
||||
long_text.jsonl
|
||||
```
|
||||
|
||||
## シナリオ定義
|
||||
|
||||
### simple_text
|
||||
|
||||
単純なテキスト応答。
|
||||
|
||||
| 項目 | 値 |
|
||||
|---|---|
|
||||
| ファイル名 | `simple_text.jsonl` |
|
||||
| system prompt | `"You are a helpful assistant. Be very concise."` |
|
||||
| user message | `"Say hello in one word."` |
|
||||
| max_tokens | 50 |
|
||||
| ツール | なし |
|
||||
|
||||
**期待パターン**:
|
||||
- `BlockStart(Text)` が1つ以上
|
||||
- `BlockDelta(Text)` が1つ以上
|
||||
- `BlockStop(Text)` が1つ以上
|
||||
- 応答が短い(1単語程度)
|
||||
|
||||
**用途**: 基本的なストリーミング動作、Timeline テキスト収集、Worker の単純な run 完了
|
||||
|
||||
### tool_call
|
||||
|
||||
ツール呼び出しを含む応答。
|
||||
|
||||
| 項目 | 値 |
|
||||
|---|---|
|
||||
| ファイル名 | `tool_call.jsonl` |
|
||||
| system prompt | `"You are a helpful assistant. Use tools when appropriate."` |
|
||||
| user message | `"What's the weather in Tokyo? Use the get_weather tool."` |
|
||||
| max_tokens | 200 |
|
||||
| ツール | `get_weather(city: string)` |
|
||||
|
||||
**期待パターン**:
|
||||
- `BlockStart(ToolUse)` を含む
|
||||
- ToolUse ブロック内に `tool_call_id`, `name: "get_weather"` がある
|
||||
- tool input JSON に `"city"` キーを含む
|
||||
|
||||
**用途**: ToolCallCollector、Worker のツール実行フロー、Session の ToolResults ログ記録
|
||||
|
||||
### long_text
|
||||
|
||||
長文テキスト応答。
|
||||
|
||||
| 項目 | 値 |
|
||||
|---|---|
|
||||
| ファイル名 | `long_text.jsonl` |
|
||||
| system prompt | `"You are a creative writer."` |
|
||||
| user message | `"Write a short story about a robot discovering a garden. It should be at least 300 words."` |
|
||||
| max_tokens | 1000 |
|
||||
| ツール | なし |
|
||||
|
||||
**期待パターン**:
|
||||
- `BlockDelta(Text)` が複数(ストリーミングチャンク)
|
||||
- 最終テキストが 300 語以上
|
||||
|
||||
**用途**: ストリーミングの分割配信検証、Subscriber のデルタ受信テスト
|
||||
|
||||
## 共通検証項目
|
||||
|
||||
全 fixture に対して以下を検証する(`assert_*` ヘルパー関数群):
|
||||
|
||||
- `assert_events_deserialize` — 全イベントが `Event` にデシリアライズできる
|
||||
- `assert_event_sequence` — BlockStart → BlockDelta → BlockStop の基本シーケンス
|
||||
- `assert_usage_tokens` — `Usage` イベントが含まれる
|
||||
- `assert_timeline_integration` — Timeline に流してテキスト収集できる
|
||||
|
||||
## 録画手順
|
||||
|
||||
### 前提
|
||||
|
||||
- API キーが環境変数に設定されていること
|
||||
- `crates/llm-worker` ディレクトリで実行
|
||||
|
||||
### コマンド
|
||||
|
||||
```bash
|
||||
# 単一シナリオ録画
|
||||
ANTHROPIC_API_KEY=... cargo run --example record_test_fixtures -- -s simple_text
|
||||
|
||||
# 全シナリオ録画
|
||||
ANTHROPIC_API_KEY=... cargo run --example record_test_fixtures -- --all
|
||||
|
||||
# プロバイダー指定
|
||||
OPENAI_API_KEY=... cargo run --example record_test_fixtures -- --all -c openai
|
||||
GEMINI_API_KEY=... cargo run --example record_test_fixtures -- --all -c gemini
|
||||
|
||||
# モデル指定
|
||||
ANTHROPIC_API_KEY=... cargo run --example record_test_fixtures -- --all -m claude-sonnet-4-20250514
|
||||
```
|
||||
|
||||
### シナリオ定義の場所
|
||||
|
||||
`crates/llm-worker/examples/record_test_fixtures/scenarios.rs`
|
||||
|
||||
新しいシナリオを追加する場合はこのファイルに `TestScenario` を追加し、
|
||||
`scenarios()` 関数の返り値に含める。
|
||||
|
||||
## 録画後の確認チェックリスト
|
||||
|
||||
録画後、テストに組み込む前に以下を手動確認する:
|
||||
|
||||
- [ ] JSONL の各行が valid JSON か(`jq . < fixture.jsonl` で確認)
|
||||
- [ ] 1行目にメタデータ(`timestamp`, `model`, `description`)が入っているか
|
||||
- [ ] simple_text: `BlockStart` → `BlockDelta` → `BlockStop` シーケンスがあるか
|
||||
- [ ] tool_call: `BlockStart` に `"block_type":"ToolUse"` を含むか
|
||||
- [ ] long_text: `BlockDelta` が複数行あるか(ストリーミング分割の確認)
|
||||
- [ ] 各 fixture に `Usage` イベントが含まれるか
|
||||
- [ ] エラーイベントが混入していないか
|
||||
|
||||
## 注意事項
|
||||
|
||||
- fixture は API の応答に依存するため、モデルバージョンアップで再録画が必要になることがある
|
||||
- 録画の自動化(CI での定期録画等)は行わない。手動実行 + 目視確認のフロー
|
||||
- fixture が存在しない場合、対応するテストは skip される(`if !fixture_path.exists() { return; }` パターン)
|
||||
Reference in New Issue
Block a user