ObjectSquare [2013 年 5 月号]

[技術書紹介]


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

テスト駆動開発による組み込みプログラミング


~C言語とオブジェクト指向で学ぶアジャイルな設計~

James W. Grenning(著)、蛸島 昭之(監訳)、笹井 崇司(訳)
オライリー・ジャパン (2013/4/24)
388ページ
ISBN978-4-87311-614-3
原著:Test Driven Development for Embedded C


はじめに

本書は 2012 年 9 月号で 紹介記事を掲載した「Test Driven Development for Embedded C」の翻訳書です。本書に関わった方々がどういう思いで出版に取り組んできたか多くの人に知っていただきたいと思い、オライリージャパン編集者の高さん、推薦者の平鍋さん、監修者の蛸島さんの許可を得て、翻訳書のあとがき・まえがき・目次を掲載させていただきました。この場を借りて感謝いたします。

なお、原著者の James W. Grenning 氏が 5 月末に来日し、Agile Japan 2013にてキーノート・ワークショップ、そして公開トレーニングを実施されます。本書の内容にご興味のある方はご参加ください。

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


日本語版まえがき(書籍より抜粋)

アジャイル開発は組み込みでは使えないのでは?

こんな風に考えて本書を手に取った方が多いのではないだろうか。「アジャイルソフトウェア開発」という手法が日本でも広まってきている。顧客とともに変化する要求に追従しながら、短期間の反復(イテレーション)の中で製品を開発する手法だ。この手法は、組み込みソフトウェアの開発では利用できない、と思われている方も多いと思う。確かに。組み込み開発の現場は例えば Web サービスの開発とは違っており、ハードウェアとともにリリースされる、限られた資源で動作する、オブジェクト指向プログラミング言語が利用できない、などなど、アジャイル開発を導入する障壁が多い環境であることは間違いない。しかし、あきらめるのはまだ早い。

アジャイル開発の中には「テスト駆動開発」という、最も技術よりのプラクティスが含まれている。この手法はアジャイル開発の中でも最も早く知られるようになったXP(Extreme Programming)の父、ケント・ベックが作った。原理は簡単で、「失敗すユニットテストを書いてから、それをパスする製品コードを書く」というもの。これを繰り返して製品コードを成長させる。ケント・ベックと後に Eclipse 開発環境のリーダーとなるエリック・ガンバは、Java 言語でユニットテストツール JUnit を開発し、「テスト熱中症」 という記事で「これまでテストが嫌いだったプログラマが、テスト駆動開発を行うことでテスト好きに感染する」と書いた。今日では幅広いプログラミング言語に同様のツール(xUnit と呼ばれる)が存在するまでに普及した。

本書は、C 言語を使う組み込み開発の現場用に書かれた、テスト駆動開発の具体的な指南書である。そう、C 言語で!テスト駆動開発はオブジェクト指向言語が前提となることが多かったのに、本書は組み込み開発現場での C 言語を前提としている。この手法をあなたの組み込み開発に取り込めないだろうか?きっと試す価値はあるはずだ。組み込み開発のソフトウェア開発現場では、なかなか障害が収束せず、出荷ぎりぎりになってデバッグに追われる日々を強いられる状況も多い。そして、みんなそんな状況から逃れたいと思っている。ジェームズは、その 1 つの答えになるのがテスト駆動開発だと信じて本書を書いた(私もそう考えている一人だ)。チームや個人が自らのソフトウェアの品質をよりよくしたい、と考えているなら、ぜひすぐにでも試しててほしい。組み込み開発の現場で日々ソースコードと格闘している、まさに、あなたのための手法だ。

私は著者のジェームズ W. グレニング氏と数年来交流している。昨年は彼の開催するテスト駆動開発のワークショップにも参加し、実際に手を動かして C 言語のコードを書いた。そこで気づいたのは、彼のとても真剣な組み込みソフトウェア開発に対する情熱だ。彼は、ワークショップが始まる前に、参加者の全員に一人ずつ自己紹介をしながら資料を手渡していた。そして、ワークショップがはじまると、静かに、しかし熱く、組み込み開発の現場の悲惨な現状を語った。彼も組み込み開発の現場を変えたいと考えている。そして、その鍵がテスト駆動開発にあると信じている。

