Skip to main content

テスタブル設計(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・クリーン/ヘキサゴナルへの橋渡し🌉✨