テスタブル設計(I/O境界の分離)アウトライン:25章 📚✨(Windows + C#2026 + AI導入済み前提)
第1章:まずはゴールのイメージを作ろう 🧭😊✨
- 「テストしやすいコード」って何が嬉しいの?✨
- “怖くない変更”ができる世界へ🛡️
- 今日からの合言葉:I/Oを外に出す! 🚪
第2章:テストがつらいコードあるある 😵💫💥
- DB直アクセス、DateTime.Now直読み、HttpClient直叩き…
- テストが「環境依存」になると何が起きる?🌪️
- “再現できないバグ”の地獄🔥
第3章:I/Oってなに?どこからがI/O?🔌📦✨
- I/Oの代表:ファイル🗂️ / DB🗄️ / ネット🌐 / 時刻🕰️ / 乱数🎲 / UI🖥️
- 「I/O=外の世界」だと思えばOK🙆♀️
- 純粋ロジックとの違い🌱
第4章 純粋ロジックってなに 🌿✨
- 入力が同じなら出力も同じ🎯
- 状態を持たない・副作用なし🧼
- テストが爆速になる理由⚡
第5章:境界(Boundary)の考え方 🚧😊
- “内側(ルール)”と“外側(I/O)”を分ける📦↔️🌍
- 境界があると、交換できる🔁
- 境界は インターフェースで作るのが定番🧩
第6章:最小サンプルで掴む「分離」🧪✨
- 例:税計算ロジック(ピュア)+レシート出力(I/O)🧾
- “混ぜるとテストできない”を体験💦
- “分けると一瞬でテストできる”を体験🎉
第7章:テストの種類をゆるく知る 🔍😊
- 単体テスト(ユニット)🧩
- 結合テスト🤝
- E2E(必要な時だけでOK)🚀
- まず狙うのは「単体が安定」💖
第8章:C#のテスト基盤を用意しよう(Windows/VS)🛠️✨
- Visual Studioでテストプロジェクト作成📦
- よく使うテストフレームワークの立ち位置(例:xUnit / NUnit / MSTest)🧪
- テスト実行の基本(Test Explorer)👀
第9章:AI(Copilot/Codex)をテスト学習に使うコツ 🤖💡🧪
- 「テストケース案を出して」って頼む📝
- Arrange/Act/Assertの骨組みを作らせる🧱
- “鵜呑み禁止ポイント”も知る⚠️(境界/責務が崩れてない?)
第10章:依存ってなに?newの怖さ(超入門)😳🔗
new が悪いわけじゃない🙆♀️
- でも “重要ロジックの中で” new すると差し替え不能🧊
- 「差し替えできる場所」を作るのが設計💎
第11章:DIの最小(コンストラクタ注入)✉️✨
- まずはこれだけでOK:コンストラクタで受け取る🧰
- 引数で渡せる=テストで偽物にできる🎭
- “依存を見える化”できる👓
第12章 インターフェースでI/Oを包む 🧩📮✨
- 例:
IClock / IFileSystem / IEmailSender
- “外の世界”は必ずここを通す🚪
- 命名のコツ(動詞より役割)📝
第13章:Fake / Stub / Mock をゆるく使い分け 🎭🧪
- Fake:それっぽく動く簡易実装🧸
- Stub:返す値固定📌
- Mock:呼ばれたか検証👀
- 最初は FakeかStub中心がおすすめ😊
第14章:時間(DateTime.Now)を境界にする 🕰️🚧✨
- “今”はテストの敵😈
IClock.Now で吸い出す🧃
- 期限チェック・期間計算が安定する🎯
第15章:乱数(Random)を境界にする 🎲🚧✨
- 乱数があるとテストが揺れる🌪️
IRandom で差し替え🔁
- ゲーム/抽選/シャッフル系は必須級✨
第16章:ファイルI/Oを境界にする 🗂️🚧✨(= 単体テストで「ファイル触らない」を実現!)
File.ReadAllText直呼びの問題💥
IFileStore / IFileSystem で包む📦
- “メモリ上のFake”で単体テストできる🎉
第17章:DBを境界にする(Repository入門)🗄️🚧✨
- DB直アクセスはテストが重い🐘
- Repositoryの目的=抽象で守る🛡️
- テストではインメモリ実装へ🔁
第18章:HTTP/外部APIを境界にする 🌐🚧
- 外部は落ちる・遅い・変わる😵
IExternalApiClientで包む📮
- 単体はFake、結合で本物を少しだけ🤏
第19章:UI(入力/表示)もI/Oだよ 🖥️🚧✨
- UIにロジックを置くと地獄👻
- UIは薄く、判断は中へ📦
- “画面は入出力装置”と割り切る✨
第20章:例外と戻り値の境界(エラー設計の入口)🚨🧩
- 例外をどこまで投げる?どこで握る?🤔
- I/Oの失敗は外側、ルール違反は内側📦↔️🌍
- Result型っぽい考え方もチラ見せ👀
第21章:テストしやすい形に“分解”する練習 🧱💖
- 大きい関数を小さく切る✂️
- “判断(if)”と“I/O”を分ける🎯
- ユースケース単位で組み立てる🧩
第22章:どこに“組み立て”を書く?(Composition Root入門)🏗️✨
- newする場所は1箇所に寄せる📍
- 「本物の実装」を接続する場所🔌
- テストでは別の組み立てにする🧪
第23章:小さなアプリで総復習(ConsoleでOK)🎮✨
- 入力→処理→出力を分離して作る📦
- Fake差し替えで単体テスト🧪
- 最後に本物I/Oを接続して動かす🚀
第24章:AIにレビューさせる(設計チェックリスト)🤖✅
- “I/Oが内側に混ざってない?”🔍
- “依存が見える形?”👓
- “テストが速い?”⚡
- Copilot/Codexに「境界の提案」をさせるコツ💡
第25章:卒業🎓✨ テスタブル設計の最小まとめ&次の一歩 🚀💖
- 今日の最重要:I/Oは外へ、ルールは中へ📦➡️🌍
- よくある落とし穴(抽象化しすぎ・YAGNI)⚠️
- 次に学ぶと強い:DI・DIP・クリーン/ヘキサゴナルへの橋渡し🌉✨