Slide 1

Slide 1 text

品質は設計でつくり込む 株式会社グロービス 大沼和也 1

Slide 2

Slide 2 text

こんな悩みありませんか? テストケースが多すぎる プロジェクト後期にテストの量が多いことに気づく プロジェクト後期に不具合に気づいてプロジェクトが遅延 2

Slide 3

Slide 3 text

本日のテーマ 品質は設計で作り込むことで、 プロダクト運用コストを大幅に減らす 3

Slide 4

Slide 4 text

0. 品質を設計で作り込むとは 4

Slide 5

Slide 5 text

シフトレフトが大事ってこと? 5

Slide 6

Slide 6 text

不具合発見の早さと修正コスト In general, the earlier you get rid of a bug, the less it costs you. 翻訳: 不具合発見が早ければ早いほど、修正コ ストは安くなる 6

Slide 7

Slide 7 text

早期発見しないと、文脈の喪失によ りコストが増大する Bringing testing forward in the software development life cycle decreases the cost and complexity of fixing bugs because they are found closer to when they were created, which establishes more of a context for what could have caused things to go wrong. 翻訳: 早い段階でテストを行うことは、バグ修 正のコストと複雑さを低減させます。なぜな ら、バグが作られた時点に近い場所で発見され るため、何が問題を引き起こしたかの文脈がよ り明確になるからです。 7

Slide 8

Slide 8 text

コストの増大は指数関数的なのでシ フトレフトが重要 Shifting problem detection to the "left," earlier on this timeline, makes it cheaper to fix than waiting longer, … 翻訳: 問題の発見をタイムラインの「左」 、つま りより早い段階にシフトすることで、後で待つ よりも修正コストが安くなります。 8

Slide 9

Slide 9 text

シフトレフトの考え方に立ち戻る 熟練したテスターは、開発サイクルの最初から 関与している Skilled testers are involved from the start of the development cycle and are given time and resources to do an adequate job of all necessary forms of testing. 本書の序文で、成功するチームの共通点として 「熟練したテスターが開発サイクルの最初から 関与している」ことを挙げています。 9

Slide 10

Slide 10 text

散々言われている「シフトレフト」という言葉に、少し引っかか りを感じていた シフトレフトはもちろん重要で、不具合を早期に見つけるのは良いこと とはいえ「早期発見のためにとにかく早く関わればいい」という解釈が広がっている 気がしており、そこに少し違和感を感じていた 10

Slide 11

Slide 11 text

「シフトレフト」と「品質を設計で作り込む」は少し違います 11

Slide 12

Slide 12 text

元ネタ トヨタ生産方式の 「品質を工程でつくり込む」 12

Slide 13

Slide 13 text

「シフトレフト」よりも、トヨタ生産方式の「品質は工程で作り 込む」のほうがしっくりきた 13

Slide 14

Slide 14 text

品質を設計で作り込むとは 「バグが出たらテストで潰す」 ではなく、 「そもそもバグを生まない構造を設計する」こと 14

Slide 15

Slide 15 text

トヨタ生産方式における「品質を工程でつくり込む」とは、 不良を後で検査で見つけるのではなく、各工程で発生させないようにする考え方 各工程の作業者が自ら品質を保証する「自工程完結」の実践 結果として、後工程に不良を流さず、全体の生産性と信頼性を高める仕組み 15

Slide 16

Slide 16 text

ソフトウェア開発に置き換えると バグをテストで見つけるのではなく、要件定義・設計・実装の段階で生まれない ようにする 各工程(要件・設計・実装)が自分の工程の品質を保証する 設計上の制約・責務分離・テスト容易性を最初から考慮し、後工程の生産性を下 げない 16

Slide 17

Slide 17 text

「品質は工程で作り込む」 「自工程完結」の考え方例 「次工程はお客様」思想 自分の後に続く工程(たとえば組立ラインの次の人)を「お客様」と見な し、  “お客様に不良を渡さない”という倫理を日常的に内面化する  →アジャイル開発だと細かいプロセスを頻繁にまわしていくので、ウォータ ーフォールのように進める必要はない   しかし、前のプロセスで気づけたであろうことは仕組み化が大事 自分の工程で完結=前工程を責めない 「不良は自分の工程で潰す」ことを前提とし、問題を後回しにしない 前工程への文句ではなく、自分の工程を変えて防ぐ 参考:https://www.toyota.co.jp/jpn/company/history/75years/data/company_information/quality/explanation02.html 17

Slide 18

Slide 18 text

1. なぜ設計で品質を作り込む必要があるのか 18

Slide 19

Slide 19 text

テスタビリティレビューの経済的効 果 At least half of your testing costs can be cut before anybody ever runs a test, if only your systems are designed with testability in mind. 翻訳: テストのしやすさを念頭に置いて設計さ れているだけで、実際にテストを実行する前 に、テストコストの少なくとも半分は削減でき る 19

