📚

『テスト駆動開発(Kent Beck)』書評

2023/02/22に公開

今回の種本は『テスト駆動開発(Kent Beck)』です。

https://www.ohmsha.co.jp/book/9784274217883/

原著の出版は2002年。新訳版の訳者は和田卓人@t_wadaさんです。
和田さんの次のスライドが本著にたどり着いたきっかけとなりました。

https://speakerdeck.com/twada/building-automated-test-culture-2022-autumn-edition

スライドでは直接テスト駆動開発には触れていませんが、途中で引用されている「LeanとDevOpsの科学」や和田さんもツイートしていた「継続的デリバリーのソフトウェア工学」などを通じてテスト駆動開発に興味を持ちました。

https://book.impress.co.jp/books/1118101029

https://bookplus.nikkei.com/atcl/catalog/22/12/01/00531/

これらの内容もいずれ記事にしたいと思います。

TL;DR

  • やってみると気持ちいい
  • 付録cがお勧めポイント
  • 伝統的SIerの私たちも適用できる

著者紹介

Kent Beck

ソフトウェア三行において最も創造的で称賛されているリーダーの一人であり、パターン、エクストリームプログラミング、テスト駆動開発を、情熱をもって実践している。

書籍巻末より

書籍概要

テスト駆動開発の例題の実践、そのパターンの説明が主になっています。

まえがき
謝辞
はじめに
第I部 多国通貨
第II部 xUnit
第III部 テスト駆動開発のパターン
付録A 因果ループ図
付録B フィボナッチ
付録C 訳者解説:テスト駆動開発の現在
参考文献

オーム社Webサイトより抜粋

Red → Green → Refactoringは楽しい

本書は原著のタイトル(Test-Driven Development by Example)にある通り、前半2部でJavaとPythonの例を用いた実践を行っていきます。

まずTODOリストを作成します。

要件を実装するためにどのようなテストが必要かを羅列し、それから仮の実装を考えて追加します。

比較的実装しやすいものから手を付けるところからサイクルが開始します。

次のサイクルを繰り返していきます。

  • Red 失敗するテストを書く
  • Green できる限り早く、テストに通るような最小限のコードを書く
  • Refactoring リファクタリング

サイクルの中で気が付いた条件や複雑になりすぎる実装はTODOリストに追加して先に進みます。

簡単な四則演算で具体的な例を見ていきます。

Red 失敗するテストを書く

2に3を加算すると5になるのでその実装を想定したテストを記述します。

package calc;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class CalcTest {
    @Test
    public void TestSummation() {
        Calc calc = new Calc();
        assertEquals(5, calc.sum(2,3));
    }
}

この時点ではCalcクラスすらないので、コンパイルエラーになります。

コンパイルエラー

クラスがないので、クラスを作成していきます。

IntelliJであれば次のようにクラスを追加できます。

クラスの追加

詳しくは本家を参照してください。

https://pleiades.io/help/idea/tdd-with-intellij-idea.html

足りなかったメソッドsumも追加します。

package calc;

public class Calc {
    public int sum(int a, int b) {
        return 0;
    }
}

とりあえずコンパイルエラーが消滅したのでテストコードを動かします。

最初の失敗

おめでとうございます!
最初のRedとの出会いです。

Green できる限り早く、テストに通るような最小限のコードを書く

テスト駆動開発の手法で面白いのはまずはテストがGreenになることを徹底的に目指すことです。
「正しさや美しさはあとから追求することにしよう」と本書の序盤では語られています。

テストが動作するには5が返却されればいいので、仮実装としてreturn 5に修正します。

package calc;

public class Calc {
    public int sum(int a, int b) {
        return 5;
    }
}

テストコードを動かします。
テスト駆動開発では変更を加えたら必ずテストコードを動かします。

最初の成功

おめでとうございます!
コンソールもきれいで楽しいですね。

このプロセスの大事なところは実装を行わずに期待値をそのまま返すようにしたことで、
テストコードの正当性が確保されたことです。

よく現場で見られるジュニアエンジニアのよくない行動でテストコードをプログラムコードから起こすことで、

テストコードがプログラムコードを検査に通すことを目的にして書かれるということです。

テストはGreenになり、カバレッジ100%で、マネージャーもニコニコです。
しかし壊れたプログラムコードに合わせたテストコードがあっても気が付くことはできません。
マネージャーが怒り始めるのは数か月後でしょう。

「どうしてこんな単純なバグを単体工程でみつけられなかったんだ!」

Refactoring リファクタリングをする

このままでは加算は行われないので、コードを修正していきます。

package calc;

public class Calc {
    public int sum(int a, int b) {
        return a + b;
    }
}

テストコードを動かします。
繰り返しですが変更を加えたら必ずテストコードを動かします。

二回目の成功

おめでとうございます!
加算処理の実装ができました。

サイクルを回す

要件は四則演算なので、TODOリストには多くの課題が残っています。
単純な話では残りの減算、乗算、除算が必要です。

次の実装を始めましょう!
ではなく・・・
次のテストコードを実装し、Redになるところから始めるのです・・・。
さあ、テスト駆動開発を信じて・・・。

後半を先に読むのもあり

本書の後半は100ページにわたって、前半に例題で実践してきた手法の解説、利用方法が書かれています。
こちらを先に読んでから例題を進めるのもよいと思います。

付録Cを是非読んでほしい

付録cには訳者による解説が書かれています。
テスト駆動開発の歴史、その過程で生まれた誤解、訳者が考えるこれからのテスト駆動開発などが短くまとまっています。

ここで要約を行うと訳者の伝えたいメッセージが伝わらないと思います。
ぜひ手に取って読んでいただきたいです。

私たちにも実践できる

新しい手法となるとチームや上司を説得しなくてはいけなくなり、挫折を経験するのは技術者あるあるだと思います。
テスト駆動開発はスキルであり、個人レベルで実践できます。

前述の付録Cから一節を引用します。

TDD(注:Test-Driven Development = テスト駆動開発)は結局のところ個人のプログラムテクニックです。
コードの書き方のスタイルであり、コードとの向き合い方です。
技法として自分自身の中に綴じているので、どのような環境でも実行可能です。
特定の言語、フレームワークに依存していませんし、開発チームのプロセスやサイズにも依存していません。

賛同者や協力者がいなくとも始められるというのは救いです。
どのような状況下にあっても、自分自身で修練を積むことで、現状を打破するきっかけにつながるからです。

本書P306「TDDはスキル」より

実戦に投入できるスキルかどうかは各位で確かめていただきたいです。

株式会社ソルクシーズ(事業戦略室)

Discussion