よく誤解されるのだが、テスト駆動開発は「テスト手法」ではない。ユニットテストをうまく利用して、よりよい設計を導くための手法である。この手法で開発されたソースコードは、「テストしやすい設計」になると同時に、動くユニットテスト群が同時に開発される、という優れものだ。このユニットテスト群は回帰テストで利用されるとともに、将来の設計変更を安全に導く基礎になる。私が本書で特に気に入っているのは、ボブおじさんこと、ロバート C. マーティンのソフトウェア設計原則である「SOLID 原則」にも章を割いて解説している点だ。テスト駆動開発は、テストしやすい設計を導く設計手法であり、ソフトウェア設計原則と不可分なのである。本書を読むことで、テスト駆動開発だけでなく、よい設計とは何か、というより大きな問題を考えるきっかけにもなるだろう。

さあ、本書を手に、すぐに試してみてほしい。テスト駆動開発のよさに感染するだろう。そして同時に疑問を抱くだろう。どうやったら自分の現場に適用できるか、と。そしたら、チームの仲間と勉強会をはじめてみてほしい。開発の仲間を作ることが、ソフトウェア開発の現場をよくすることの第一歩だから。組み込み開発のやりがい、そして楽しさ、を取り戻そう。

株式会社チェンジビジョン
平鍋 健児
2013 年2 月

TOP ページのトップへ戻る


監訳者あとがき(書籍より抜粋)

本書について

本書は、2011 年4 月に出版されたJames W. Grenning 著『Test-Driven Development for Embedded C』の全訳です。本書は、おそらく世界で初めて、そしてこの翻訳が出版される現在においても唯一の組み込み開発環境におけるテスト駆動開発について書かれた本です。

本書の原書が出版された 2011 年は、著者のグレニング氏も起案に参加したアジャイルマニフェストが宣言されてからちょうど 10 年の節目の年でした。その 10 年の間にアジャイル開発に端を発する多くの設計手法やプラクティスが生まれ、ソフトウェア開発を発展させてきました。本書のメインテーマであるテスト駆動開発もそうしたうちの 1 つです。しかし残念なことに、それらの有効な設計手法やプラクティスの多くは Web サービスやエンタープライズ系の開発では大きな広がりを見せましたが、組み込み開発ではまだ一般的とは言えないのが現状です。

このように組み込み業界だけが取り残されてしまった原因として、組み込み開発環境の特殊性があるのではないかと私は考えています。コードサイズと実行速度が重要となる組み込み開発では、手続き型言語のC が今でも主流言語として使用されています。その一方で、テスト駆動開発や設計改善に関する書籍のほとんどがオブジェクト指向言語を前提として書かれているため、そのままではうまく組み込み開発に適用することができません。

実際、私自身も C によるテスト駆動開発を行うために、多くの書籍を参考にしながら試行錯誤してきました。しかし、もっと C にフォーカスした書籍はないものかというもどかしさを感じていました。本書の原書である『Test-Driven Development for Embedded C』が出版されたのはまさにそんな折でした。

さっそく購入して読み始めてみるとすぐに、組み込み TDD に関する有益な情報が詰まった期待通りの本だと思いました。ところが、さらに読み進めていくうちにその感想は間違いだったことに気づきました。なぜなら、ボブおじさんが「まえがき」で述べているように、本書は「TDD について多くのことを語っているが、それ以上にもっと多くのことを語っている」からです。

本書では、「テスト駆動開発」と「テストしやすいす柔軟な設計」という大きく分けて 2 つのテーマについて解説されています。「Ⅰ部 TDD を始めよう」と「Ⅱ部 コラボレータのあるモジュールをテストする」では、制約のある組み込み開発環境で TDD を行うためのノウハウが余すところなく語られています。そして続く「Ⅲ部 設計と継続的改善」では、SOLID 原則、リファクタリング、レガシーコードへのテストの追加が取り上げられています。これら 3 つの章では、『アジャイルソフトウェア開発の奥義』[Mar02]、『リファクタリング』[FBBO99]、『レガシーコード改善ガイド』[Fea04] から抽出された重要なエッセンスが簡潔に、しかし抜け漏れなく取り上げられています。これらの設計原則やテクニックは、もともとはオブジェクト指向を前提に考えだされたものです。それをどのように C に適用するかが見事に示されているのには感動すら覚えます。すぐれた設計原則をC で実装するには、高度な関数ポインタの利用が必要になるため、一度読んだだけではコードを理解するのは難しいかもしれません。ぜひ腰をすえてじっくりとコードを追いかけてみてください。そうすればきっと、私が感じたのと同じ感動があなたにも味わえるはずです。

もしすでに本書をすべて通して読まれたのであれば、私と同じく非常に多くのことを学ばれたことでしょう。しかし、ただ知っていることと実践できることは違います。ぜひ、本書を片手にテスト駆動による開発を始めてみてください。きっとあなたもすぐにテストに夢中になり、テストからのフィードバックを心待ちにする「パブロフのプログラマ」になるでしょう。