Slide 20

Slide 20 text

テスタビリティは設計段階で考えた い Failing to review designs and code for testability: At least half of your testing costs can be cut before anybody ever runs a test, if only your systems are designed with testability in mind. 翻訳: もしシステムがテストのしやすさを念頭に置い て設計されているだけで、実際に誰かがテスト を実行する前に、テストコストの少なくとも半 分は削減できるのです。 20

Slide 21

Slide 21 text

2. 要件定義/仕様決定でテスタビリティが漏れやすい のはなぜか 21

Slide 22

Slide 22 text

エンジニアの視点 「どう実装するべきか」を考えながら参加していることが多い 自分が実装するので、技術的な実現方法(プロダクションコード)に意識が向く 「プロダクションコードに分岐を追加する」というコーディングコストは非 常に低い テストケースの爆発には意識が向きづらい QAの視点が補完できる(もちろんエンジニアもこの視点があると良い) 「この仕様だと何パターンのテストが必要か」 「どのような制約があればテストが減るか」 22

Slide 23

Slide 23 text

3. 品質を作り込むためにはどうすればいいのか 23

Slide 24

Slide 24 text

QAとして品質を作り込みやすいのは 要件定義/設計段階 24

Slide 25

Slide 25 text

実例:設計段階でのQAの介入 During one iteration planning meeting that I was in, the programmers started talking about implementation and drawing pictures on the whiteboard to show what they were thinking. 翻訳: イテレーション計画ミーティングで、プ ログラマーたちが実装について話し合い、ホワ イトボードに図を描いていた。 25

Slide 26

Slide 26 text

QAからの問いかけ I thought about it for a bit and asked the question, "Can it be done more simply? The permutations and combinations for testing your proposed implementation will make testing horrendous." 翻訳: 少し考えてから質問した。 「もっとシンプ ルにできませんか?その実装案だと、テストの 順列組み合わせが膨大になり、テストが地獄に なります。 」 26

Slide 27

Slide 27 text

その後の展開 The programmers thought about it for a couple of minutes and suggested an alternative that not only met the customer's needs, but was simpler and easier to test. It was a win-win combination for everyone. 翻訳: プログラマーたちは数分考え、顧客のニ ーズを満たしつつ、よりシンプルでテストしや すい代替案を提案した。全員にとってWin-Win の結果となった。 27

Slide 28

Slide 28 text

実例1:外部アプリとのデータ連携 Before: 共通基盤からサービスにデータ連携する場合のPush型連携 各サービスの受信状況・再送制御・失敗時のリトライなど、共通基盤側に多くの 条件分岐が必要 データ連携エラーがあったときに、各サービス起点で復帰できない(共通基盤の job実行を待つ必要がある) 28

Slide 29

Slide 29 text

Push型の仕組み 29

Slide 30

Slide 30 text

Push型連携 メリット: リアルタイム性高くデータ連携が可能 リソースの問題: 共通基盤のアプリチームが全ての連携実装を担当 3サービス分の実装・テスト・保守でリソース枯渇 ドメイン知識の問題: 各アプリの仕様は、それぞれのプロダクトチームほど理解していない 仕様変更のたびに確認・調整コストが発生 うっかり分岐で対応すると3サービスすべてに影響が出てしまう可能性がある 30

Slide 31

Slide 31 text

After: Pull型連携 シンプルな設計: 一つのエンドポイント(GET /users)を提供 各サービスが必要な時にデータを取得(or ポーリング)する メリット: 各サービスは自分のタイミングで取得 共通基盤チームの負担が大幅に軽減 副作用の心配がない(取得するだけ) デメリット: リアルタイム性の高いデータ同期には向かない 31

Slide 32

Slide 32 text

After: Pull型の仕組み 32

Slide 33

Slide 33 text

実例2:申込情報の扱い 申込機能移管プロジェクト 33

Slide 34

Slide 34 text

申込機能移管プロジェクトの背景 申込情報は基幹システムに連携する必要がある 売上速報に使われている 不具合を起こすと影響が大きい 34

Slide 35

Slide 35 text

Before: 移管前の申込管理(旧システム) 問題のある設計: キャンセル期限後も申込情報を編集できた 確定済みの申込に人を追加できる 名前やメールアドレスを変更できる 35

Slide 36

Slide 36 text

After: 移管後の申込管理(新システム) 復元力の高い設計: キャンセル期限後は申込情報を確定(イミュータブル) 確定後は編集不可 履歴として保持できる →過去の申込をもとに売上データを再生成できる 36

Slide 37

Slide 37 text

イミュータブル設計のメリット 冪等性の担保: 同じ申込データから何度実行しても同じ結果 リトライ時に「入力値が変わっていた」という問題が起きない テストの容易性: テストデータが不変なので、テストが安定する デバッグの容易性: 「あの時どんな値が送信されていたか」が確実にわかる 過去の障害を当時の状態で再現できる 「今のデータと違う」という辛さがない 37

