Skip to main content

テスタブル設計(I/O境界の分離)30章アウトライン🌟🧪

第1章:はじめに(この講座のゴール)🎯😊

  • ねらい:テスタブル設計=「怖くない変更」を作る感覚をつかむ✨
  • 学ぶ:I/O境界の分離って何?どこが嬉しい?🧠
  • ハンズオン:テストしにくいコードの例を“眺めて”つらさを体験😵‍💫

第2章:I/Oと副作用ってなに?⚡🚪

  • ねらい:「I/O=外の世界」を言語化できるようにする
  • 学ぶ:HTTP/DB/ファイル/時刻/乱数/環境変数/ログ…ぜんぶI/O寄り🌀
  • ハンズオン:自分が書きがちな処理を「I/O」「ロジック」に分ける📝

第3章:テストしやすいってどういう状態?🧪✨

  • ねらい:“テスト可能性”の条件を持つ
  • 学ぶ:入力→出力が安定、外部依存が差し替え可能、実行が速い⚡
  • ハンズオン:同じ処理を「テストしやすい版」に言い換えてみる🔁

第4章:「中心(ロジック)」と「外側(I/O)」モデル🏠➡️🌍

  • ねらい:頭の中に設計の地図を作る
  • 学ぶ:中心=純粋ロジック/外側=アダプタ、境界=インターフェース📌
  • ハンズオン:図を描く練習(中心・外側・境界線)🖊️

第5章:Windows + VS Codeで“動く最小環境”を作る🪟💻

  • ねらい:迷子にならない土台を作る
  • 学ぶ:プロジェクト構成(TypeScript、実行、テストの置き場所)📁
  • ハンズオン:空プロジェクトを作って「テストが走る」まで✅

第6章:テストランナー入門(まず1本通す)🧪🎉

  • ねらい:成功体験で安心する
  • 学ぶ:テストの実行・失敗の読み方・基本アサーション👀
  • ハンズオン:超小さい純粋関数を作ってテストを書く✍️

第7章:テストの型(AAA)で迷わなくする📐🧪

  • ねらい:毎回の書き方を固定して楽にする
  • 学ぶ:Arrange/Act/Assert、命名、境界値テストの考え方🧠
  • ハンズオン:同じ関数にテストケースを増やして慣れる📈

第8章:純粋関数の作り方(I/Oゼロの中心)🍰✨

  • ねらい:中心を“きれい”にする技術
  • 学ぶ:副作用を持たない、同じ入力なら同じ出力、例外の扱い方の基本
  • ハンズオン:文字列整形・料金計算など“日常ネタ”で練習🍩💰

第9章:TypeScriptの型でテストを減らす🛡️📘

  • ねらい:型を味方にする
  • 学ぶ:型で表現できる不正を締め出す(ユニオン型、型ガードの感覚)✅
  • ハンズオン:入力型を強くしてバグの入口を塞ぐ🚧

第10章:「テストしにくい臭い」カタログ👃💨

  • ねらい:リファクタ対象を見つけられるようにする
  • 学ぶ:関数の奥で new、直 Date、直 fetch、直 process.env、巨大関数…😱
  • ハンズオン:臭いポイントに赤ペン入れて「何を境界にする?」を言語化🖍️

第11章:境界線の引き方(判断軸だけ覚える)✂️🧠

  • ねらい:境界の“引き方”を持つ
  • 学ぶ:変更理由の違いで分ける、外部都合を中心に入れない🚪
  • ハンズオン:同じ題材に3つ線引きして比較🔁

第12章:分離の基本手順(押し出す→薄くする)🧹➡️🧩

  • ねらい:安全に分離する手順を身につける
  • 学ぶ:①中心抽出→②I/Oを外へ→③境界をinterface化→④テスト追加
  • ハンズオン:小さな“最悪コード”を段階的に改善する🛠️

第13章:依存を外から渡す(引数注入)🎁➡️

  • ねらい:差し替え可能にする最短ルート
  • 学ぶ:関数引数で依存を渡す、中心は依存を作らない🙅‍♀️
  • ハンズオン:Clock/Loggerを引数で受け取る版に変える⏰📝

第14章:コンストラクタ注入&合成の置き場(組み立て場所)🏗️🧱

  • ねらい:アプリの“組み立て係”を作る
  • 学ぶ:中心は薄い依存、外側で実体を組み立てる(Composition Root)📌
  • ハンズオン:main側で依存を組んで中心に渡す✅

第15章:interfaceは“最小の約束”にする📜✨

  • ねらい:巨大interface地獄を回避
  • 学ぶ:必要な操作だけ、I/Oの詳細を漏らさない🚫
  • ハンズオン:HTTP/DBのinterfaceを“最小化”する練習✂️

