圧倒亭グランパのブログ

30年後の自分にもわかるように書くブログ

テスト駆動開発は「治具を使いこなす」ようなもの

前回に続き、@t_wadaさん翻訳の「新訳版 テスト駆動開発」を読み、思ったことについて書きます。

   

前回は、この本の読み進め方について書きました。

at-grandpa.hatenablog.jp

今回は、前々から思っていた「テスト駆動開発治具を使いこなすようなものだ」ということについて、具体的に言語化できたのでまとめます。  

目次

 

治具」とは

治具とはなんでしょうか。wikipediaを見てみましょう。

治具 - Wikipedia

治具 - wikipedia
出典:wikipedia

治具(じぐ)は、加工や組立ての際、部品や工具の作業位置を指示・誘導するために用いる器具の総称。

自分がこの言葉と出会ったのは、十年ほど前の学生時代のインターンで携帯電話の生産工場を訪れたときです。組み立て行程の内、手作業で組み立てる部分があるのですが、そこで「治具」というものが使われていました。手作業のみで組み立てを行うと、取り付け先の携帯本体は固定できないですし、取り付ける部品の位置も手で繊細に制御しなければなりません。かなりのストレスです。しかし、治具を用いると、早く、正確に、ストレスなく作業が行なえます。本体を固定する治具、部品の位置を誘導する治具、そして次の工程にはまたそれ専用の治具があります。治具はかなり局所的なもので、「その作業のみの効率と品質を最大化するための道具」です。生産工場で話を聞いていて驚いたのは、「治具を開発する専門のチーム」があることです。作業者の要望を聞いたり、もっと効率を上げられないかなどを議論し、生産性の向上を目指します。工場全体のパフォーマンスに直結する、非常に重要な部分です。

今回は、この「治具を使いこなす」と「テスト駆動開発(以下TDD)」がとても似ているのでは?と思ったのでまとめました。

 

TDDを間違って使っていた自分

昔、ピアソンから発売されていたTDD本の旧訳版を読みました。その時は深いところまで読み込んでおらず、TDDは以下のようなものだと軽く認識していました。

  • テストから先に書く
  • とにかくテストを回してグリーンバーを維持する
  • これらをやっていれば、開発が駆動するし良いコードが書ける

当時の自分が、何か新しい新機能を実装したときの話をしましょう。まず始めに行ったのが、機能要件を満たす具体的な実装を思い描くことでした。ああいうメソッドがあって、必要な引数はこれで、このリストをmapでこう処理すればいいな、出力はこうだ、という具合です。次に行ったのはテストの想像です。「TDDではテストから書く!」という知識をもとに、頭の中で実装を思い浮かべながら「こういうテストが必要だな」と想像しました。そして、そのテストから書きました。ちゃんとテストから書いています。(自分の知っている)TDDですね。テストを書いていると、かなり処理が複雑になってきて、頭のなかで実装を想像するのが困難になりました。わけがわからなくなってきたので、テストを書いている途中ですが、実装のコードも書き始めました。メソッドの前半部分を書いて、「ここまでの処理は正しいかな?」と確認するために、実装の途中結果をreturnして、それをテストでassertionします。グリーン。よし。こうやって、ちゃんとグリーンバーを維持しつつ、メソッドを成長させていったのです。とても(自分の知っている)TDDですね。これを行っていけば良い設計になると信じて、どんどん進めました。結果、そこに出来上がったのは、何十行にも膨れ上がり、至る所で重複したコードが並ぶ複雑怪奇なモンスターコードでした。保守したくありません。ちゃんとTDDをやったのに。。。TDDを行ったつもりですが、まったく良くない設計のコードが出来上がってしまいました。

これは、TDDの使い方を間違っていたからです。TDDを「治具を使いこなす」ように行えば、このようなことは起きません。

 

テストは治具

テストは治具です。TDDでは、治具のようにテストを使いこなします。