Slide 38

Slide 38 text

実例3:管理者削除機能 法人管理者向け管理画面 38

Slide 39

Slide 39 text

管理者削除機能の仕様 シンプルそうな機能: 管理者一覧画面がある 各管理者の横に「削除」ボタンがある ボタンを押すと削除される 39

Slide 40

Slide 40 text

テストケース考え始めると意外と考慮ポイントがある 誰でも削除可能な仕様だと: いろいろと条件分岐のための考慮が発生する: 最後の1人を削除できるか?  →組織に管理者がいなくなると困る 自分で自分自身を削除した場合の挙動は? 他の人から消されたときと挙動に差はある? 削除後のリダイレクト先は? 削除実行者が消えた場合のログは? 40

Slide 41

Slide 41 text

仕様をシンプルにするための制約を追加すると... 本人は削除できない このシンプルなルールだけで: 自分以外の管理者は削除可能 自分自身は削除不可  →「最後の1人」問題も自動的に解決  →説明しやすい 41

Slide 42

Slide 42 text

これらの事例に共通する考え方 2つの設計原則 42

Slide 43

Slide 43 text

原則1:決定性の向上 決定性とは: 同じ入力に対して、常に同じ出力が得られること ソフトウェアの振る舞いが: 説明しやすい 再現可能である 外部の状態変化に影響されない 43

Slide 44

Slide 44 text

原則2:条件分岐の削減 シンプルなルールにする: 複雑な条件分岐を削減し、理解しやすい設計にする 動的な状態依存を減らす エッジケースを減らす テストすべき組み合わせを減らす 44

Slide 45

Slide 45 text

決定性を高めるとテストが減る理由 決定性が低い設計: タイミング依存のバグが発生しやすい リトライ時の動作が予測困難 副作用のテストが必要 決定性が高い設計: 同じ入力なら同じ結果 → テストケース削減 冪等性が保証される → テストが容易 45

Slide 46

Slide 46 text

要件定義段階で複雑性を下げるには 非常に限られたケース用に、 「一応」 「念のため」で対応すると複雑になりかえっ て不具合のもとになる 46

Slide 47

Slide 47 text

YAGNI原則 You Aren't Gonna Need It YAGNI stands for "You aren't gonna need it" and advocates against investing time in functionality that's not needed right now. 翻訳: YAGNIは「どうせそれは必要にならない」 の略で、今すぐ必要とされていない機能に時間 を投資することに反対します。 47

Slide 48

Slide 48 text

YAGNIが言及しているコスト The less code in the project, the better. Introducing code just in case without an immediate need unnecessarily increases your code base's cost of ownership. 翻訳: プロジェクトのコードは少ないほど良 い。差し迫った必要性がないのに「念のため」 にコードを導入すると、コードベースの所有コ ストを不必要に増大させます。 48

Slide 49

Slide 49 text

YAGNIと品質保証 コード量が少ないほど、バグが潜む場所も 少なくなる 機能が少ないほど、システムの複雑さが抑 えられ、テストすべき組み合わせも減る 不要な機能は、将来の変更時に予期せぬ不 具合(デグレード)の原因となりうる 49

Slide 50

Slide 50 text

僕が実際に使っている問いかけ方例 「この要件/仕様ってなんで必要なんでしたっ け?」 要件/仕様がなんの価値と結びついているの かわからなくなったときに聞いている 「 【梅案】だとこういう感じで【竹案】だとこ んな感じでして、 【梅案】のほうが実装コスト は軽いんですが困ることってありそうです?」 隅付き括弧の中は案に名前をつけて言うこ とが多い 梅からいくと、上位の松竹にした理由を回 収しやすい 50

Slide 51

Slide 51 text

松竹梅メソッドを使うとき になぜ梅から考えると良い か コストは精緻に計算しやすい一方 で、価値(顧客がどれくらい満足し たのかなど)が本当にあったのかは 計測しづらい  →価値ある最小限の機能を提供 し、起きた反応を経験して判断材料 をためると良い 51

Slide 52

Slide 52 text

4. おわりに 52

Slide 53

Slide 53 text

明日からはじめやすいアクション Claude Code や Codex CLI などのAIツールを使って、普段コード読まない方でもコ ードを落としてきて 「hogeというパスの機能はどの程度複雑?また、どんなテストが存在してい る?」 などざっくり聞くことから始めても少しずつ理解できていける 開発が進んでいく中で、どんな価値を実現する機能なのかは抜けることがあるの で 「自分だけわかってなかったらすみません、このデータ連携でリアルタイム性が 必要な理由はなんでしたっけ?」 とMTGやslackで疑問を潰しておくと、チームとしても再認識できて良い 53

Slide 54

Slide 54 text

まとめ QA(にかかわらずチーム全員)は 設計段階から品質を作り込むことで最大の価値を発揮できる 54