第16章:テストダブル入門(スタブ/モック/スパイ)🧸👀

  • ねらい:差し替えテストの道具を覚える
  • 学ぶ:スタブ=返す、スパイ=記録、モック=期待を確認
  • ハンズオン:通知送信を“送ったことにする”テスト📩😆

第17章:時刻(Clock)を分離する⏰🧊

  • ねらい:時間バグを消す
  • 学ぶ:期限判定・日跨ぎ・タイムゾーン事故の入口
  • ハンズオン:Clockを注入して“時間を止める”テストを書く🧪

第18章:乱数(Random)を分離する🎲🎯

  • ねらい:再現性のあるテストにする
  • 学ぶ:乱数直書きが不安定の原因
  • ハンズオン:固定乱数でくじ引きロジックを検証🎁

第19章:ファイルI/Oを外に押し出す📁🚪

  • ねらい:読み書きと計算を分ける
  • 学ぶ:中心=解析/集計、外側=読み込み/保存
  • ハンズオン:CSVっぽい入力→集計ロジックを中心へ📊

第20章:HTTPアクセスを外に押し出す🌐🧩

  • ねらい:API変更に強くする
  • 学ぶ:Client interface + Adapter、レスポンス変換は境界で
  • ハンズオン:API結果を“ドメイン型”に変換して中心へ✨

第21章:DB/永続化を外に押し出す🗄️🧩

  • ねらい:永続化都合でロジックを汚さない
  • 学ぶ:Repositoryの最小操作、中心はDBを知らない🙈
  • ハンズオン:保存/取得を差し替え可能にして中心テストを高速化⚡

第22章:設定・環境変数を外に押し出す⚙️📦

  • ねらい:環境差で壊れない設計
  • 学ぶ:設定はConfigとして注入、中心は process.env を触らない🙅‍♀️
  • ハンズオン:テストでConfigを差し替えて分岐を検証✅

第23章:境界でデータ変換(DTO ↔ Domain)🔁✨

  • ねらい:外の形を中心に持ち込まない
  • 学ぶ:命名・単位・欠損値・nullの吸収、変換の置き場
  • ハンズオン:外部DTOを“きれいな型”に直して中心へ💎

第24章:入力検証と不変条件(入口で守る)🚧🛡️

  • ねらい:中心に“壊れたデータ”を入れない
  • 学ぶ:入口でチェック、中心は前提を信頼する設計
  • ハンズオン:不正入力が来たときの挙動をテストで固定📌

第25章:エラー設計(ドメイン vs インフラ)😇🚨

  • ねらい:例外が暴れない世界へ
  • 学ぶ:ドメインエラー(仕様の失敗)/インフラエラー(外部都合)
  • ハンズオン:失敗の種類を分類して、中心が扱う形を決める🧠

第26章:境界でエラー変換(例外→結果、結果→表示)🔁🧯

  • ねらい:「境界で変換する」一点突破
  • 学ぶ:外側の例外を中心の扱いやすい形へ、逆に表示用へ
  • ハンズオン:HTTP失敗→中心の結果→UI/CLI表示、を一本につなぐ🔗

第27章:テストの粒度(ユニット/結合)と基本方針🍱🧪

  • ねらい:どこを何で守るか迷わない
  • 学ぶ:中心=ユニットで速く、外側=最小限の結合で確認🔌
  • ハンズオン:同じ機能を「中心テスト」「結合テスト」両方で作る🙂

第28章:観測(ログ)もI/O!テスタブルにする📈📝

  • ねらい:あとで調査できる&テストも壊れない
  • 学ぶ:Loggerを注入、重要イベントだけ出す、テストではスパイで検証👀
  • ハンズオン:「失敗理由が追えるログ」を設計してテストする🕵️‍♀️

第29章:AI拡張と上手に進める(丸投げしないコツ)🤖🎀

  • ねらい:AIで速くなるけど設計は自分が握る

  • 学ぶ:AIに頼るところ(テストケース列挙、モック下書き、命名案)📝 逆に頼らないところ(境界判断・要件解釈の丸投げ)🙅‍♀️

  • ハンズオン:

    • 良いプロンプト例(ケース洗い出し)
    • ダメ回答の見抜き方(責務が混ざる、境界が曖昧)👁️

第30章:ミニプロジェクト(集大成)🎓🌈

  • ねらい:現実っぽい形で「中心と外側」を完成させる

  • 題材例:注文(合計/割引/在庫チェック)🛒🍕(難しすぎないやつ)

  • 進め方(章内で3ステップに分けてやる)✨

    1. 設計:境界図・依存の向き・interface決定🗺️
    2. 中心実装:純粋ロジック + ユニットテスト🧪
    3. 外側接続:HTTP/DB/設定/ログのアダプタ + 最小の結合テスト🔌
  • 成果物:中心が“ほぼユニットテストだけで守れる”構造🎯