ある携帯の組み立て作業を行う際、いきなり携帯本体に手を出してはいけません。まずは治具の設置を行います。部品を正確な位置に取り付けられるように調整しましょう。品質に関わってくる部分です。この治具を通って生産された携帯は、多くの人に使われます。使いにくい携帯にならないよう、部品の位置の調整はしっかり行いましょう。作業途中で「少し品質が悪いかな」と感じたら、治具を調整し直しましょう。よりよい品質にするためには、治具の調整も必要です。

あるメソッドを書く際、いきなりメソッド本体に手を出してはいけません。まずはテストを書きます。「自分がそのメソッドを使いやすい」と思うインターフェースを定義しましょう。品質に関わってくる部分です。このテストを通って作成されたメソッドは、多くの人に使われます。使いにくいメソッドにならないよう、インターフェースの定義はしっかり行いましょう。コーディング途中で「少し品質が悪いかな」と感じたら、テストを直しましょう。よりよい品質にするためには、テストの修正も必要です。

どうですか?とても似ていませんか?まとめると以下です。

  • 始めに(治具|テスト)を(設置する|書く)
    • (携帯本体|メソッド)のことは一切考えない
  • (携帯本体|メソッド)が使いやすくなるように(部品の位置|インターフェース)を定義する
    • ここで品質が決まる
  • 途中でおかしいなと感じたら(治具|テスト)を修正する

昔の自分はこれに全く則っていませんね。「携帯本体をどう動かすか」ばかり気にしていて、使いやすさの考慮と、その使いやすさ・品質を保つための治具の固定ができていませんでした。設計の良くない携帯本体に引っ張られる形で治具を扱っていたことになります。これでは良い品質にはならない。

さらにギュッとポイントをまとめると以下になります。

  • 良い設計は何かを始めに熟考する
  • その設計になるように定義を固定してしまう
  • 定義が悪ければ都度修正する

これで、始めに考慮した良い設計に向かって、ずれることなく実装できます。まさに治具

さて、ここで1つ重要な点があります。次に続きます。

 

TDDは「良い設計」を生むものではない

「TDDを行えば良い設計になる」と昔の自分は思っていましたが、これは間違いでした。TDDは「自分で決めた設計からずれないようにするもの」です。治具を使ったからといって、良い設計の携帯にはならないのと同じですね。「部品はこの位置だと使いやすい」というのは始めに自分が考えるものであり、「そこからずれないようにする」のが治具の役割です。

この間違いに気づくと、次に思い浮かぶのが「良い設計にするには?」という疑問です。答えは簡単です。自分の知識です。TDDを行っていればデザインパターンを使いこなせるわけではなく、デザインパターンを知っている人がデザインパターンを使いこなせるのです。ということで、まだまだ勉強は続くのです。

パターンに関しては、新訳版 テスト駆動開発 の第Ⅲ部にまとめられています。ここもカバーできているのは素晴らしいと思います。まず始めにぶつかる「良い設計とは何か」のハードルを低くしていると思います。そして、スムーズにTDDのサイクルに導かれる。素晴らしいですね。

 

まとめ

今回は「テスト駆動開発治具を使いこなすようなものだ」という自分の考えを細かく見ていきました。テストは治具であり、TDDのサイクルによってテストを治具のように使いこなし、自分の思い描いた設計からずれないようにする。この流れを意識してTDDを回せるようになりました。「TDDをやっていれば良い設計になる」という勘違いにも気付けたのはよかったです。「あたりまえじゃん」と思う方もいらっしゃるかもしれませんが、自分にとっては良い気付きでした。

この「テスト駆動開発治具を使いこなすようなものだ」という考えは以前から持っていたのですが、出演させていただいた以下の ajito.fm#13 で、ちらっと「治具のようなものですね」というシーンがありました。この回は、TDDについて和田さんも含め、いろいろなエピソードや考え方が話されているので、興味がある方はぜひ聴いてみてください。

ajito.fm