ObjectSquare [2013 年 10 月号]

[突撃インタビュー]


組み込みアジャイルコーチ James Grenning さん突撃インタビュー IN JAPAN!

 James さん

去る 5 月に東京にて開催された Agile Japan 2013 にてキーノートスピーチおよび TDD のワークショップを担当された James Grenning さんにインタビューを実施させていただきました。

James さんは、組み込みソフトウェア開発におけるアジャイル開発のコーチ・トレーナー・コンサルタント、『 Test Driven Development for Embedded C(翻訳書は「テスト駆動開発による組み込みプログラミング ― C 言語とオブジェクト指向で学ぶアジャイルな設計」)』の著者、アジャイルソフトウェア開発宣言の著者 17 名の 1 人、そしてアジャイルな見積り手法「プランニングポーカー」の考案者でもあります。

2012 年 10 月号で公開したインタビュー記事 *1 に続く本記事では、これから TDD に取り組む人、すでに取り組んでいる人が感じている疑問についてお聞きしました。

*1 Agile 2012 開催地のアメリカ・テキサス州ダラスにて実施。

  • TDD のトレーニングと実プロジェクトへの適用のギャップをどう埋めるか?
  • テストを書く場所はどう判断するか?
  • 事前にどれくらい設計を考えるか?
  • 組み込み分野のアジャイル開発 今後の展望について

  • なお、本インタビューは、翻訳書監修者の蛸島さん、翻訳書の推薦者であり Agile Japan 実行委員の平鍋さん、Agile Japan 事務局の近藤さんのご協力を受けて実現できました。協力いただいた皆様にこの場を借りて感謝いたします。


    1. TDD のトレーニングと実プロジェクトへの適用のギャップをどう埋めるか?

    -- 今回はインタビューのお時間をいただきありがとうございます。まず、TDD を実プロジェクトに適用する際の工夫について質問させてください。TDD のトレーニングと実プロジェクトへの適用には大きなギャップがあると思います。それをどのように埋めているのでしょうか?例えば、実プロジェクトでは厳しい納期や品質基準があったり、テストのないレガシーコードがあったり、TDD を導入する上で超えなければならないハードルがあります。

    トレーニングのスケジュール

    私が普段、仕事でどうやっているかについてお話しましょう。私は、TDD を新しく学び始めた人にトレーニングをする時は、最初に理想的な TDD を見せます。それは彼らにどこに向かっていくか具体的なイメージを持ってもらうためです。

    たいてい新しいチームと 1 週間一緒に作業をします。そして、理想的な TDD を見せるのに 3 日間かけます。この時、既存のコードはありませんから、彼らは理想的な C コードを実装できます。

    次にやることは、2 日間を使って、彼らに現実的な TDD を体験してもらい、既存のコードにもテストが追加できることを確信してもらいます。これまで TDD のトレーニングをやってきた中で、最初の 3 日間だけでは不十分だと気づいたからです。開発環境からコードを取り出し、テストハーネスにテストを追加することは非常に困難なことです。既存のコードに対するテストの追加方法を知らない多くの人は、TDD の価値を享受できません。

    -- TDD の理想と現実についてもう少し詳しく聞かせていただけますか?

    理想のTDDにおいてやることは、テスト駆動で開発し、リファクタリングすること。主にグリーンフィールド *2 の作業です。書籍の例を見ていだければ、どういう内容かは分かってもらえると思います。この作業で、参加者には理想的な世界で TDD のビジョンを理解してもらいます。

    *2 レガシーコードがなく、新しく始める新規開発のこと。つまりしがらみがない理想世界。

    ただ、理想的な世界は TDD を始めるには丁度良い内容ですが、エキスパートになるには不十分なんです。現実はスパゲッティコードです。あなたのコードはあらゆる場所に依存関係があるでしょう。一部のコードを取り出すと、依存先のコードが一緒についてきてしまい、テストがかなり難しいものになります。最初からテストできるような設計でコードを書かなければ、そのコードはテストできるようになりません。だから多くの人はターゲットにソフトウェアをアップロードして、ボタンを押しながら手動テストするしかありません。

    そこで私が取り組んでいるのは、理想の TDD で学んだことを現実に適用することを支援することです。もし自分ひとりで現実に対処しようとしたら、フラストレーションがたまって途中で諦めてしまいます。皆さん、助けが必要ですよね。そこで皆で一緒に集まってワークショップをやります。皆で自分のコードを持ち寄ってテストを追加する「レガシーコード・ワークショップ」を開催します。あなたの会社でも、このワークショップはやれるはずです。

    -- レガシーコードワークショップではどのようなことをするのでしょうか?

    テストを追加するプロセス

    テストを追加できる状態にするための最初の小さなステップを見つけます。一度に一つの小さい問題を順番に解決します。これは TDD と同じ原則です。

    具体的なテクニックは簡単です。小さくても良いから、テストを実際に書いてみることです。テストケースに関数を呼び出すコードを書いて、テストケースをコンパイルします。おそらく大量にコンパイルエラーが出るでしょう。コンパイルエラーが出たら、インクルード文を追加したり、エラーを解消します。次はおそらくリンクエラーが出ると思います。リンクエラーの問題を解決して実行すると最初はクラッシュするでしょう。次にクラッシュしないように初期化のコードを加えます。テストが書けるようになるまで、この作業を何度も何度も繰り返すのです。テストが動くようになったら、もっと意味のある作業をやれるようになります。

    このやり方は細かい作業がたくさん必要になりますが、これは小さい 1 歩を進めるために非常に大事なことです。






    2. テストを書く場所はどう判断するか?

    James氏と筆者

    -- テストを追加していくやり方は著書の 13 章「レガシーコードにテストを追加する」に書かれていましたね。では、どこに最初のテストを書くべきか、どのように判断するのでしょうか?

    テストケースを考える上では、(1) システムのどこにどんな変更するのか、(2) どうすれば期待した内容以外には変更を加えていないことをを確かめられるか、を考えてもらいます。その答えがテストケースになります。

    例えば、foo 関数に 2 つの変更を加えるとします。どこを変更するべきかはコードを調べれば分かるでしょう。そしてテストケースから foo 関数を呼び出すコードを書きます。まず、 foo 関数の実行結果と期待値を比較して、期待した処理が行われたことを確認します。さらに、foo 関数以外が変わっていないことを回帰テストで確認します。

    -- テストがない場合、どこから手を付けるべきか迷います。どうテストを追加していくかを話し合っている時に、「最初は簡単なところから手を付けるしかないんじゃないか?」という意見も聞きます。その意見についてはどう思いますか?

    OK。では、プール *3 を例に説明しましょうか?

    *3 アメリカではビリヤードのことをプール(pool)と呼ぶ。

    -- 平鍋さん:彼はプールが得意なんですよ。

    そうそう、大好きなんですよ!

    -- (一同 笑)

    うちの息子がまだ子どもの頃にプールで遊んだ時の話です。私はポケットの近くに 2 つ玉を置いてやりました。1 つはポケットの側、もう 1 つは少し離したところ。そしてキューで玉を付く方法を教えます。すると、子どもは玉を突いてポケットに入れて大満足です。この練習をして、ようやく本格的なゲームを始めるわけです。

    先ほど 1 週間のトレーニングの最初に理想的な TDD を学ぶという話をしました。理想的な TDD は私が子どもにプールを教えたのと同じで簡単です。そこはあくまでも難しい問題に取り組む前のスタート地点です。テストをどこに書くべきかを考える時は、製品の価値がどこにあるのかを考えるべきです。

    どこに価値があるか?

    例えば、このような3層の組み込みソフトウェアを考えましょう。上側はアプリケーションのレイヤ、真ん中がハードウェア抽象化レイヤ(HAL; Hardware Abstraction Layer)、下側がハードウェア実装レイヤ(HIL; Hardware Implementation Layer)です。中央の HAL は上位と下位のレイヤが密に結合しないためのインタフェースです。

    ハードウェア実装レイヤでは、UART でメッセージを受け取るとします。メッセージはハードウェア抽象化レイヤを通して、アプリケーションレイヤにコマンドとして渡されます。アプリケーションレイヤではコマンドに応答する処理を行います。

    このソフトウェアで最もテストする価値があるのはどこでしょう?おそらくハードウェア抽象化レイヤより上側です。ハードウェア、ファームウェア、ソフトウェアの3つを考えた場合、ハードウェアが変わるとファームウェアも変えないといけません。ハードウェアとファームウェアは共に短命です。一方でソフトウェアの寿命は長い。例えば、私が持っている携帯電話では 20 年も前の GSM や通信技術が未だに動いています。

    -- アプリケーションレイヤが製品の価値を決めるから、アプリケーションレイヤの方がテストする価値があるということでしょうか?

    -- 蛸島さん: 私はこのトピックについて違った意見を持っています。アプリケーションレイヤが顧客への価値を提供するという点には納得しています。しかし、組み込みソフトウェアを考えた場合、デバイスドライバに小さいバグでも発見されると、それだけで大きな問題になります。

    これだけをやれ、あれだけをやれと言っているわけではありません。元々の質問は「簡単なところから始めるべきか?」というものでした。なので「それでもいいけど、製品の価値がどこにあるのかを考えるべきだ」という意見を話しました。

    テストすべき場所についてルールはありません。ただ良い判断をしなければいけないだけです。アプリケーションに対して新しい機能を付け加える時であればアプリケーションのテストを考えるでしょう。もし、新しいハードウェアにアプリケーションを移植する場合であったり、複雑なデバイスドライバを実装しているのであれば、ハードウェア抽象化レイヤ配下をテストすることになります。

    3. 事前にどれくらい設計を考えるか?

    James氏

    -- 蛸島さん: TDD での事前設計について質問させてください。私はテストファーストで開発をやっています。良い設計を検討する際にテストが役立つということも実感しています。だから設計を思い描き、テストリストも書いています。しかし、TDDについてはまだ十分納得しきれていません。テストを書く前にどのくらい設計を検討するのでしょうか?

    まず、あなたが実践されているやり方は、私も、Kent Beck も、Bob Martin も、ケンジ(平鍋さん)もやっています。とても良いことです。そのまま続けて下さい。

    事前にどれくらい設計を考えるかは、その人のスキルや経験によります。この質問には回答はないんですよ。でも「必要な分だけやってください」では納得してくれませんよね?

    -- (一同 笑)

    大きなシステムであれば、最初の段階で設計の全体像はまだ雲の中にあり、詳細は分かりません。ただ、もっと近くまで歩いて行くとだんだんと正確に見えてきます。

    しかし、システムの部分ごとの責務はある程度分かる場合が多いでしょう。ここは通信に関することをやることだ、ここはユーザに関することだ、ここは他のことをやるとこだ、と想い描く(envision)わけです。

    プールのスコア管理アプリ

    そして実装するためのストーリーを一つ選びます。このストーリーはシステムの重要な責務が確認できるようなものを選びます。こうすることにどういう意味があるでしょうか?ストーリーは一連のテストケースにもなりますし、「動くスケルトン *4」 を使った実験にもなります。このような作業を別のストーリーに対しても行っていきます。

    *4 「実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる」で紹介されている手法。組み込みであれば、ハードウェアのI/Oから画面周りまでエンドツーエンドで通貫する機能を 1 つずつ順番に実現する。レイヤーごとに開発し、積み上げていく手法と比較すると、最初から動くシステムが出来上がり、検証しながら徐々にシステムを育てられる点でリスクを低減できる。

    もし少人数のチームで開発するとしたら、皆、一緒の場所で開発しているでしょう。好きな時に話しかけられます。膨大な時間をかけて話し合う必要なんてありません。皆が同じ方向を向いていればいいし、アーキテクチャのビジョンを共有できればいいのです。時折集まって設計について議論すれば十分でしょう。

    私がやりたくないのは、この段階であまり詳細に掘り下げて検討しすぎないことです。ラフな設計のアイディアができて絵が描けたところで、とめるのです。あまり手間をかけてはいけません。早い段階で詳細に考えこみすぎではいけません。試さずに詳細に検討しすぎても、結局は、手直しの元になるだけです。

    -- 平鍋さん:最初に絵で検討しているんですか?

    そうですね。私は図で検討します。部分ごとの責務を絵に書くだけでもアイディアのいくつかは明確になります。

    -- 平鍋さん:私も最初の全体像を描いて、徐々にテストしながら進化的な設計をしていく方が好みですね。

    例えば、プールのスコアを計算する Android アプリを例に考えてみましょうか?

    -- 平鍋さん:実践的ですね!

    -- (一同 笑)

    プールのスコア管理アプリ

    絵を描くとしたらこんな感じでしょうか?プールのルールは必ず必要になるでしょう。私は詳しいルールを知っているので、ルールが正しいか確認するためのテストを書けます。

    ただし、Android の画面やボタン、メッセージの送信などの実現手段はまだ分かりません。だから、 分かっている範囲でシステムの大まかなフレームワークの絵を描くわけです。中央にプールのルールがあります。そしてルールは Android のインタフェースを通じて画面とやり取りする必要があります。

    おそらくインタフェースには「プレイヤー 1 がショットする」というボタンが必要そうだなと思い描きます。「プレイヤー 2 がショットする」というボタンも必要かもしれない。ここで「インタフェースに同じようなボタンを用意するのは馬鹿げている」と思ったら、プレイヤーごとに見た目は同じインタフェースを、別々のインスタンスとして用意する設計に変えるといいでしょう。おそらくルールに影響があるでしょうが、こちらの方が合理的です。

    こういう風に絵を描きながら部分ごとの責務を考えていけば、何をやるべきか明確になってきます。絵のレベルですから、設計を変更することに何の躊躇もありません。

    4. 組み込み分野のアジャイル開発 今後の展望について

    -- 最後に組み込みソフトウェアでのアジャイル開発や TDD について展望をお聞かせ願えますか?

    今、組み込みアジャイル( embedded agile )について新しい本を書いています。

    -- 平鍋さん:え、本当に?それは素晴らしい。その本は組み込み領域のアジャイルの話ですか?それともアジャイルをチームに組み込むという話?

    -- (一同笑)

    組み込みソフトウェア開発で起こりそうな問題を扱っています。例えば、ユーザストーリーを使って、どう組み込みシステムを記述するのか、どう計画するのかなどです。

    -- 素晴らしいですね。早く本が出版されることを期待しております。質問は以上です。今日はありがとうございました。


    まとめ

    組み込み開発で TDD を導入する上では、James さんが話されたように現実的な課題を克服していく必要があります。まず、現場のコードはスパゲッティになっています。さらに、開発言語が C の場合、モジュールを祖結合に設計し、テスト用のモジュールに置換する仕組みを自力で実現する必要があり、難易度が高いといえます。Web 開発であれば開発言語やフレームワークがテストしやすい環境を提供してくれますが、組み込みだとそうはいきません。

    インタビューに臨んだ際には、この現実的な課題を簡単に克服する魔法のような方法があるのではないかと期待しましたが、結局は、自分でコードの依存関係を解きほぐして、地道にテストを追加していくしかないと再確認しました。残念な反面、自分がプロジェクトで実践しているやり方はそれほど間違ってはいないと確信しました。

    まとめると、TDD を現場に導入する上での重要なポイントは、以下だと理解しました。

    (株式会社オージス総研 大西 洋平)


    インタビュー参加者 あとがき

    大西 洋平(本記事の編集担当)

    講演やワークショップ開催でお疲れになっているにもかかわらず、タイトル通りの突撃インタビューを引き受けてくださった James さんに感謝いたします。初めてのインタビューのため非常に緊張しましたし、英語のやり取りのため聞き取れずに何度も聞き返すことがありました。それでも冗談を交えながら繰り返し説明していただいたり、絵を使って具体例を示していただいたり、ユーモアあり、サービス精神の旺盛な方だと感じました。(私のインタビューがつたないので、気を遣わせてしまったのかもしれませんが^^;)

    そして、お忙しい中、本企画の調整をしていただいた、蛸島さん、平鍋さん、近藤さんに感謝いたします!みなさんのおかげで企画を実現でき、自信をつけることができました。これに懲りず今後も読者の皆様の役に立つような企画をやっていきます!

    蛸島 昭之(翻訳書 監修者)

    今回のインタビューで初めて、James さんと会ってお話しすることができました。冗談を交えながらとても気さくにお話をされる中にも、ソフトウェア開発に対するとても真摯な思いが伝わってくる人柄は、書籍を通して感じていた印象そのままでした。おかげさまで今回のインタビューからとても貴重な学びを得ることが出来ました。インタビューを企画して頂いた大西さん、実現にご協力頂いた平鍋さん、近藤さん、そしてキーノートスピーチとワークショップの直後にもかかわらず快くインタビューにお答え頂いた James さんに、この場を借りて感謝の意を述べたいと思います。

    平鍋 健児(Agile Japan 2013運営委員、翻訳書 推薦者)

    Jamesさんの誠実さがよく伝わるインタビューでした。理想的なTDDを理解することと、現実の自分のチームで実際に動いている既存のシステムにおいてうまくTDDを活用することは、大きな開きがあります。自分の仕事を誇りをもってするためにも、 TDDを普及し、アジャイル開発をより現実的に日本に根付かせていく活動をしていきたい、と私自身、思ったひと時でした。


    「テスト駆動開発による組み込みプログラミング ―C言語とオブジェクト指向で学ぶアジャイルな設計」 読者プレゼント

    サイン本

    今回特別に『テスト駆動開発による組み込みプログラミング ―C言語とオブジェクト指向で学ぶアジャイルな設計』を抽選で 1 名の方に読者プレゼントいたします。
    原著書の James Grenning さん、翻訳書監修者の蛸島さんサイン付きの特別版です!

    締め切りは、2013年 10 月 31 日(木)です。当選者の発表はご本人宛にメールにてお知らせいたします。

    【個人情報の取り扱いについて】
    ご応募で頂いた個人情報につきましては、プレゼントのご連絡のみに使用いたします。お客様の個人情報は、当社の個人情報保護方針に基づき、適切にお取り扱いいたします。 また、ご本人の承諾なしに、第三者機関へ提供することはありません。

    プレゼントの応募は締め切らせていただきました。
    たくさんのご応募ありがとうございました。
    抽選の結果、当選された方には 11/11 頃に案内メールをお送りいたします。
    (2013/11/01)

    記事の内容を 5 点満点で評価してください。
    1 点 2 点 3 点 4 点 5 点
    記事に関するコメントがあれば併せてご記入ください。

    ©2013 OGIS-RI Co., Ltd.
    Prev Index
    Prev Index