nikkie-ftnextの日記

イベントレポートや読書メモを発信

読書&写経ログ | #ちょうぜつ本 6.5 FizzBuzzを例にテストファーストで開発。BDDをしていたんだ

はじめに

変更しやすいコードが書けないのにソフトウェア開発とか舐めているのですか
天使様1ごめんなさい〜、nikkieです

「かわいい」と技術書が夢の合体を果たした、ちょうぜつ本(『ちょうぜつソフトウェア設計入門』)!🤗
読書会と絡めて読み進めており、今回は第6章「テスト駆動開発」の6.5を写経しつつ読みました。
写経しながら思ったこと2をアウトプットしていきます

目次

前回のちょうぜつ本!

いわしまんさんの書評エントリがきっかけで、手に取りました。
6.4まで読み進め、テスト駆動開発の準備はOK

次の読書会の予習の一歩目として6.5に取り組みます

はじめてTDD 〜FizzBuzzを例に〜

6.4まででテストの書き方を学び、いよいよ6.5からテスト駆動開発を実践します。
例題はFizzBuzz
読者にとって初めてのTDDは以下のように進みました。

  • NumberConverterクラス(何もしない)を用意する
  • convertメソッドに1を渡したら文字列の"1"を返すことを検証するテストを追加
    • convertメソッドがないとテストを実行できないので空文字列を返す状態で実装
    • 1のケースのテストは落ちている🟥
  • 最小限の実装でテストを通す
    • convertメソッドは固定値の"1"を返す🟩
  • 2のケースを追加。文字列の"2"を返すことを検証
    • 落ちる🟥
  • 最小限の実装でテストを通す
    • 引数を文字列にして返す🟩
  • 3のケースを追加。文字列の"Fizz"を返すことを検証
    • 落ちる🟥
  • 最小限の実装でテストを通す
    • 引数が3と等しいときの分岐を追加🟩
  • 以下は省略します。気になる方は書籍をどうぞ!

写経ログ

Pythonで写経したコードはこちら:

Red-Green-Refactorのサイクルじゃないんだ

  • 私が普段やっているのは、 Red-Green-Refactor というサイクル
  • 6.5は Red-Green のサイクルで、Refactorはサイクルの外だった

Refactorが別になっている影響が出ているのではと思うところは、例えば3のケースを通す実装

class NumberConverter:
    def convert(self, n: int) -> str:
        if n == 3:
            return "Fizz"
        else:
            return str(n)
  • 早期リターンが使えるので、elseいらないのではないか
  • 私はelseを使う実装がまず書けなかった(最小限なので、行数が少ない早期リターンでまず書いた)

Red-Green-Refactor だと、上の if-else の実装で3のケースを通した(Green🟩)あと、早期リターンで書き直すチャンスがあるのではないか

class NumberConverter:
    def convert(self, n: int) -> str:
        if n == 3:
            return "Fizz"
        return str(n)
  • もうちょっというと、Red🟥の捉え方も少し違う
  • 6.5では、実行できるがテストが通らないがRed
  • 私のとらえ方では、テストが通らないがRed。実行できないもRedに含まれる
    • Uncle Bobの『Clean Craftsmanship』がきっかけ3
    • 例えば
      • importできなくてRedなので、importできるようにクラス追加(Green)
      • クラスにメソッドがないためにRedなので、メソッドをもたせる(Green)
    • TDDに熟達してくると Red-Green-Refactor を小さい単位で何回も回せるのだと理解している

最小限の実装

テストコードと実装の振る舞いが同じ歩調で育ちます (Kindle版 p.240)

  • テストファースト(実装より先にテストを書く)のよさはきっとこれ(すばらしい言語化👏)
  • 実装(アルゴリズム)だけ浮かぶことあるんですよね〜
    • テスト一切書かずに実装しきっちゃって、機能追加で四苦八苦(壊しているのか分からない)
      • 実装に比べて、テストのカバー範囲が薄い(TDDは複式簿記4なのに!)
    • 浮かんだ実装を一気に書けないという制約をあえてかける5ことで、動く仕様ドキュメント(=テストコード)と実装の両者のカバー範囲が一致した状態を保てる
      • プロとしてプログラムを書いていく上ではこの状態は保つべきだな〜6

天使様、(過去の私に)言ってやってください

実装とテストコードの歩調が合ってないのにソフトウェア開発とか舐めているのですか

本当にごめんなさい〜🙇‍♂️

実はBDDだったのです!

6.5を読んで衝撃だったのは、初めてのTDDを終えたあとの部分!
ここでやった例は、実はBDDだったのです。

TDDの真価は設計技法として使ったときに発揮されるとのことで、これは続く6.6を読むのが楽しみになってきました!

そして、DHHの「TDD is dead」にも言及がありました。

TDD実践者の私としてはDHHのこの主張がさっぱり分からなかった(ちっとも死んでないよ!)のですが、ちょうぜつ本によると

最短実装で動くフレームワークに対してさえも、過剰に細粒度なTDDを適用しては、なかなかアプリケーションを作らない開発者を見て、“TDD is dead”と表現しました。(Kindle版 p.243)

なるほど、こういった文脈であればDHHの主張も理解できます。
過ぎたるは及ばざるが如し、ですからね(でも一次情報に当たりたいので積ん読です)

終わりに

ちょうぜつ本 6.5で、FizzBuzzを例にTDDしました。
「TDDって2パターンあるっぽいんだよな」と感じていたのですが

  • 6.5で紹介されたBDD
  • 6.6でカバーされる設計技法としてのTDD(おそらくモックを使う)

ということなのかなと仮説を持ち始めています(6.6を読んで検証だ!)。
テストファーストは共通で、BDDとTDD(設計技法)があるという理解です。

P.S. 9/22(金) 第6章「テスト駆動開発」後半のちょうぜつ本_読書py!

次回ちょうぜつ本_読書py(Python使い視点でちょうぜつ本を読む、みんなのアウトプット中心の読書会)は9/22(金)です!

常連さんも、お久しぶりの方も、はじめましての方もテスト駆動開発に興味ある方、大歓迎です!
ぜひぜひお気軽にお越しください〜


  1. ちょうぜつ本読書ログシリーズではおなじみのこちらの書き出し。元は『お隣の天使様にいつの間にか駄目人間にされていた件』の「家事ができないのに一人暮らしとか舐めているのですか」です
  2. 『エンジニアの知的生産術』にもありますが、私は写経しながらかなりいろいろ考えるスタイルです(著者とペアプロに入っている感覚)
  3. 「ITエンジニア本大賞 2023」で投票したおすすめ本の残りは『プロになるJava』『Clean Craftsmanship』『Googleのソフトウェアエンジニアリング』『ソフトウェアアーキテクチャの基礎』『エンジニアリングマネージャーのしごと』です #itbookaward - nikkie-ftnextの日記 より「Uncle Bobに見せてもらったTDDは、1つのテストを通す上で、RedとGreenを何回も往復します!
  4. 近年のUncle Bobの書籍でよく見る表現です。『Clean Agile』や『Clean Craftsmanship』で見た覚え
  5. 『Clean Craftsmanship』では「金メダルを目指さない」という警句がありました。この効果の1つに歩調を合わせるがあると気づきました
  6. グリーンバンドの話を思い出しました 天使様のバンド自作、ありだな