-
Notifications
You must be signed in to change notification settings - Fork 0
TestStrategy
← Home
このドキュメントは、FloatSoda のテストを「範囲 × 目的 × オラクル」の3軸で整理し、現在の配置と既知の穴をまとめたものです。テストの命名と「何を検証するか」の観点は CONTRIBUTING.md が正典で、このページはそれを置き換えません。テストをどこに置くかを決めるときの地図として使います。
テストの種類は1本の軸には並びません。次の3軸を分けて考えます。
| 軸 | 値 | 意味 |
|---|---|---|
| 範囲 | 単体 / 結合 / 描画 / 実機 | どこまで結合して動かすか |
| 目的 | 機能 / 回帰 / 非機能 / 受け入れ | 何を確かめるか |
| オラクル | 例示 / 不変条件 / ゴールデン / 差分 | 期待値をどう言うか |
範囲の4値は FloatSoda の構造に対応します。
| 範囲 | 対象 | 実行手段 |
|---|---|---|
| 単体 | ジオメトリ型、RenderObject 1個、Widget 1個 | dotnet test |
| 結合 |
WidgetBinding から RenderPipeline までを通した経路。差分更新、入力の配送 |
dotnet test |
| 描画 |
FloatSoda.Testing のビットマップ描画で画素を確認する |
dotnet test |
| 実機 | SteamVR が動いている状態でしか観測できないもの。オーバーレイハンドル、コントローラーの座標、レンダースレッドの GL コンテキスト | HMD を着けて手で操作する(.agents/skills/floatsoda-device-test) |
オラクルは「期待値をどう言えるか」で選びます。
| オラクル | 期待値の言い方 | 向いている対象 |
|---|---|---|
| 例示 | 入力に対する正確な出力を書く | サイズ計算、イベントの順序、画素の色 |
| 不変条件 | 常に成り立つ性質を書く | ツリーの親子関係と深さ、dirty list の整合 |
| ゴールデン | 保存しておいた出力と一致する | 描画結果の意図しない変化 |
| 差分 | Flutter の挙動を正解として比較する | Flutter 由来の Widget / RenderObject |
差分オラクルは FloatSoda 固有です。Flutter を正解として使えるのは observable behavior だけで、性能や並行性には使えません。判断原則は APIDesign の「Flutter 由来の observable behavior に差異を作らない」にあります。
3軸を掛けると64マスになりますが、ほとんどは空でよい場所です。次の3つの基準で切ります。
- 最小範囲: 同じ壊れ方をより小さい範囲で観測できるなら、大きい範囲のマスは使いません。実機は「実機でしか見えないもの」だけに使います。
- オラクル成立: その範囲で期待値を言えないマスは使いません。非機能 × 差分は、Flutter の性能が .NET の正解にならないので全て空です。
- シナリオ: 「誰が・いつ・何をしたくなるか」を1文で言えないマスは使いません。負荷、セキュリティ、アクセシビリティ(Semantics は非移植の方針)は、この基準で外れます。
この表は穴を見つけるために使います。「ある」が付いていないマスを機械的に埋める必要はありません。
64マスのうち、基準を通過したのは14マスです。件数は [Fact] と [Theory] の数です。
| 目的 | 範囲 | オラクル | 現状 | 根拠 |
|---|---|---|---|---|
| 機能 | 単体 | 例示 | ある |
tests/FloatSoda.Test 412件、tests/FloatSoda.Rendering.Test 8件 |
| 機能 | 単体 | 不変条件 | 薄い |
[Theory] 47件はあるが、ツリー不変条件を機械的に検査するヘルパーは無い |
| 機能 | 単体 | 差分 | 手順のみ | CONTRIBUTING が Flutter 公式テストの参照を必須にしている。テスト自体は例示として書かれる |
| 機能 | 結合 | 例示 | 薄い |
WidgetBinding を端から端まで動かすのは Core/WidgetBindingTest.cs と Core/PointerInputIntegrationTest.cs の2ファイル |
| 機能 | 描画 | 例示 | ある |
GetPixel による画素の断言が15ファイル、84箇所 |
| 機能 | 実機 | 例示 | 無い | device test の手順はあるが、ハーネスは未着手 |
| 機能 | 実機 | 差分 | 文書のみ |
known-divergences.md に9件。うち8件が Test: — (not set)
|
| 回帰 | 単体 | 例示 | ある | バグ修正ごとの regression test を REVIEW.md が必須にしている |
| 回帰 | 描画 | ゴールデン | 無い | 参照画像はゼロ。GetPixel で足りている間は優先度が低い |
| 非機能 | 結合 | 例示(閾値) | 未着手 |
tests/FloatSoda.Test/FloatSoda.Test.csproj が BenchmarkDotNet を参照しているが、[Benchmark] はゼロ |
| 非機能 | 結合 | 不変条件(並行性) | 薄い | スレッドを扱うのは Engine/IOTaskRunnerTest.cs など数件。レンダースレッドと Layer clone の競合は未検証 |
| 受け入れ | 実機 | 例示 | 手動 |
samples/ は CONTRIBUTING で「結合テストのシナリオを兼ねる」とされるが、CI はビルドのみ。実行には SteamVR が要る |
| 受け入れ | 文書と API | 例示 | 手動 | junior-coder test(.agents/skills/floatsoda-junior-coder-test)。実績あり。LLM を使うので CI には乗せない |
| 受け入れ | 文書 | 例示(スモーク) | ある | website/scripts/verify-dist.mjs |
影響が大きい順です。
- Flutter との差異がテストで固定されていない。 差異は意図した仕様なので、テストで固定しないと次の移植作業で気づかずに元へ戻ります。9件のうち半分は実機を使わず、単体か結合で固定できます。振り分けは §5 を参照してください。
- 結合が2ファイルしかない。 差分更新の dirty 伝播と入力の配送経路は、単体では見えず、実機では遅すぎます。この中間の範囲を厚くします。
- BenchmarkDotNet が宙に浮いている。 依存だけあってベンチマークがありません。「1フレームの予算内にレイアウトが収まるか」は Booth 創作者のペルソナが最も気にする点なので、書くか外すかを決めます。
優先度が低い、または判断待ちの項目です。
- ツリー不変条件のヘルパー: ツリー操作の後に親子関係と深さを検査する共通ヘルパー。安価に足せます。
-
ゴールデン: SkiaSharp の更新で描画が変わる事故を捕まえる用途に限ります。
GetPixelで捕まえられない事故が起きるまで保留します。 -
samples/の位置づけ: 規約上は結合テストのシナリオですが、実行手段は実機だけです。実機シナリオとして扱うか、ヘッドレスで実行する仕組みを作るかは未決定です。 - ペルソナ2・3の受け入れ: Unity 出身者が uGUI の語彙で読めるかを確かめる手段がまだありません。シナリオは書けますが実行手段が無いので、名前だけ残します。
差異の台帳は known-divergences.md です。テストを書く前にラベルを決めます。 ラベルによって、書くべきテストの向きが逆になるためです。
| ラベル | 書くテスト |
|---|---|
| deliberate | 差異を固定するテスト。差異を元に戻すと落ちる |
| port mistake | 修正前に落ち、修正後に通る regression test |
| not ported | テストは書かず、Issue を立てる |
| unlabelled | 先にラベルを決める。この状態でテストを書くと、バグを仕様として固定する恐れがある |
9件それぞれの範囲、テスト名、着手順は、台帳末尾の「Triage 2026-09-09」節に記録しています。
Phase 2 のリリース(Home)後に着手します。順番は次のとおりです。
- 差異の固定テスト。台帳の Triage 節の順(#4 → #5 → #1 → #7)
- 結合テストの拡充。dirty 伝播と入力の配送
- BenchmarkDotNet を書くか外すかの判断
- 台帳の更新。#5 の Flutter 欄の書き直し、#2 と #3 の統合、#6 の分割
着手したら §3 の表と §4 の一覧を更新し、日付を書き換えます。