謝辞

本書の監訳にあたっては、非常に多くの方にお世話になりました。おかげさまで初めての監訳作業を無事終えることが出来ました。改めてお礼申し上げます。

柴田芳樹さんには、面識がないにもかかわらず「技術書の翻訳本を出版するためのプロセスを教えてください」という突然のメールに親切にご回答いただき、本書の編集者である髙恵子さんをご紹介いただきました。髙さんには、本書の価値にご賛同いたき、翻訳の企画を快く引き受けていただきました。お二人がいなければこの翻訳が出版されることはありませんでした。

原田騎朗さんには、原書の読書会を主催されていた大西洋平さんをご紹介いただきました。翻訳の企画が無事に通ったのは、本書自身の内容の良さもさることながら、読書会の存在によるところも大きかったと思います。

平鍋健児さんには、自著の執筆がお忙しいにもかかわらず、本書の魅力が大変よくわかるすばらしい「日本語版まえがき」を書いていただきました。

笹井崇司さんには、監訳のもととなる翻訳原稿をいただきました。監訳原稿のレビューには、前述の大西さんほか、島田浩二さん、高橋明さん、加藤洋平さん、安部聡志さん、井芹洋輝さん、浦川隆之さんにご協力いただきました。訳者の笹井さん、そしてレビューアの皆さんと活発に議論することで、多くのことを学ばせていただきました。本書が読みやすいと感じていただけたのであれば、それは訳者とレビューアのみなさんの功績によるものです。もし本書に誤りがあれば、それはすべて監訳者である私の責任です。

大学時代のルームメイトの Darin Allen には、見慣れない英語のイディオムなどについて教えてもらいました。著者のグレニング氏には、原書のコードや意味の取りにくい文についての質問に丁寧な回答をいただきました。その豊富な知識と経験を書籍というかたちで共有してくれたこととあわせて感謝します。

本書の監訳作業には多くの時間と、家族からの惜しみない協力を必要としました。いつでも私を理解し支えてくれる妻の彩年と、その愛くるしい笑顔でいつも私の心を癒してくれる娘の優希、そしてまだ見ぬ 4 人目の家族に心からの感謝を贈ります。また、よい教育を受けさせてくれた、両親と祖母にも同じく感謝のことばを贈ります。

最後に

ソフトウェア開発の現場は、新3K 職場などという不名誉な名前で呼ばれることがあります。たしかに、日々の開発の中では苦しいこともたくさんあります。しかし、ソフトウェア開発は本来、楽しいもののはずです。そして、ジャック・ガンセルの「まえがき」にもあるように、「それこそが、私たちの多くがこの分野に足を踏み入れた、そもそもの理由」のはずです。

私が『Test-Driven Development for Embedded C』を日本の組み込みソフトウェア開発者にもぜひ読んでもらいたい思ったのは、テスト駆動開発がもっと広まれば多くの人がソフトウェア開発の楽しさを取り戻せると考えたからです。本書が一人でも多の方に読まれることで、日本の組み込みソフトウェア開発の現場がより良くなり、ひいては皆さんの人生がより充実したものとなれば監訳者としてこれ以上の喜びはありません。

2013年3月19日
蛸島 昭之

TOP ページのトップへ戻る


目次(書籍より抜粋)

本書への賞賛の声
日本語版まえがき
ジャック・ガンセルによるまえがき
ロバート・C・マーティンによるまえがき
はじめに

1章 テスト駆動開発

1.1 なぜTDDが必要か?
1.2 テスト駆動開発とは何か?
1.3 TDDの特性
1.4 TDDのマイクロサイクル
1.5 TDDのメリット
1.6 組み込みにとってのメリット

I部 TDDを始めよう

2章 テスト駆動ツールと約束事

2.1 ユニットテストハーネスとは何か?
2.2 Unity:C専用テストハーネス
2.3 CppUTest:C++ユニットテストハーネス
2.4 ユニットテストはクラッシュする
2.5 4フェーズテストパターン
2.6 まとめ
2.7 練習問題

3章 Cモジュールにとりかかる

3.1 テストしやすいCモジュール
3.2 LEDドライバは何をするのか?
3.3 テストリストを書く
3.4 最初のテストを書く
3.5 内部の前にインターフェイスをテスト駆動する
3.6 インクリメンタルな進捗
3.7 テスト駆動開発者のステートマシン
3.8 テストはFIRST
3.9 まとめ
3.10 練習問題

4章 完了までの道のりを確かめる

4.1 シンプルなところから成長させる
4.2 コードをきれいに保つ――進みながらリファクタリング
4.3 完了するまで繰り返す
4.4 「完了」を宣言する前に一歩戻る
4.5 まとめ
4.6 練習問題

5章 組み込みTDD戦略

5.1 ハードウェアボトルネック
5.2 デュアルターゲットのメリット
5.3 デュアルターゲットテストのリスク
5.4 組み込みTDDのサイクル
5.5 デュアルターゲットの非互換性
5.7 急がば回れ
5.8 まとめ
5.9 練習問題

6章 そうは言っても

6.1 時間がない
6.2 コードを書いてからテストを書いてはいけないのか?
6.3 テストをメンテナンスする必要がある
6.4 ユニットテストがすべてのバグを見つけられるわけではない
6.5 ビルドに時間がかかる
6.6 既存のコードがある
6.7 メモリに制約がある
6.8 ハードウェアとやり取りする必要がある
6.9 CをテストするのになぜC++テストハーネスを使うのか?
6.10 まとめ
6.11 練習問題

II部 コラボレータのあるモジュールをテストする

7章 テストダブルの導入

7.1 コラボレータ
7.2 依存関係を断ち切る
7.3 いつテストダブルを使うか
7.4 Cでだますにはどうするか
7.5 まとめ
7.6 練習問題

8章 プロダクトコードをスパイする

8.1 ライトスケジュール機能のテストリスト
8.2 ハードウェアとOSとの依存関係
8.3 リンカによる置き換え
8.4 テスト対象コードをスパイする
8.5 時計をコントロールする
8.6 0で動かしてから1で動かす
8.7 複数で動くようにする
8.8 まとめ
8.9 練習問題

9章 テストダブルの実行時バインディング

9.1 ランダムなものをテストする
9.2 関数ポインタを使ってフェイクする
9.3 スパイを外科的に埋め込む
9.4 スパイを使って出力を検証する
9.5 まとめ
9.6 練習問題

10章 モックオブジェクト

10.1 フラッシュドライバ
10.2 MockIO
10.3 ドライバをテスト駆動で開発する
10.3 ドライバをテスト駆動で開発する
10.4 デバイスのタイムアウトをシミュレートする
10.5 それだけの価値があるか?
10.6 CppUMockを使う
10.7 モックを生成する
10.8 まとめ
10.9 練習問題

III部 設計と継続的改善

11章 SOLIDで柔軟でテストしやすい設計

11.1 SOLID原則
11.2 SOLIDな設計モデル
11.3 要求の進化と問題のある設計
11.4 動的インターフェイスを使って設計を改善する
11.5 型による動的インターフェイスを使って柔軟性を高める
11.6 どれだけ設計すれば十分なのか?
11.7 まとめ
11.8 練習問題

12章リファクタリング

12.1 ソフトウェアの2つの価値
12.2 3つの重要なスキル
12.3 コードのにおいと改善方法
12.4 コードを変換する
12.5 でもパフォーマンスとサイズは?
12.6 まとめ
12.7 練習問題

13章 レガシーコードにテストを追加する

13.1 レガシーコードの変更ポリシー
13.2 ボーイスカウトの原則(Boy Scout Principle)
13.3 レガシーコードの変更手順
13.4 テストポイント
13.5 構造体の2段階初期化
13.6 クラッシュさせて成功させる(Crash to Pass)
13.7 仕様化テスト(Characterization Test)
13.8 サードパーティー製コードのための学習テスト
13.9 テスト駆動によるバグ修正
13.10 戦略的テストを追加する
13.11 まとめ
13.12 練習問題

14章 テストのパターンとアンチパターン
14.1 「だらだら続くテスト」アンチパターン
14.2 「コピー、ペースト、少し変更、繰り返し」アンチパターン
14.3 「場違いなテストケース」アンチパターン
14.4 「テストグループ間の重複」アンチパターン
14.5 「テスト軽視」アンチパターン
14.6 「振る舞い駆動開発」アンチパターン
14.7 まとめ
14.8 練習問題

IV部 付録

付録A ホスト開発システム上のテスト環境
付録B Unityクイックリファレンス
付録C CppUTestクイックリファレンス
付録D 作成中のLedDriver
付録E OS分離レイヤーの例
付録F 参考文献

監訳者あとがき
索引

TOP ページのトップへ戻る


©2013 OGIS-RI Co., Ltd.
HOME HOME TOP オブジェクトの広場 TOP