2012/12/28

2012年の活動まとめ。初の勉強会主催、海外著者インタビュー記事公開、グローバルな技術系イベントで海外の人と交流、初の自著執筆など

今年の振り返り。
今年意識したことは以下。それなりにできたので満足です。

  • 自分の能力が最大限に発揮できる道と社会が発展する道がうまく交差するような場を見つける。頑張って楽しいと、社会に何がしかポジティブな影響を与えることを両立する。
  • 国境や母国語の違いを超えてグローバルに海外のエンジニアとも交流する。そのために日本語だけでなく英語でコミュニケーションする。

----

■1月

  • 2011年から検討してきた組み込みTDD読書会を告知しました。技術系の勉強会初のイベント主催です。
  • 最初に告知に反応してくれたのが著者James Grenning氏でした。来日予定あったJames氏が僕のツイートを発見し、「本読んでくれてありがとう。近々日本に行くから、会おうよ。日本の読者と話してみたいし。」とコンタクトを受けました。ちょっとびっくりですが、著者と読者を交えて座談会をしようと企画を練り始めます。

■2月


■3月


■4月

■5月

  • 組み込みTDD本の著者James氏の来日がキャンセルになり、日本人読者との座談会の企画もキャンセルになりました。でも、計5名が横浜に集い、JamesさんはアメリカからSkypeで参加してくださり、こじんまり短時間ではありますが、意見交換をやりました。まさかこんな展開になるとは思わなかったので感動しました^^
  • この時に、原田さんから紹介頂いた名古屋の組み込み開発者の方がわざわざ横浜まで来て座談会に参加してくださりました。この方が後に翻訳書の企画を出版社に通し、監修者になります。

■6 - 7月

  • 定例でTDDの読書会を開催したり、あとはJamesさんが来日キャンセルになったけど、いろいろ質問事項がたまっていたので、インタビューしようと企画しました。実施方法は悩みましたが、職場の方がAgile 2012に参加するから代理でインタビューしようかと言われたのでお願いしました。

■8月

  • インタビューの録音データをいただいたので、ここから自分がインタビューしたわけではないインタビュー音声のテープおこしが始まります^^; しんどいけどヒアリングは練習したかいもあってなんとかなりました。アジャイル開発をやるやらないに限らず、持続可能な開発をやる基盤としてTDDの可能性は感じていたので、やはりここはインタビュー記事をしっかり書いて公開したいなと思いました。僕だってたいしたことはできんけど、世の中の役には立ちたいという気持ちはあるからね。

■9月

  • Jamesさんのインタビュー記事を公開するに先立って、そもそも書籍がどういうものか認知度を上げる必要があるなと思い、書籍紹介の記事を公開しました。ニッチではあるけど、組み込み・テスト・アジャイルクラスタの間で本書の認知度が上がり始めます。
  • 5月に座談会でご一緒した方から翻訳書の企画通りました!との連絡あり、監修体制について議論を始めました。出版社からは早く市場に出したいとのことで、翻訳はプロが監修やレビューについては我々が責任をもってやるという役割分担をすることに。インタビュー記事があり、レビューどこではありませんでしたが、幸い翻訳原稿が届くのは少し後とのことでホットしました。

■10月

  • Jamesさんのインタビュー記事前編を公開しました。僕にとってアジャイルマニフェストは社会に出た時にすでに本に書かれた昔のできごとであり、そんな人間がアジャイルマニフェストの著者のインタビュー記事を書いていることに違和感を感じました。XP/アジャイル直撃世代の方がふさわしいのでは?と思いましたが、企画したのは自分だし、これを世に送り出すことは僕の使命だなと思い、通勤電車の中で何度も読み返しながら推敲しました。Jamesさんが話していた「アジャイルソフトウェア開発宣言で我々が語っているのは人の重要性です。」という言葉を何度もかみしめました。
  • この辺から翻訳書監修チームでの会合が始まり、おおまかな体制が決まりました。

■11月

  • Jamesさんのインタビュー記事後編を公開しました。アジャイル・テスト・組み込みクラスタJamesさんの話していることは、仕事の中で培ってきた価値観にすごい合う印象でうんうんそうそうと納得しました。テクニックというよりアジャイルのマインドを理解し始めました。
  • Ultimate Agilist Tokyoに参加。これまでのTDDの活動についてプレゼンしました。短い時間ながらも、大きな規模のイベントで話する側に回れて満足感を得ました。
  • この辺から翻訳原稿が届き始め、ビューが本格的にスタートします。

■12月

  • Global Day of Coderetreatのファシリテータ研修に参加。テレビ会議をつないで4カ国から6名の人が研修に参加。受講者のうち一人がJamesさんの元クライアントであり、中国語版翻訳者の同僚であることが分かりびっくり!世界はせまい。
  • 本番ではJava/JavaScript/Ruby/Scalaでペアプロをやり、大満足。TDDのリズム感は楽しいな!と実感。TDDが血肉になりつつあるのを感じました。
  • 書き忘れてたけど、1年通して自著を書いてて、今ようやくゲラチェック中^^; 来年初めには出版です!

2012/12/09

世界規模のプログラミング教育イベント Global Day of Coderetreat 2012 は楽しかった!!

2012/12/9(日)にGlobal Day of Coderetreatに参加してきました。私は昨年のGlobal Day of Coderetreat以来、1年ぶり2回目の参加です。

このエントリでは、
  • Coderetreatとはどういうイベントなのか?
  • Global Day of Coderetreatとはどういうイベントなのか?
  • Coderetreatをどう楽しむか?学びを有意義にするか?
をお話したいと思います。

■参考


■Coderetreatとはどういうイベントなのか?

まず、告知ページを一見しただけでは、「プログラマが1日中ひたすらペアプロをするイベントかな?」と思われるかもしれませんが、それだけではありません。

Coderetreatはプログラマのretreat(避難所とか静養所という意味)です。プログラマという職業の人は、普段の業務では常にリリースで追われていて、プログラミング、設計、テストなどの基礎テクニックをあらためて習得する機会に巡りあうことは少ないでしょう。納期とは無縁な場所で基礎テクニックを習得する機会を与えるのがこのイベントの趣旨です。

特徴としては以下の通り。
  • 題材は「コンウェイのライフゲーム」です。人工生命のシミュレーションをするやつですね。


  • 45分で1セッションのペアプログラミングを6回繰り返します。ペアは毎回変更します。
  • セッション終了時にはコードを全て削除し、毎回、ゼロからライフゲームというゲームのコードを書いていきます。
    • これは新しい設計アイディアに挑戦させる狙いがあるそうです。
    • 実際、セッションを経る度に、ファシリテータが設計制約を課してくるので、それを乗り越えるたびに普段と違った発想で設計する強制力が働きます。
  • ペアプログラミング、TDD、オブジェクト指向設計といったプラクティスを習得する機会が得られます。
    • 手取り足取り教えられるわけではありませんが、やり方はファシリテータが説明しますし、ペアの人が詳しければ実地で教えてもらえます。
  • プログラミング言語が限定されていないので、やり方によってはいろんな言語の学習機会が得られます。
    • どの言語でコードを書くかはペア次第なので、ペアの話し合いの結果によってはあまり馴染みのない言語で書く場合もあります。私は普段、C/C++/Python/VBなど使っていますが、今回は「普段使ってない言語を使う」というポリシーなので、相手の特異なJava/Ruby/Scala/JavaScriptを使いました。
  • ちなみに公式イベントは昼食とおやつはスポンサー持ち!


■Global Day of Coderetreatとはどういうイベントなのか?

今回は単にCoderetreatではなく、頭に「Global Day of」とついています。つまり世界中で同時に開催されているわけです。実際公式サイトを「Global Day of Code Retreat 2012」で検索すると、ものすごい量の開催告知が出てきます。少なくとも50都市以上で開催されているのではないでしょうか?

今回、日本ではおそらく東京、大阪、福岡、愛媛で開催されていて、会場ではGoogle Hangoutというツールを使ってリアルタイムでお互いの状況が分かるようになっていました。たしか、海外の会場ともつながっていたと思います。昨年はインドと中継して、「How are you doing?」なんてやり取りする場面もあり、なかなかおもしろかったですが、今年は海外とのやり取りがなくて物足りなかったです^^;

■Coderetreatをどう楽しむか?学びを有意義にするか?

せっかく丸一日使うのだから十分楽しみ、有意義な時間にするべきだと思います。楽しめて有意義にするためには、どうしたらいいんでしょう?普段とは違うやり方に取り組んだり、他の人から違う考え方を学び、視野を広げることだと思います。

今回、私が意識したのは以下です。

○普段と違う言語・フレームワークを使う

私は組み込みソフトウェア開発者なので、主に業務で使うのはC/C++です。開発環境のマクロを組む時にVB、スクリプトを開発する時にPythonなどを触る機会がありますが、他の言語を触る機会はありません。

しかし、他の言語の方がプロダクトコードやテストコードを書きやすい言語仕様やテスティングフレームワークになっている場合があり、他の言語のやり方を学ぶ良い機会になります。

今回一番良かったのはRubyとそのテスティングフレームワークのRSpec。直感的に書いたコードがだいたい動く感じが非常に気持良いです。そして、RSpecのdescriptionやcontextという要素でテストコードを構造化していくやり方は非常に頭が整理されているようで良かったです。

普段の言語にはそのまま持ち込むことはできないケースが多いと思いますが、エッセンスを咀嚼して普段の開発に活かすことはできるかもしれません。

○普段と違う設計をする

今回のイベントの趣旨は、業務ではできない体験をすることなので、普段とは違う考え方で設計をやるのが一番でしょう。普段、モデリングして、オブジェクト指向的に設計していない人はオブジェクト指向にチャレンジする機会です。私はオブジェクト指向設計に慣れているので、あまり慣れていないペアの時はモデルを書きながら、オブジェクト指向設計をリードして、「なるほど、こんな風に考えるんですね。勉強になりました。」とペアの方に言われて嬉しかったです。

また、for文を使わないようにするという設計制約を乗り越える過程で、普段あまり使わない言語要素の map & filter で簡潔にコードを書く方法を教えてもらったりしました。これは勉強になりました。

○理想的な形で技術プラクティスにチャレンジする

1セッション45分で非常に短いのでちょっと焦りますが、仕事と違って完成しなくても上司とお客さんに怒られたりしないので、理想的な形で試してみたい技術プラクティスに取り組んでみるといいのではと思います。

TDDって知識として知ってはいるけど、やってみたことはないという人は絶好の機会なので本に書かれているTDDをやってみてみて下さい。きっちり歯車が噛み合っている状態でバグを発生せずに少しずつ前に進んいく感覚は非常に気持が良いと思います。

今回、私がやってみたのは「実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる (Object Oriented SELECTION) 」で紹介されている「二重のテストループ」です。翻訳者の和智さんがブログエントリ「テスト駆動開発の進化」で紹介されています。

coderetreatで起こりがちなのが部品となるクラスの完成度が上がっていったけど、ライフゲーム全体は殆どできずに終わるというケースです。本番のシステム開発でやるとダメパターンですね。

これをアジャイル開発のように常に全体が動くようにするために、ユーザ視点で意味のあるシナリオ1つに対して受け入れテストを書き、内部をテスト駆動で書いていきます。これをやると、特定のシナリオに対して動くシステムが早めにでき上がって確認できる上に、アーキテクチャ設計から細部の設計・実装までひと通り通しでやってみて気づくような設計判断が早め早めに分かるというメリットがあります。

実践テスト駆動の題材に比べると細かいテストコードを書いていましたが^^; 雰囲気だけ分かって良かったです。

○振り返りで面白かったネタをシェアする

セッションの最後にペアで振り返りし、その時の付箋をボードに貼って、皆と体験をシェアします。基本的にはファシリテータの方が全体にシェアすべきことを拾ってくれますが、特にこれは!と思う内容は付箋を貼る時に皆に話してみると取り上げてもらえる確率も上がると思います。


○海外の人と交流する

そして、今回は global day ということで、ハッシュタグ #gdcr12 で世界中の人がいっせいにつぶやいていました。私も #gdcr12 に対して質問してみたのですが、J. B. Rainsberger(@jbrains)というヨーロッパ系カナダ人のコンサルタントの方から即座にコメントがありました。


ちなみにcoderetreat.orgのActivity CatalogというページにCoderetreatでよくやれているアクティビティの紹介が書かれていて、そこに「Verbs Instead of Nouns」と書かれていたので、何ですか?と書かれたので質問しました。回答は「Name your modules or classes with verbs instead of nouns(モジュールやクラスの名前に名詞ではなく動詞を使いなさい). It affects how I divide responsibilities(このやり方は責務の分割に影響します).」とのこと。どう影響するのかは教えてもらえませんでしたが、ビデオを見つけたので後で見ようと思います。


Verbs Instead of Nouns - Next Up at Coderetreat from Coderetreat on Vimeo.

■最後に

本エントリでは、Coderetreat自体とその楽しみ方を紹介してきました。このイベントはかなりよく練られたイベントで、世界中でやられているのも頷ける内容です。

なにより、違う分野の人同士が、それも国境を超えて、切磋琢磨する場があるといいうのがすこい素晴らしいと思います。異業種の人にも紹介してみましたが、そんなイベントがあるなんて!と驚いていました。

今後も定期的に開催されると思うので、今後とも参加したいと思います。
#やっぱコード書きたいからなるべく一般参加者で・・・^^;

2012/12/01

Ultimate Agilist Tokyoに参加してきた

先日のブログにも書いたとおり、Ultimate Agilist Tokyoというイベントに参加してきました。ここでは聴講した他の方の発表についてレポートしたいと思います。


細谷 泰夫さん:アジャイル×テスト開発を考える



http://togetter.com/li/407192
http://yasuo.hatenablog.com/entry/2012/11/18/225159

アジャイル開発において成果物の品質を早期に確定させるためにどのようなテストを計画していくかについて発表されていました。2000年代からXPの推進者であった細谷さんが10年近くにわたって他部門の方(品質保証?)の方とアジャイル開発の導入について議論してきた経験が反映されている発表だという印象を受けました。

細谷さんによると、アジャイルに批判的な人の中には「品質の確定性」を気にしていて、「頻繁に変更が加わって品質が安定しなさそう」と言う方がいるのだそう。おそらくは、頭の中に理想的なフォーターフォール(つまり目標の品質に対して直線的に向かっている状況)を思い描き、それと対比して、頻繁にリリースをしながら徐々に目標の品質に向かうアジャイルに対してネガティブな印象を持っているのではないか?という話です。

しかし、細谷さんはプロセスの違いが問題ではなく、
  • 利害関係者の間でどうやって目標の品質を共有するのか?
  • その目標の品質をどうやって達成するのか?
が大事だと説明しました。

前者については、コンテキストに依存するので計画の段階で合意する必要があるようです。後者については、アジャイル開発をやると早期に開発とテストが協調し始めて、テストコミュニティでよく話題に挙がる「Wモデル」と同じ効果が得られるのだそうです。このWモデルとは、V字モデルの左側(要求分析・基本設計・詳細設計・実装)と並行してテスト設計を始める手法です。

そして、早期に開発とテストを協調させる上で重要になるのが「テスト計画」のようです。テスト計画としては以下を考えるとよさそうです。
  • いつ、どんな品質を確定させたいか?
  • 複数のテストの粒度をどう組み合わせるか?(ユニット、インテグレーション、受け入れ、etc)
  • どう自動化するか?
  • 誰からどのようにフィードバックを受けるか?
このテスト計画をやる上での知見については、アジャイルプロセス協議会のテスト・レビューWGでヒアリングしているとのこと。私はテスト計画をやった経験ではないのですが、開発において重要な分野だと思うので少し勉強したいと思います。WGの今後の成果に期待ですね。※こんなこと書くと、お前が参加して貢献しろと言われそう :)


前川 直也 さん: 家電商品を開発してみると目からウロコなAgileの本質

http://togetter.com/li/407795

本職は家電メーカーのPMである前川さんが、大規模開発でアジャイル開発を実践する上での体験を話されていました。昨今のニュースで見聞きしているのと同じで、やはり家電開発はかなりしんどい状況におかれているようです。かなり際どい話だったので資料は非公開のようです^^;

円高、新興国メーカーの台頭、消費者の趣向の変化など社会が急速に変わっていく中で、市場に受け入れてもらって、企業が生き残っていくには、どの分野でどういう価値を提供して利益を得ていくかはかなり深刻な問題です。昨今のニュースを見る限りでは、次から次へと起こる変化に対応していくうちに、開発規模は膨れ上がり、他社との価格競争は激化し、疲弊していっているのが現状だと思います。

先日の主要エレクトロニクス企業の決算を見る限りでは、もはや一度敗北してしまって、今焼け野原の中にたっているということを認めてしまった方が良いのかもしれません。そこから、もう一度、我々の事業は何なのか?を見つめなおして再スタートを切るべきなのかも。これは家電企業だけの話をしているわけではなく、私のいるSI業界も似た状況に立たされると思っています。


そこで、前川さんが話していたアジャイルの本質(おそらくは「現場、人、お客さんの価値提供を重視すること」だと思います)の重要性が増してきているのだと思います。そして、前川さん自身は主要エレクトリにクス企業の創業者の格言の中にアジャイルの本質を再発見しているそうです。戦後の焼け野原の中でエレクトロニクス企業が次々と立ち上がったように我々も立ち上がる時期がきています。

たぶん、SI業界もタイミングが少し遅れてきっつい状況が来るのだと思うので、今から準備しておくと良いでしょうね。


原田 騎郎 さん:Can you keep doing that? <No-Bull Know-How>



こちらは講演はなしです。「No-Bull Know-How」というのはAgile 2012などでも実践されているセッションのスタイルの一つだそうです。有識者が一人壇上に上がり、聴講者が質問を投げかけ、それに対して有識者がアドバイスします。そのアドバイスを聞いた他の聴講者がアドバイスが妥当かどうかを判断するというものです。

@daipresentsさんのブログにも紹介されているのでぜひ読んでみて下さい。
Agile 2012「No-Bull Know-How Stage」はアジャイル著名人とディスカッションできるステージ

私自身は個々の質問が、というより、このスタイルに興味を持ちました。一般的に、日本で講演スタイルを取ると講演者が質問して、残り数分で質問の時間に入りますが、あまり質問できずに終わることが多いと思います。そして、スキマ時間に1対1で質問する人も多いと思います。

しかし、もっと講演者と聴講者が対話的になることで生まれる価値みたいなものもあるのでは?と思います。あるいは、「あ、○○さんいた。○○さんの方が詳しいからちょっと話してよ。」みたいな無茶ぶりすることで、別の視点が引き出せたり。指名された人はえーって驚きそうですが。

これまで、このスタイルはあまり一般的ではなかったですが、イベントでこういう対話的なセッションが増えてもいいなと思っています。


井芹 洋輝 さん:テストを支える。テストを育てる。



Test Driven Development for Embedded C読書会でご一緒した井芹さんの発表です。発表の内容は、現状のテストで起きる問題を「テストを育てる・支える」という視点で解決しようというものです。問題というのは以下のようなもの。
  • テストの保守性が低くて、変更の度に生産性が下がる。
  • テストの要求を見逃してしまったり、目的が異なるテスト同士が阻害しあったりする。
  • テスト全体として整合性がとれておらず、穴があったり冗長だったりする。
それに対する解決作は資料で詳しく解説されているので、そちらを参照していただきたいと思います^^; かなり情報量が多くて理解しきれていません。。

「育てる」の方は、ソフトウェア開発における要求分析やアーキテクチャ設計でよく言われるような話をテスト全体に適用しているような印象を受けました。

「支える」の方は、検討したテストが破綻しないように効率化したり、保守性を向上したりする話だと思います。一旦、作り上げた後もメンテナンスが走るのは世の常なのでどうフォローするかも重要な視点だと思います。

特に「育てる」の方で挙がってたテストの全体の計画については自分が計画する役割ではなかったとしても、その視点は持っていた方が良いと思うので、たびたび引用されていた「ソフトウェア・テスト PRESS 総集編 」は購入して読んでみようと思います。




最後に

おそらく、遊びを除いて、イベント参加はこれが今年最後だと思います。今回のイベントは自分が話す側だったこともあって、非常に有益な場だと思います。アウトプットする側の方が良いインプットも得られるというのが私の持論です。今、裏でいろいろと準備をしているので、またイベント参加の際は話す側に回って皆さんに情報提供したいと思います。いい話をできるように頑張ります!

2012/11/17

2012年は #tdd4ec に始まり、#tdd4ec に終わった。来年もいろいろあるよ。きっと。

11/17(土)Ultimate Agilist Tokyoにて、この1年間の活動を締めくくる内容の発表を10分ほどしました。イベントでしゃべるの初めてなので、緊張して疲れました。LT職人の皆さん、ただものじゃなかったです。

今年を振り返ると、やっぱ年初にJames Grenningさんが若手芸人ばりの軽いノリでコンタクトをとってくれたのがきっかけで、いろいろな話が展開をしたのが良かったと思います。その後、何十とメールをやりとししたり、インタビュー原稿を書いたりして、本に書いているノウハウ的なものだけじゃなくて、TDD実践者の視点いろいろと見た気がします。多少が世界が広がったとおもいます。この成果は来年春の書籍出版や、イベントの開催で見せたいです。

あー、今まで英語勉強してから、いろいろ対応できて良かった^^今後とも海外の技術者とも交流していこうと思います。

そして、1年間支援していただいた皆様ありがとうございました。今後ともよろしくお願いします。

■記事



■発表
自分のコミュニティを始めてみませんか? @ Ultimate Agilist Tokyo



■読書会 開催告知およびまとめ

○第1回 2/5:第2章 Test Driving Tools and Conventions 、第3章 Starting a C Module 
○第2回 3/4:第3章 Starting a C Module、第4章 Testing Your Way to Done
○第3回 4/22:第5章 Embedded TDD Strategy、第6章 Year, but…
○ペアプロの回 第1回 5/6
○第4回 6/3:第7章「Introducing Test Doubles」、第8章「Spying on the Production Code」
○第5回 7/7:第9章「Runtime-Bounded Test Doubles」、第10章「The Mock Object」
○第6回 8/19:第11章「SOLID, Flexible, and Testable Designs」、第12章「Refactoring」
○第7回 10/6:第12章「Refactoring」、第13章「Adding Tests to Legacy Code」
○第8回 11/4:第13章「Adding Tests to Legacy Code」、第14章「Test Patterns and Antipatterns」、第15章「Closing Thoughts」

2012/09/23

Boot CampでMacbookにWindowsをインストールしたらMax OSが起動しなくなった時の対処

先日、Boot Campを使ってMacbookにWindowsをインストールしたら、PC起動時にWindowsが起動するようになり、Mac OSが起動できなくなりました。

あれ困ったぞと思って原因と対処方法を調べました。

環境

減少が発生したMacbookはこんな感じ。

  • Mac
    • ハード:2008年モデルのMacbook
    • OS:Mac OS X 10.7.4 (Mountain Lion)
  • Windows
    • OS: Windows 7

原因


  • デフォルトの「起動ディスク」がWindows側になっていた。

対処法


  • 起動時にoptionキーを押し続け、起動する「起動ディスク」を選択する。
  • デフォルトでMac OSを起動したい場合は、以下の手順でデフォルトの起動ディスクをMac側にしておく。
    • システム環境設定 → 起動ディスクを開いて、「Macintosh HD」を選択する。

参考

起動時のショートカットは覚えておくと便利そうです。

2012/07/14

組み込みTDDにおける関数ポインタ置換とモックオブジェクトの導入について


先週末、組み込みTDD読書会第5回をやりました。
内容は以下の輪読およびディスカッション。

  • 第9章 「Runtime-Bounded Test Doubles」
  • 第10章「The Mock Object」
#当日のやり取りはtogetterにもまとめていますので、そちらも参照ください。

第9章 「Runtime-Bounded Test Doubles」

C言語でプロダクトコードを実装する場合、依存先モジュールをTest Doublesに置換する方法として、プリプロセッサ、リンク、関数ポインタがあります。第8章で紹介されていたリンク時置換は実行時に関数を置き換えることができず、自由度は低いというデメリットがあります。テスト実行中に、あるときはプロダクトコード、またあるときはTest Doublesに置き換えたい場合は、第9章で紹介されている関数ポインタ置換が有効です。

ただし、ディスカッションの中で関数ポインタとプリプロセッサはコードの可読性を下げる副作用があり、多用しない方がいいという意見が挙がりました。そして、書籍内ではほとんどプリプロセッサ置換の話は出てこず、著者はプリプロセッサ置換はあまり好きじゃないのかもしれません。

第10章「The Mock Object」

第10章は、組み込み業界だとなじみの薄いモックオブジェクトについて。
題材は実在するフラッシュメモリのデバイスドライバです。フラッシュに限らず、デバイス入出力は以下の理由でハードウェアと統合する前にモックオブジェクトを使った品質を確保する手法が有効なのだそうです。


  • 詳細なプロトコルに従って書き込み・読み出しをするテストは、通常のテスティングフレームワークでテストしづらい。
  • 本物のデバイスではテストできないケースがある。(例)特に例外系などは再現できない場合がある。


10章の大半はC言語でモックオブジェクトを実装する方法について解説が割かれています。一方で、C++のモッキングライブラリCppUMockやC言語のモック生成ツールCMockなども紹介されています。

たいていの場合、モック自身が複雑になると思うので、解説を見る限りでは自作モックはモック自身のちゃんとしたテストが必要な印象を受けました。
#ライブラリの品質が保証されていればOK?

一般的に、デバイスの入出力をある程度共有化できるように作ると思うので、モックを作ったり、コストをかけて取り組む価値は出てくるのかなと思いました。

最後に業務系やWeb系でモックオブジェクトが流行っている理由について話が及びました。理由は簡単で、言語的制約がないためモッキングライブラリが整備され、モッキンぐライブラリが使いやすくなっているからではないかとのこと。

こういう点が組み込みTDDが、組み込みじゃないTDDとの違いで。言語制約を乗り越えるためのスキルや仕組み作りなしには、TDDの効果を出せないのかと思いました。

2012/07/07

「Mobile5~HTML5の現状とこれから~」に参加した。そして、その後に感じたモヤモヤ


先日、豆蔵さんのトレーニングルームでやっていた「Mobile5~HTML5の現状とこれから~」というイベントに参加してきました。

私は、新卒以来5年間、仕事でべったべたの組み込みをやっているのですが、

  • 技術者として、モバイルがらみも気になってウォッチしていた。
  • 消費者として、スマフォはまー使ってるし、その他のモバイル端末は気になってる。
  • 9月ごろから余裕が出そうだし、何か作りたいな~でも何作ろうかな~。

ともやもやしてたところに、TLでモバイル、組み込み、HTML5などなどのキーワードが流れてきたので興味もって参加してみました。

このエントリでは、主に発表内容が理解できた主催者の@tomo_watanabeさんの発表を聞いて思った感想を書きます。

えっと、おそらく私のすぐ近くに座っていた方がかなり詳しいレポートを書いているので、詳しくはそっちみてください。
http://hoshi.air-nifty.com/diary/2012/07/mobile5-17f1.html

主催者の@tomo_watanabeさんのブログ記事もあります。
http://tomowatanabe.hatenablog.com/entry/2012/07/03/230852

togetterもあります。
http://togetter.com/li/331260


「組込みにおけるHTML5の意味」とは?

@tomo_watanabeさんの発表のタイトルは「組込みにおけるHTML5の意味」。
ちょっと間違っているかもしれませんが、要点は

  • Android ADKような仕組みで既存の組み込み機器がモバイル機器と連携できる
  • HTML5の恩恵でブラウザ上での開発環境が豊かになった
  • 機器同士がWebSocketのような技術でおしゃべりできるようになった
  • おまけにアプリをソーシャルネットワークで共有できる仕組みもある
  • そのうちユーザがアプリを組み合わせて、ディジタル家電のアプリを作るようになるんじゃね?

というものでした。(ちょっと抜けている?)

デモも豊富にあり、ああ楽しそう。なんかやってみたい!という気持ちになりました。大変すばらしいです。これからは組み込みもWebでモバイルや!と思いました。

So What?

で、帰り際で電車で思ったのは、だから利用者は何がうれしいのか?機器同士がおしゃべりすると何がうれしいのか?利用者がエアコンを制御するアプリを作れると何がうれしいのか?もやもや。

今は、こんなことができるんだよ!って世間に提示するのは技術者の役割だけど、それだけでは技術者の自己満足を超えて世の中を動かしていくような製品にはつながらないような気がしました。

消費者として「お!いいね!」って思えるようなユースケース(キラーアプリというのでしょうか?)がないと、消費者に支持されて、爆発的なブームにはならないよなと思いました。あと、ビジネス的にうまみがないと製品化も難しいかもとも。

そして、帰り際、実際に売れるデバイス!となると、HTTPはしゃべれなくていいから、消費者としてうれしいもの・便利なもの、ビジネス的に効果的な使い方の視点がないといけないのかなともやもや考えていました。

派手じゃないけど、現実に利用者の利便性を向上しつつ、ビジネスモデルを変える道具としてモバイルやWebを使っている例あるよな

で、もやもや考えつつ、お家に帰ったら、

  • 従来の組み込み機器を使いつつ、
  • モバイルやWebを使って、利便性を向上し、
  • ありがちなハード売り抜けモデルから、継続的に利益を上げるサービス提供型にビジネスを転換している

ような例はすでにありました。

消費者的にうれしいし、ビジネス的にうれしそうです。
HTML5とか使ってませんが、個人的に便利な製品・サービスありました。WellnessLink(ウェルネスリンク)というサービスです。
http://www.wellnesslink.jp/p/

最近、新会社立ち上げのニュースありましたよね。

NTTドコモとオムロン ヘルスケアが新会社「ドコモ・ヘルスケア」を設立
http://www.advertimes.com/20120704/article74757/

#実際もうけてんのかは調べていません(きり



で、何ができるのかというと、
  • 体組成計で計測した体重やら体脂肪やら筋骨率やらをWeb上にアップして、
  • グラフとして経過を見たり、
  • 目標管理ができたり、
  • 経過データをもとに定期レポートでアドバイスくれたり

などなどです。

データを1か月だけ残すなら無料。1か月以上残すなら月々○○○円という値段設定です。
まだまだサービスは少ないですが、

  • 消費者的には、
    • 測って、記録とって、経過みての一連の流れが自動化されて、非常にうれしいです。もう元の体組成計に戻れません。
  • そして、ビジネス的には
    • 体組成計をただ売って終わりのビジネスモデルから、継続的に利益を上げるサービス提供型モデルに転換できています。
    • また、データが蓄積されていることで私のように利用者が離れづらくなるし、何か別のビジネス提供の機会が今後も増えていくでしょう。
    • コスト的にもデータをアップロードする情報端末を世間に流通しているスマートフォンへ外部化することで、自分たちが作る範囲を制限し、コスト的にも抑えることができています。

あとは

  • まだ微妙に使い勝手が悪くて面倒なとこあるので、私が経営者なら利便性を向上して、もっと使ってもらう機会を増やして客が逃げないようにする。
  • イベントとコラボって、利用者をふやす。
  • 高い料金を払ってもらえるようなサービスを提供する

などなどしていくとよいのでしょうね。

モバイルとWebがビジネスモデルの穴を埋める

WellnessLink(ウェルネスリンク)のサービスを考えていく上で、中の人ってどのように開発していったのでしょう?技術主導なのか、ビジネス主導なのか分かりませんが、個人的には提供したいサービスがあって、それを実現するためにWebやモバイルの技術を配置していっているようなイメージがあります。

ビジネスサイドと技術サイドの両輪がかみ合っている感じ。技術的にものすごいことやるわけじゃないけど、ビジネス的にうまみがでるような技術の使い方をしようとしている印象です。そういうやりたいビジネスモデルがあって、それを実現するためにピースをうめていくような思考が大事なのかなと。

今後技術者に求められるのは?

たぶん、製造業も苦しい時期でしょうし、自分のいるSIerもけっこービジネス的にしんどいです。そういうときって技術サイドから、あれがこれして、こんな面白いことできます!というスタンスも技術者として大事ですが、今より利益率が高くて、ビジネス的に成功する流れを実現するために、ビジネスサイドの人に、この技術とこの技術を組み合わせて、こんなサービスやりましょうってコミュニケーションする姿勢が必要なのかなと思いました。

さて、どうしたらいいのか分からないが。

2012/05/12

組み込みアジャイルコーチのJames Grenningさんが組み込みTDD読書会にやってきた!(あ、Skype会議だけどね

本日、「Test-Driven Development for Embedded C (Pragmatic Programmers)」読書会のスピンアウト企画として、アメリカ・カンザス州にいる著者のJames Grenning氏を交えてSkypeミーティングをやりました。

書籍の感想や読書会の活動内容を伝え、いくつか技術的なトピックについてディスカッションしました。最後、コンピュータサイエンスの修士課程に在籍されている息子さんもTDDをやっているなど、プライベートな話もし、終始なごやかなムードでした。

ディスカッションの中で語った技術的な話は、別途、どこかで記事にしたいと思います。ここではJamesさんとSkypeミーティングをやるにいたった経緯をお話します。

James Grenningさんってどんな人?

著者のブログなどから引用。

プロフィール
http://renaissancesoftware.net/about-us.html
http://www.linkedin.com/in/jwgrenning

  • アジャイルマニフェストの著者17人の一人。
  • プランニングポーカーの考案者。
  • 経験のある分野:weather radar display, FAA control tower displays, distributed automatic testing systems, voice response systems, high-speed cut-sheet printing and communications systems.
  • 1996年からObject Mentor社でXPやアジャイル開発のトレーニングやコーチングに取り組んでいる。( ※未確認ですが、Robert C. Martin氏と一緒に起業した?)
  • 2008年から現在のRenaissance Software Consulting社を創業。アメリカ国内だけでなく、ヨーロッパ方面にも度々カンファレンス参加やトレーニングの仕事で訪問している。
  • 設計、要求、マネジメント、計画、テスト自動化、開発プロセスの改善などの経験あり。
  • "Clean Code”や"Beautiful Team"などの執筆もサポートしている。
  • IEEE software, IEEE Test and Measurement, C++ Reportなどに論文を寄稿。
  • 組み込みやアジャイル関係のカンファレンスの運営をやっている。

ブログ
http://www.renaissancesoftware.net/blog/

論文やカンファレンスの発表資料の一覧
http://www.renaissancesoftware.net/papers.html

アジャイル開発の論文
http://www.eetimes.com/design/embedded/4215538/Agile-embedded-software-development
http://www.renaissancesoftware.net/papers/35-agile-embedded-software-development-esc.html

インタビュー動画
http://www.youtube.com/watch?v=1oIaz7aZsno

講演動画
http://www.youtube.com/watch?v=T8lw0qkXCMc


これまでの経緯(ちょっと長いけど、読書会が始まるところから・・・)

2011年

  • 11月ごろ
    • 大西がTDD Boot Campの盛り上がりに興味をもって、TDD Boot Camp for C++に参加する。t_wada先生が放つジェットストリームアタックにより、あえなく撃沈。
  • 12月ごろ
    • Boot Campのポジペで「Test Driven Development for Embedded Cの読書会をやりたいんですけど、誰か興味ある人いませんか?」と告知したところ、@Catu_dmさん@goyokiさんが名乗りを上げる。

2012年
  • 1月ごろ
    • 第1回の告知をすると、一番最初に著者であるJames Grenning氏が参加希望を表明する謎展開が起きる。
    • あ…ありのまま 今 起こった事を話すぜ!『日本人相手に読書会の募集をかけたと思ったら、最初に参加表明したのがアメリカ人の著者本人だった』な… 何を言ってるのか わからねーと思うがおれも何を起きたのか全くわからなかった…(以下、AA略
    • 3月ごろに日本を訪問されるそうだったが、予定が合わないようなのであえなくお流れ。

  • 3月ごろ
    •  James氏が5月に日本を訪問することになりそうだということなので、読書会メンバーに募集をかける。James氏含めて10名で5月12日に対面して組み込み分野でのアジャイル開発やTDDのディスカッションをする会を開催することが決定。
  • 4月ごろ
    • 当初はインタビュー形式を考えたが、人数が10名程度ということでワールドカフェ形式に変更。事前に質問を書いたポジペを用意して、James氏にも目を通してもらう。
    • しかし、残念ながらJames氏の来日がキャンセルとなり落胆。しかし、Skypeでミーティングすることはできそうということで、引き続き関係者とは連絡を取る。
  • 5月
    •  ついにSkypeミーティングを開催。音声が聞こえないトラブルに見舞われるも、映像とチャットを使って交流。James氏の息子さんにTDDの英才教育をやっているらしき記述を本で見かけたので聞いてみたら、「あいつ、けっこーうまいぜ」と親バカトークに場がなごむ。

意図された偶発性が意図しない偶発性を引き起こす

実際にメールやSkypeで話した内容は後日、James氏や関係者の許可を受けて、記事として公開するよう進めています。詳しい内容は後日そちらを参照してください。  

ここでは一連のやり取りを通して、私が改めて考えさせられたのについて書きます。偶然や偶発性とかいうもの。

私はTwitter上で告知をかけるとき、「組み込みでTDDなんて誰も来てくれない。せいぜい5人くらいでできればいいや。」と思いながら、募集をかけました。組み込みの人でTDDについて話している人なんて、@goyokiさん以外見たことなかったし、あきらかにニッチすぎると思ったからです。

でも、どういう組み込みエンジニアが参加してくれるかは全く分からなかったですが、たまたまTwitterでTDDについてウォッチしている組み込みエンジニアが僕の呼びかけに反応してくれればいいやと思い、Twitterで告知をかけました。 これを「意図した偶発性」と呼ぶことにしましょう。  



しかし、実際には10名近くの人が参加してくれて、こじんまりとしてはいますが、活発な会になっています。何より最初に参加を表明してくれたのが(おそらく書籍タイトルをウォッチしていた)James氏本人だったことに非常に驚きました。「意図しない偶発性」とでも言うのでしょうか? 



世の中どういうことが起きるかわからないですが、関心ごとを同じくする人と一緒に何か面白いことやってみたい!という思いをこめて、Twitterという拡声器を使って呼びかければ、ちょっと予期しなかったような面白いことが起きてくれる。 そんな風に僕は思ったのでした。

さーて、ネタはそろったけど、どんな記事にしようか、、、orz 

2012/05/06

Test Driven Development for Embedded C でペアプロの会 第1回をやりました


本日、「Test Driven Development for Embedded C でペアプロの会 第1回」をやりました。

読書会なので普段は書籍の内容について話し合うことが多いのですが、読書会でサンプルの内容全てを理解するのは限界があると思い、スピンアウト企画としてペアプロの会を始めてみました。
ペアプロの会は演習中心です。実際に書籍のサンプルをTDDをやります。おまけにペアプログラミングをやります。

今日は第8章の「Spying on the Production Code」をやりました。詳しい内容は次回の読書会が終わってからブログで紹介したいと思います。

本日のエントリでは、どんな風に演習をしたかをご紹介します。ちょっとポンチ絵を描いてみました。


演習と振り返りという2つの工程をぐるぐる繰り返しつつ、演習の中では3名が以下の3つの役割をテストケースごとに交代しつつぐるぐる繰り返します。名づけて、ぐるぐるTDD(だっせー><)

  • コードを書く(=ドライバ)
  • コードを描いている様を横で見てアドバイスを出す(=ナビゲータ)
  • もう一人は本を読んで皆の疑問を解決する(=オブザーバ?)
2つ目と3つ目の違いは客観性です。ナビゲータは、ドライバがコードを書いているのを見て、すかさずアドバイスしますが、3つ目の役割の人はナビゲータほど絡んでいかず客観的に場を見ています。で、ドライバとナビゲータの手が止まったり、つまづいていたりすると、参考資料を読んだりして二人の疑問を解決することに専念します。

客観的な視点が入ることと、横で調べている人がいることで、ペアよりスムーズに作業が進んだりするようです。ただ、適正人数は3~4人なので大勢でやるのは向いていませんし、作業ペースは落ちると思われます。皆でじっくり理解しながら進めたいときに向いているかもしれません。

P.S.

このぐるぐるTDDを最初からやろうと思っていたわけではなく、参加人数が少なすぎたので結果的にこういう形になったのですが、意外と面白い体験だったので、次回以降のペアプロの会でも取り入れたいと思います。

2012/04/28

Test Driven Development for Embedded C ぺアプロの会 第1回 演習補足資料


本エントリは、5/6(日)に行う「Test Driven Development for Embedded C ぺアプロの会 第1回」の補足資料です。最初のテストを書くまでが大変になりそうなので、演習をスムーズに進める目的で作成しました。

本エントリの範囲

第8章 p.138 「8.4 Spying on the Code Under Test」までです。それ以降は口頭ベースでやり取りしましょう。

サンプルコード

第8章のソースコードとテストコードを抜いたものを以下に置いています。これをベースに演習を進めてください。

https://github.com/yohei1126/embeddedtdd/zipball/chapter8_init

コードの書き方の細部が分からない場合は、公式サイトのソースコードを参照してください。こちらは全てのコードが入っています。

http://pragprog.com/titles/jgade/source_code

サンプルコードの動作確認

解凍したら make all してください。エラーなしにビルドが通ればOKです。

テストリストの確認

p.130のFigure 8.1 Light Scheduler Test Listを参照してください。本章ではこのテストを一通り消化します。

この時点では全て内容を把握する必要はありません。テストが1個終われば、確認すれば良いでしょう。

テスト対象の設計の確認

p.134のFigure 8.4 Light Scheduler Unit Test Structureを参照。テスト対象のLightSchedulerは、LightControllerとTimerServiceのインタフェースにのみ依存します。テスト中は、LightControllerとTimerServiceをTestDoubleに置き換えることで、テスト可能にします。

p.136 LightControllerSpyのCreateのテスト

p.134~135のテストは途中で中断します。最初はp.136のLightControllerSpyのCreateのテストから始めた方が良いです。

LightControllerSpyTest.cppのテストコードを記述

まずはp.136のテストコードを一通り書いてみましょう。テストコードの配置場所は以下になります。
    tests\HomeAutomation\LightContollerSpyTest.cpp

CppUTestでテストする際に以下は必須です。

  • TestHarness.hのインクルード
  • TEST_GROUPの宣言

また、C++のテスティングフレームワークであるCppUTestを使って、C言語のコードをテストするため、C言語のヘッダファイルをインクルードする際はextern宣言します。

ここで、テストコードを一通り書いた段階でまだプロトタイプ宣言がないため、コンパイルエラーが起きます。

LightControllerのプロトタイプ宣言を実装

コンパイルエラーを解消するため、LightControllerのプロトタイプ宣言を記述します。LightControllerはテスト対象なので、ヘッダファイルの場所はinclude以下になります。
   include\HomeAutomation\LightContoller.h

LightControllerSpyのプロトタイプ宣言を実装

コンパイルエラーを解消するため、LightControllerSpyのプロトタイプ宣言を記述します。
LightControllerSpyはTestDoubleなので、ヘッダファイルの場所はtests以下になります。
   tests\HomeAutomation\LightContollerSpy.h

ヘッダファイルの定義はp.137を参照してください。ここで定義されているenumはテストでのみ使うため、ここで定義しているそうです。

LightControllerの関数定義を実装

リンクエラーを解消するため、テストコードで使われているLightControllerの関数2つを実装します。
ここでは空実装で構いません。

LightControllerSpyの関数定義を仮実装

リンクエラーを解消するため、テストコードで使われているLightControllerSpyの関数2つを実装します。ここではテストが動いていることを確認するため、わざと明らかに違う値を返します。
例)1000

テストすると、失敗します。

LightControllerSpyの関数定義を本実装

テストを通すための最小限の実装を行います。テストの期待値をそのまま返せばOKです。


p.137 LightControllerSpyのRememberTheLastLightIdControlledのテスト

テストコードを記述

まずはp.137の最初のテストコードを記述します。プロトタイプ宣言がない関数があるのでコンパイルエラーが出ます。

LightControllerのプロトタイプ宣言を実装

コンパイルエラーを取り除くため、LightController.hにLight_Controller_Onを記述します。

LightControllerSpyの関数定義を仮実装

リンクエラーを取り除くため、LightControllerSpy.cにLight_Controller_Onを記述します。
※TestDoubleで置き換えるため、tests側に実装しています。

ここでビルドするとテストに失敗します。

LightControllerSpyの関数定義を本実装

テストを通すために最小限の実装を行います。
p.137~p.138にかけてあるとおり、IDと状態を記憶する処理を実装します。

---

以上で最初のとっかかり部分はできました。
サポートもしまずが、後はなるべく自力でがんばってください。

Dual Target Testingで組み込みソフトウェアの品質を早期に作りこむ

4/22(日)に「Test Driven Development for Embedded C 読書会 第3回」を開催しました。当日のやり取りはTogetterにまとめていますので、そちらもご覧ください。

この日は以下の2章をやりました。
  • 第5章「Embedded TDD Strategy」
    • 組み込みシステム開発でTDDをやる上で重要なDual Target Testingについて紹介されています。
  • 第6章「Yeah, but...」
    • TDDを実開発に導入する上でよく聞かれる反対意見とその意見に対する反論が書かれています。
本エントリでは第5章の内容をご紹介します。


ハードウェアとソフトウェアの並行開発が組み込みシステム開発を難しくしている

組み込みシステム開発では、ハードウェアとソフトウェア開発が並行で走ることがよくあります。

以前、「組み込み開発のリスクである「ソフトウェアとハードウェアの並行開発」の解決方法の一つが組み込みTDDじゃないだろうか?」というエントリでもそのことについて書きましたが、この並行開発が組み込みシステム開発が困難になる理由だと私は考えています。それはソフトウェアとハードウェアの両方にバグが混入された状態で開発が進むため、原因の切り分けが非常に分かりづらいバグが発生することがよくあるからです。

並行開発について少し例を挙げてみましょう。私が経験した組み込みシステム開発では、以下のようにいくつかイテレーション(フェーズとも言う)を区切って、イテレーションごとに機能のスコープを切り、イテレーションの最後にハードウェアとソフトウェアを結合して、品質評価をやるというスタイルを取っていました。こういうプロトタイピングを繰り返し、だんだん仕様を固めていくスタイルはよくあるのではないでしょうか?


このように繰り返しプロトタイピングしながら進めていくスタイルでは、
  • 開発序盤にそもそも次期製品のハードウェアがない。
    • たいていの場合は、チップ周りを担当する人には本当に最小限の回路が乗っているハードが提供されて、OSの立ち上がりの確認をしたりする。
    • もっとユーザ寄りの機能を担当する人は、前製品のハードウェアが提供され、全製品と重複している箇所の動作確認からはじめたりする。
  • ソフトウェアとハードウェア双方にバグがある。
という状態で進みます。

そして、イテレーションの最後に結合してリリースした後の品質評価が大量のバグが上がってくると、まずはバグの原因はハードウェアなのかソフトウェアなのかの切り分けから始まります。双方の品質が低い状態なので原因の切り分けははっきり言うと難しいです。そのため、ソフトウェア技術者にとってはソフトウェアにバグはないと確認し、自信を持って主張するためのエヴィデンスの確保に大量の時間を取られてしまいます。

はっきり言って、この時間は不毛だし、生産的ではないでしょう。この不毛な時間を少しでもなくし、より生産性の高い開発を実現するために、組み込みソフトウェアエンジニアは日夜、ハードウェアが届く前にソフトウェアの品質を作りこむことに力を注がなくてはいけません。


Dual Target Testingでソフトウェアの品質を早期に作りこむ

ハードウェアが届く前にソフトウェアの品質を作りこむにはどうしたらいいんでしょうか?書籍で推奨されているのがDual Target Testing、つまりターゲット・ハードウェアとPC上の両方でテストできるようにすることです。

書籍では、以下のプロセスでテスト駆動な開発をしろと解説しています。



特徴は以下。
  • 最初の段階で、徹底的にPC上で単体テストとリファクタリングをして、単体レベルのソフトウェアの品質を確保してから評価ボードに持っていく。
    • デバッグ環境の貧弱な評価ボード上で単体レベルのロジックのミスを見つけるような、不毛な作業がなくなります。
  • PC上でターゲット用のコンパイルを行ったり、評価ボードやターゲットハードウェア上でも単体テストを動かすことで、ホスト環境とターゲット環境の違いによるバグを早期に見つける。
  • ターゲットハードウェアに対する受け入れテストも用意する。
ここでやっているのはあくまでも単体テストなので、単体テストのスコープの検証しかできませんが、評価ボードに持っていくまでに品質を確保できているので、まず開発の立ち上がりがスムーズに行くと考えられます。

また、PC、評価ボード、ターゲット・ハードウェアの3つに対して単体テストが自動的にできるため、結合した上で単体レベルの動作確認などが不要になります。結合した時に振る舞い、あるいはマルチタスクの微妙なタイミングによリ発生するバグなど、もっと複雑な不具合の究明に力を注ぐことができるはずです。


Dual Target Testingをやるには地道に単体テストを積み上げる必要がある

ただし、自動テストをやるには単体テストが用意されている必要があります。これは、いきなり評価ボードに持っていって実機デバッグをやるより、はっきり言って時間のかかる作業だと思います。

単体テストを作らずに評価ボードで実機テストを繰り返すスタイルは、直近で見ると一見手間がかからなくて楽な方法です。しかし、機能を追加するとテスト作業が全てが手作業になり、繰り返し単体レベルの動作を保証することはできません。また、途中で混入したデバッグ作業に時間を浪費し、生産性の向上は見込めません。

Dual Target Testing用に単体テストを積み上げていくスタイルは、直近で見ると時間がかかり、進捗は遅くなりますが、開発を進むにつれて混入したバグを即座に発見することができるため、デバッグ時間の節約にもなり、より難易度の高い不具合の究明に時間をさけるようになります。

この開発時間についてどう捉えるかは6章で扱っているので、そちらで紹介したいと思います。

どうやってDual Target Testingをやるの?

具体的なテクニックは第7章「Introducing Test Doubles」以降で紹介されています。次回の読書会で扱う予定。その際にまたブログで紹介したいと思います。

2012/04/14

#coderetreat in Tokyo 2nd に参加してきた

Coderetreat in Tokyo 2ndに参加してきました。

Coderetreatとはイベント告知のページによると以下のようなイベントです。
Coderetreat は、プログラマのための練習、学習のためのイベントです。同じ課題をペアプロで実装しながら、プログラミング、設計、テストなどの技術を学びます。
特徴を挙げると・・・
  • 全員がライフゲームという題材に取り組む。
  • ペアプログラミングをしながら実装する。
  • 開発45分で振り返り15分で1セッション。
  • セッションのたびにペアを入れ替える。
  • 毎回コードを捨てて、一から作り直すという作業を繰り返す。
  • 言語は固定せずにいろんな言語で実装する。
    • 実際、私はRuby/C/Javaで実装しました。
  • セッションのたびに追加課題が与えられる。
    • 配列を使うなとか、if文を使うなとか、セッター・ゲッターは使うなとか。
このイベントはかなり斬新で、すごい楽しかったです。

これをやることによって何が起こるかというと
  • ペア作業を繰り返すことで、いろんな人の設計アイディアが合成されて、セッションを進むごとに設計が洗練されていきます。
    • 実際、最初のライフゲームのデータ構造は地味な2次元配列でしたが、途中からクラスベースで多次元に対応できるデータ構造になっていきました。
  • 普段使わない言語で実装することで、違った視点を得られたり、違う言語ならではの体験ができます。
    • 特に、私は組み込みCでのTDDに取り組んでいるので、Rubyでのコードの記述量の少なさ、本質的なコードに集中できることの生産性はすごいうれしいと分かりました。
    • C言語の場合、言語的な制約をカバーする要素が多く、Rubyのような生産性はなかなか出せません。
    • ただし、C言語でも(Rubyには及ばないまでも)早いサイクルでTDDを回すことはできますが。
  • 実装の制約をかすことで、よりオブジェクト指向らしいきれいな設計に収束していきます。
今回のイベントに参加したおかげで、ペアプロ、TDD、オブジェクト指向設計の面白さや大切さを再発見しました。

今、組み込みCのTDDの読書会をやっていますが、区切りの良いタイミングで、今回のイベントのように演習中心でペアプロをする会をやれたらいいなという思いが強まりました。その時は、組み込みらしく実機も用意して、dual targeting testを実践すると。

最後になりましたが、場所・食事・おやつのスポンサーのグロースエクスパートナーズ株式会社、株式会社 情報システム総研-、株式会社 スペイシーズの皆様に感謝したいと思います。素晴らしいイベントをやっていただいてありがとうございました!


2012/03/25

#agilesamurai dojo gatheringでマスター・センセイのコーチングを受けた

3/24(土)にあったAgilesamurai Dojo Gatheringでのこと。

ワールドカフェにて

なんやようわからんけど、うちのテーブルにマスターセンセイことJonathan Rasmussonさんが来て、僕がホストをやった。

legoboku「前のグループで話してたのは、アジャイルにしろ何かを変えるためにはモチベーションが大事で、他の人のモチベーションをどうやってあげたらいいのか?を話ししてました。」

legoboku「ある人は、共通の話題とかを見つけて仲良くなって、彼らを支援したらいいんじゃないかとか。あるいは、他の人のモチベーションを上げるって難しいから話振って興味を示してくれる人を見つけて仲間を作るのが精一杯じゃないかって。」

Jonathan「そうだね。他の人のモチベーションを上げるってことは本当に難しい。それをやれって言われても、そこは責任を持つことはできない。僕らにできるのは自分で自分のモチベーションを上げることが出来る人をサポートすることくらいだ。」

Jonathan「だから、他の人を変えなくちゃいけないって思いつめなくてもいいよ。大事なのは、自分で自分の仕事に誇りを持って、信念をもってやることじゃないかな。そして、君自身が楽しむことができたら、あいつが楽しそうにやってるのはなぜだろう?って周りの人が興味を持ってもらえるかもしれない。」

そうっすね。皆、何か変化が起きて欲しいと思うけど、誰かに変えろって言われたら反発しちゃうし、自発的な変化が起きるように支援する事が大事かなと。あと、自分が楽しむこと。do it for fun.

ビアバッシュしてる時に真面目な話

legoboku「えっと、けっこーseriousなproblemがあって、質問があります。」

Jonathan「problemじゃなくてchallengeだよ!では、向こうで話そうか」

legoboku「僕は組み込みソフトウェアの開発をやっているのですが、組み込みシステムの開発ってアジャイルに向いていないんじゃないかって意見があるんです。例えば、組み込みシステム開発って、メカエンジニアとか電気回路のエンジニアとか製品企画とかとすりあわせしながら、繰り返しプロトタイプを作るって開発します。」

legoboku「で、リリース対象の機能を備えたハードウェアがないとシステムテストができないけど、物理的なものを作るのって早くはできない。それに、リコールすると回収コストがものすごくなるし、ドメインによっては人命にかかわるから、品質保証プロセスが重たいものになりがち。繰り返しはしているけど、アジャイルにはなりにくい。」

Jonathan「そうだね。僕は組み込みのことはよくわからないけれど、ハードウェアが早くつくれないってのはそうなんだろう。例えば、ハードウェアとソフトウェアの境界を早く決めることでスムーズにソフトウェアを開発することはできないかな?」

legoboku「そうですね。Test-Driven Development for Embedded C (Pragmatic Programmers)では、ソフトウェアエンジニアとハードウェアエンジニアが先にインタフェースの仕様を合意して、テスト駆動で中を作り込むってシーンを描いてました。」

Jonathan「そう。境界を早く作るってのが一つの手だね。」

legoboku「そうですね。境界を作るには技術領域が違う人達が協力する必要があるんです。でも、誰でもどっちも分かっている人ってそれほど多くなくて、お互いに相手が何を言っているのか分からなくて、コミュニケーションがうまくできなかったり。それに、なんか組み込みの分野ってハードウェアの人が偉くて、ソフトウェアの人が後回しにされているような気がしてて、最後に尻拭いされているような感じがするんですよね。」

Jonathan「うーん、じゃ、こう考えようか。君がCEOで、僕がハードウェアエンジニアだ。僕がソフトウェアエンジニアとうまくやって、プロジェクトとして開発をアジャイルにするために僕にどういう風に説明するかな?」

legoboku「そうですね。例えば、共通の目的が何かを話するかもしれないですね。目的は、お客さんが満足する製品を早く提供すること。そこは一致しているんだから、技術的なところでうまく協調できないかとか。」

Jonathan「じゃ、うまく協調するためにはどうしたらいいだろう?」

legoboku「あ、そうだ。例えば、ソフトウェアエンジニアがハードウェアエンジニアのところに行ってちょっと修行するってのはどうでしょう?彼らが何を考えているとか、何を気にしているのか分かるかもしれない。」

Jonathan「そうすると、ソフトウェアのプロジェクトに戻ってきても、以前よりうまく開発できるかもしれないね。」

知らないお姉さん「わー、Jonathan、サインして!!」

Jonathan「あ、呼ばれてる。もう大丈夫かな?」

legoboku「あ、はい。なんか分かったような気がします。」

いやね、簡単な回路図とか読めるんすよ。で、もっと奥深く入った方がスムーズにコミュニケーション出来るってのも分かるけど、ソフトウェアでもいろいろ考えることあるし、なんか電気回路とかにモチベーションががががが。

あるいは、こういうのは企画とか営業とエンジニアとか、他の職種の境界でも起こるのかもしれない。あいつ何言っているのか分からないし、何でそんな簡単なことすぐにやってくれないのかとか。
でも、ワールドカフェで話したのは、仲が悪いんじゃないよ、コミュニケーションが足りないだけで、お互いを知ればもっとより良くできるはずとか。

そんな風に、コーチングを受けて思った。

文化のギャップを乗り越える

日英の逐次通訳をやるのも、技術領域の境界を話し合うのも同じなのかもしれないと帰りながら思った。気持ちが大事だよ!気持ち!!
でも、もっと上位の目的で合意するためには、実は相手の言語と思考パターンを理解しないといけない。相手の言語と思考パターンが全く分からない状況では、あいつは何を考えているんだとかコミュニケーションの障害が起きてしまう。それを乗り越えるには、気持ちだけじゃなくて、言語スキルと相手の思考パターンを理解することが大事なんだ。多分、きっと。

そのためには、あれか同じ釜の飯を食うってやつか。

2012/03/07

組み込み開発のリスクである「ソフトウェアとハードウェアの並行開発」の解決方法の一つが組み込みTDDじゃないだろうか?


私はSIerの人間であって、メーカーの人間ではないですが、メーカーの製品開発の中に深く入り込んで開発した経験があります。その時感じたのは組み込み開発の最大のリスクがハードウェア・ソフトウェアの並行開発だということです。

■未完成品のハードウェアに対してコードを書くのは大変><

一般的な組み込み開発の場合、開発PC上で開発→ 評価ボードでデバッグ → 本製品上での評価と開発が進みます。ベッタベタな開発の場合、最初はターゲットがない状態でごしごしコードを書いて、しばらくしたら評価ボードと言われる半完成品のハードウェアが届いて、そいつにソフトウェアをのっけてデバッグして、ソフトウェアのバグを取り除く作業をやります。

とにかく早く実機で動かすのが腕の見せ所!な状態なので、そもそも単体テストできることを考えていない場合も。だからハードウェアと密結合を起こして、後から単体テストできなくなってしまいます。

ここで
  • 開発PC、評価ボード・製品向けのライブラリやコンパイラが微妙に違う
  • 最初は評価ボードの完成度が低い
  • ソフトウェアのロジックのミスがある
  • ハードウェアが固まった後のしわ寄せがソフトウェアにくる
などなどのリスクがある状況で開発が進むので、とにかくデバッグに時間がかかったり、バグの原因の切り分けが難しくなったりして、ソフトウェア開発がものすごい困難になります。

(組み込みでアジャイル開発をやる場合は、ここがネックになると思います。)

Dual-Target Testing

そこで、Test-Driven Development for Embedded Cでは、最初からハードウェアへ依存しない設計にし、開発PCでも評価ボードでも単体テストが動くようにすることを推奨しています。これをDual-Target Testingと呼んでいます。これで、開発PCで徹底的に単体テストをし、ソフトウェアのロジックミスを排除して、さらに評価ボード上でも単体テストが動くことを確認します。これで、テストがかなりスムーズに行えます。

Dual-Target Testingに必要な要素は?

では、Dual-Targeting Testをやるには何が必要なんでしょうか?第一にJava界隈で育ってきたテストの技術を応用して、最初から単体テスト可能に設計することが重要だと思います。

次に、低レイヤーの開発の場合、メカ・エレキなど周辺領域の技術者との緊密なコミュニケーションが必要だと感じます。Test-Driven Development for Embedded Cでは、エレキの技術者とハードウェアとのインタフェース部分の設計をつめているシーンが書かれています。最初からハードウェアへ依存しない設計にするためにも、ハードウェアとのインタフェースをつめておかないと、Test Doubleの作り方も決められないからだと思います。

Test-Driven Development for Embedded Cではどうやっているのか?

最後に書籍のサンプルをのせていますので、そちらを参照してください。このサンプルの肝はコンストラクタでハードウェアへの依存性を注入している箇所です。変数ledsAddressとは、書き込みポートのアドレスですが、これをコンストラクタで与えることで、開発PCでも評価ボードでも単体テストできるようにしてます。

また、かなり芸が細かいですが、このハードウェアは読み込みポートがないという設定です。LEDの状態は一度ledsImageという変数に書き込んでおいて、あるタイミングでポートに書き込みます。読み込みポートがあるのかとかはエレキの人と早めに仕様を詰める必要があります。

今回の例は極めて単純なので、だからどうしたと思われるかもしれません。現場にはもっとテスト困難な例があると思います。そんな時にどうするのか?基本は同じで、ハードウェアおよび外部モジュールに対する疎結合な設計、早期のハードウェアとのインタフェースの確立だと思います。

詳しくは次回以降のTest-Driven Development for Embedded C読書会で学んでいきます。乞うご期待。

(サンプル)テストコード
#include "unity_fixture.h"
#include "LedDriver.h"
#include "RuntimeErrorStub.h"

#ifndef NULL
#define NULL @((void *) 0)
#endif

TEST_GROUP(LedDriver);

static uint16_t virtualLeds;

TEST_SETUP(LedDriver)
{
 LedDriver_Create(&virtualLeds);
}

TEST_TEAR_DOWN(LedDriver)
{
}

TEST(LedDriver, LedsOffAfterCreate)
{
 uint16_t virtualLeds = 0xffff;
 LedDriver_Create(&virtualLeds);
 TEST_ASSERT_EQUAL_HEX16(0, virtualLeds);
}

TEST(LedDriver, TurnOnLedOne)
{
 LedDriver_TurnOn(1);
 TEST_ASSERT_EQUAL_HEX16(1, virtualLeds);
}

TEST(LedDriver, TurnOffLedOne)
{
 LedDriver_TurnOn(1);
 LedDriver_TurnOff(1);
 TEST_ASSERT_EQUAL_HEX16(0, virtualLeds);
}

TEST(LedDriver, TurnOnMultipleLeds)
{
 LedDriver_TurnOn(9);
 LedDriver_TurnOn(8);
 TEST_ASSERT_EQUAL_HEX16(0x180, virtualLeds);
}

TEST(LedDriver, AllOn)
{
 LedDriver_TurnAllOn();
 TEST_ASSERT_EQUAL_HEX16(0xffff, virtualLeds);
}

TEST(LedDriver, TurnOffAnyLeds)
{
 LedDriver_TurnAllOn();
 LedDriver_TurnOff(8);
 TEST_ASSERT_EQUAL_HEX16(0xFF7F, virtualLeds);
}

TEST(LedDriver, LedMemoryISNotReadable)
{
 virtualLeds = 0xffff;
 LedDriver_TurnOn(8);
 TEST_ASSERT_EQUAL_HEX16(0x80, virtualLeds);
}

TEST(LedDriver, UpperAnbLowerBounds)
{
 LedDriver_TurnOn(1);
 LedDriver_TurnOn(16);
 TEST_ASSERT_EQUAL_HEX16(0x8001, virtualLeds);
}

TEST(LedDriver, OutOfBoundsChangesNothing)
{
 LedDriver_TurnOn(-1);
 LedDriver_TurnOn(0);
 LedDriver_TurnOn(17);
 LedDriver_TurnOn(3141);
 TEST_ASSERT_EQUAL_HEX16(0, virtualLeds);
}

TEST(LedDriver, OutOfBoundsTurnOffDoesNoHarm)
{
 LedDriver_TurnAllOn();
 LedDriver_TurnOff(-1);
 LedDriver_TurnOff(0);
 LedDriver_TurnOff(17);
 LedDriver_TurnOff(3141);
 TEST_ASSERT_EQUAL_HEX16(0xffff, virtualLeds);
}

TEST(LedDriver, OutOfBoundsProducesRuntimeError)
{
 LedDriver_TurnOn(-1);
 TEST_ASSERT_EQUAL_STRING("LED Driver: out-of-bounds LED", RuntimeErrorStub_GetLastError());
 TEST_ASSERT_EQUAL(-1, RuntimeErrorStub_GetLastParameter());
}

TEST(LedDriver, IsOn)
{
 TEST_ASSERT_FALSE(LedDriver_IsOn(11));
 LedDriver_TurnOn(11);
 TEST_ASSERT_TRUE(LedDriver_IsOn(11));
}

TEST(LedDriver, OutOfBoundsLedsAlwaysOff)
{
 TEST_ASSERT_TRUE(LedDriver_IsOff(0));
 TEST_ASSERT_TRUE(LedDriver_IsOff(17));
 TEST_ASSERT_FALSE(LedDriver_IsOn(0));
 TEST_ASSERT_FALSE(LedDriver_IsOn(17));
}

TEST(LedDriver, IsOff)
{
 TEST_ASSERT_TRUE(LedDriver_IsOff(12));
 LedDriver_TurnOn(12);
 TEST_ASSERT_FALSE(LedDriver_IsOff(12));
}
(サンプル)プロダクトコード
#include "LedDriver.h"
#include "RuntimeError.h"

enum {ALL_LEDS_ON = ~0, ALL_LEDS_OFF = ~ALL_LEDS_ON};
enum {FIRST_LED = 1, LAST_LED =16};
static uint16_t *ledsAddress;
static uint16_t ledsImage;

void LedDriver_Create(uint16_t* address)
{
 ledsAddress = address;
 ledsImage = ALL_LEDS_OFF;
 *ledsAddress = ledsImage;
}

void LedDriver_Destroy(void)
{
}

int convertLedNumberToBit(int ledNumber)
{
 return 1 << (ledNumber - 1);
}

static void updateHardware(void)
{
 *ledsAddress = ledsImage;
}

int IsLedOutOfBounds(int ledNumber)
{
    return (ledNumber < FIRST_LED) || (ledNumber > LAST_LED);
}

void setLedImageBit(int ledNumber)
{
    ledsImage |= convertLedNumberToBit(ledNumber);
}

void clearLedImageBit(int ledNumber)
{
    ledsImage &= ~convertLedNumberToBit(ledNumber);
}

void LedDriver_TurnOn(int ledNumber)
{
 if (IsLedOutOfBounds(ledNumber)) {
  RUNTIME_ERROR("LED Driver: out-of-bounds LED", ledNumber);
  return;
 }
 setLedImageBit(ledNumber);
 updateHardware();
}

void LedDriver_TurnOff(int ledNumber)
{
 if (IsLedOutOfBounds(ledNumber)) {
  RUNTIME_ERROR("LED Driver: out-of-bounds LED", ledNumber);
  return;
 }
 clearLedImageBit(ledNumber);
 updateHardware();
}

void LedDriver_TurnAllOn()
{
 ledsImage = ALL_LEDS_ON;
 updateHardware();
}

BOOL LedDriver_IsOn(int ledNumber)
{
 if (IsLedOutOfBounds(ledNumber)) {
  return FALSE;
 } else {
  return ledsImage & (convertLedNumberToBit(ledNumber));
 }
}

BOOL LedDriver_IsOff(int ledNumber)
{
 return !(LedDriver_IsOn(ledNumber));
}

2012/03/04

Test-Driven Development for Embedded C読書会第2回をやりました











本日、「Test-Driven Development for Embedded C (Pragmatic Programmers)」読書会の第2回をやりました。

今日読んだ範囲は?

第3章「Starting a C Module」と第4章「Testing Your Way to Done」をやりました。第3章は初めてのTDDセッションでLEDドライバのコア部分をTDDで実装する章です。第4章はテストリストに書いた機能をひと通り実装しながら、リファクタリングをしていく章です。

第3〜4章の一連の流れは前半のハイライトだと思います。本書を読み進めていく場合に、最初に感じを掴みたい方はここのサンプルを一から自分で書いてみることをオススメします。

サイトにレジュメを置いているので、こちらも参照してみてください。
サンプルコードは私のgithubのリポジトリにあります。ちょっとインデントが崩れているので、後で綺麗に整形します^^;
常にコードを安定な状態に置く

今日の勉強会で一番勉強になった点を2つご紹介します。

まず、1つめは「常にコードを安定な状態に置く」ということ。これは以前、ブログの
C/C++でTDDする時の手順をステートマシン図で描いてみた」に書いたTDDの作業を表現したステートマシン図に通じる話です。

今日、勉強会をやっていてふと思ったコードには2つの安定した状態があって、TDDでは必ずその2つのうちのどっちかの状態に置いて安定させるという意図があるんじゃないかということです(持論です)。



1つ目はテストが通って安定した状態。これにはテストが通っただけでリファクタリングされていない状態と、リファクタリングされている状態があります。これはTDDを少しかじっていれば知っている内容ですね。

2つは、(勉強会を初めて知りましたが)テストが通っていなくて安定している状態があります。コンパイルエラー、リンクエラー、テスト失敗ときてプロダクトコードを書くための過程の状態です。それまでの間に、ちゃんとテストが通っていない実装があることが目に見えている状況を作り出しています。これで全体としてはテストが通っているけど、失敗もエラーも起きない隠れた実装ミスや不要なものがあるという不安定な状況を意図的になくそうとしています。

ここまで厳密にやる必要があるのか?と思う人がいるでしょう。もちろん、人によっては、こんなことやらなくても、ぱぱっと1度で完全なコードを実装出来る人もいると思います。私のように、そうでない人は何かしらの手段で実装モレや不要な実装を残さない手段は取っておくと良いのかなと思いました。

実装する時は最初からパフォーマンス重視にせず、基本は可読性を意識する

もう1つは、リファクタリングを通じて重複を排除していく箇所でこのような記述がありました。

don't let the performance factor outweigh improved design and readability unless there is proof the code is contributing to a specific performance problem.

今リファクタリングしようとしているコードがパフォーマンス上の問題箇所であるという証明がないなら、可読性を重視しろということです。

これは組み込みで大事な性能を無視しろということを言っているわけではありません。ディスカッションでも意見が挙がりましたが、パフォーマンス上の問題はちゃんとプロファイラなどのツールで計測して、ボトルネックを明らかにしてから対処するべきです。どこにボトルネックがあるかを明らかにしないまま闇雲にパフォーマンス重視なコードを書いていては、保守性が下がり、開発コストに悪影響を与えます。

なので以下がいいのかなと思いました。
  • アーキテクチャ設計の段階でちゃん性能要求を満たすよう設計しておく。
  • アーキテクチャを固める段階、プロジェクト序盤でプロファイリングなどを使って性能のボトルネックを明らかにして対処する。
  • 個々の実装では可読性を重視した実装へリファクタリングする。
今日はオフトピとして各自の工夫についても披露してもらいました

1つ目はEclipseを使い、ファイル保存時にビルド・テストが走らせること(これは私が話しました)。Eclipseには、ファイル保存時にビルドコマンドを実行する設定があります。これを有効にしておくと、Makefaileを修正して静的解析・コードフォーマット・カバレッジのツールを自動実行でき、非常に楽チンで良いかなと思っています。

2つ目は静的解析ツールAdLintをビルド時に実行すること(うちの先輩が開発してるんで宣伝させてもらいました^^;)。まだ「Mac OS X LionにC言語用静的解析ツールAdLintをインストールした」に書いたとおり調べている途中で、案を話した程度です。次回くらいに披露したいですね。

3つ目はコード整形ツールを使ってコード書式を自動で統一するという内容。今日、紹介されたのはArtistic Styleというツール。今日の話では、ビルド時に毎回Artistic Styleを走らせてコード書式の統一を強制するやり方はどうか?とい話でした。意図しない成形が起こる場合があるので注意が必要ですが、コード書式の統一をツールで自動化するのは有用だと思いました。

4つ目はカバレッジ計測ツールの利用です。皆さんgccを使っているのでgcovというツールが良さそうだというアドバイスがありました。

次回の予定は?

次回は4月にやります。そのうち案内を出します。

読む範囲は第5章「Embedded TDD Strategy」と第6章「Yeah, but...」になる予定です。前者は組み込み開発にTDDを適用する際に、後者は周囲の人にTDDを導入を勧める際に役立ちそうな内容だと期待しています。

その前に情報処理技術者試験がんばれ俺orz

2012/03/03

自発性・熟達・目的、現代を生きる人々のモチベーション

2月に読んだ本を紹介します。

一番良かったのは「モチベーション3.0 持続する「やる気!」をいかに引き出すか」。
現代を生きる人々のためのモチベーションについて書かれています。昔から人々のモチベーションを上げるやり方として「飴と鞭」がありましたが、それは目標と解決策が明確な場合にしか機能しないのだそうです。現代では目標と解決策が明確でない問題の方が多いため、飴と鞭のやり方をそのまま適用できることが少ないとか。

代わって現代を生きる我々に必要なのは「自発性・熟達・目的」。社員が自発的にこうしたいという思いと、会社として利益を上げる方法を交差させるポイントを見つけることができた組織が今後活躍するのだなと思いました。

アジャイル開発でも似た点があると思っています。先日、アジャイル開発のセミナーを受けた時に、上から命令をするやり方ではなく、自己組織化したチームが自発的に自分達のやり方を決めていくことを推奨していました。おそらくアジャイル開発をやる組織は、内発的動機に突き動かされている、自己組織化されたチームではないと、短期間に高いパフォーマンスを出すのは難しいのでしょう。

「自発性・熟達・目的」。自分個人としても、自分が所属する組織としても、この言葉を実現できるやり方を模索したいなと思います。

legobokuの本棚
2012年02月
アイテム数:6
パブリック―開かれたネットの価値を最大化せよ
ジェフ・ジャービス
読了日:02月18日
{book['rank']

河北新報のいちばん長い日 震災下の地元紙
河北新報社
読了日:02月18日
{book['rank']

データ分析できない社員はいらない
平井 明夫
読了日:02月18日
{book['rank']

「週4時間」だけ働く。
ティモシー・フェリス
読了日:02月19日
{book['rank']

powered by ブクログ

2012/03/02

Mac OS X LionにC言語用静的解析ツールAdLintをインストールした

オープンソースのC言語用静的解析ツールAdLintを自宅のMacbook(OSはLion)にインストールしました。手順を残しておきますね。
(インストール方法は公式サイトにもあるので、そちらも参照してください。)

Ruby1.9.3のインストール

まず、Ruby1.9.3が必要なのでインストールします。私はMacport使ってますが、homebrewでもソースビルドでもいいでしょう。

% sudo port install ruby19 +nosuffix
% sudo port -f activate ruby19

macportで入れる場合はオプションに "+nosuffix" が必要です。Ruby1.9.Xを普通にインストールすると、Rubyを実行する時に「ruby19」とバージョン番号をつける必要があります。これだと他のツールから呼び出してもらえないので、バージョン番号なしで呼び出せるようにするためです。

AdLint1.0.0のインストール

こっちはgemで一発です。なんかマークが出たら成功です。

% sudo gem install adlint
(中略)
-------------------------------------------------------------------------------
     ___    ____  __    ___   _________
    /   |  / _  |/ /   / / | / /__  __/            Source Code Static Analyzer
   / /| | / / / / /   / /  |/ /  / /                    AdLint - Advanced Lint
  / __  |/ /_/ / /___/ / /|  /  / /
 /_/  |_|_____/_____/_/_/ |_/  /_/    Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.

                         Thanks for installing AdLint!
     Please visit our project homepage at .

-------------------------------------------------------------------------------
Successfully installed adlint-1.0.0


AdLintを何に使うの?

今、「Test-Driven Development for Embedded C (Pragmatic Programmers)」の読書会をやっていて、C言語でTDDをする一連のプロセスの中にちょちょいと静的解析を入れられないか検討してます。

高いライセンスのツールと違い、AdLintはフリーなのでビシバシ手元で静的解析をかける感じで使いたいなと思います。

タイミングとしては、テストがパスしている安定な状態で、一度リファクタリングした後くらいで静的解析をかけて、問題のあるコードを取り除いたりする作業が気軽に導入できればいいかなと。あくまでもぼんやりとした案レベルですが。

次回の読書会まで時間がないので、次の次くらいに読書会参加者の皆さんに披露したいと思ってます。

2012/02/26

C/C++でTDDする時の手順をステートマシン図で描いてみた


タイトルで描いてみたと言いつつ、「Test-Driven Development for Embedded C (Pragmatic Programmers)」の第3.7節「Test-Driven Development State Machine」より引用です。著者のJames W. Grenning氏はTDDの作業を以下のステートマシン図のように捉えると良いと書いています。

TDDの作業を状態遷移として表現したステートマシン図


※作業を状態として書いているので良い書き方じゃないのですが、そこは置いときましょう。

TDDをやっている人ならご存知だと思いますが、テスト対象を実装する前にいきなりテストを書いて、わざわざコンパイルエラーを起こすとこからやるのが大事です。そして、コンパイルエラーの次は、リンクエラー、テスト失敗と来てからようやくテストを通るように実装します。

この一連の流れをやる目的は、

  • 今あるテストを通すための最小限の実装を常に維持する
  • テストが通っていないなら、どこに問題があるか明確に分かるようにする

です。

まずはテストを書いて目標を定めておいて、エラーまたはテスト失敗で作業ステップを確認しつつ、1歩1歩歩いていくのです。本当に1歩ずつです。ちょっとでも道から外れていれば、そこ道外れているよ!と警告を上げてくれます。

(TDDをやらない人でもIDEを使っている人は、IDEについている構文チェックのサポートを受けてコードを書いているので似ているようなことをやっているかもしれません。)

TDDをやらないコーディングの場合、本人が気付かないだけで、作業と並行して細かなミスが蓄積していったり、実装モレがあったりします。実装が一通り終わったという状態になっていても、どこにバグや実装モレが潜んでいるか分からない状態でテスト or デバッグをすることになります。

しかし、このステップをきれいに守ることで、何か問題が起こっていれば明確に問題の箇所が把握できます。テストしていないとか、実装し終わっていないとか、不安定な状態でいる期間が短くなります。常に動くコードをさわっているという核心を持ち、非常に安心感をもって作業ができます。

慣れてくるとビシッと歯車がかみ合った状態で1個1個作業が進んでいる感覚が得られて気持ち良いです。少なくとも読書会をやっているときはきっちりTDDのステップでコードを書き続けてみます。

2012/02/25

TDDする時は少しでもコードを書いたら即ビルド・テストを実行させる

Test-Driven Development for Embedded C (Pragmatic Programmers)」の第1章「Test-Drivern Development」 p.8に以下の記述がありました。
With every change, run the tests. The tests show you when the new code works; they also warn when a change has unintended consequences. In a sense, the code screams when you break it!
この本ではコードがテストされていない期間を可能な限り短くすることを強調していて、理想的には少しでもコードを書いたらビルドしてテストすべきと推奨しています。聞いたところによると、Kent Beckもかなり短いサイクルでコーディングとテストをまわすことを推奨しているとか。これはアジャイル開発に共通する考え方ですね。

Eclipse CDTでやる場合は、プロジェクトのプロパティ -> C/C++ Buildタブ -> Behavior -> Build on resource save (Auto build) にチェックを入れます(下図を参照)。必要に応じてビルドターゲットも設定しましょう。


実際にやってみるとちょっとした記述ミスがあると、すぐにテスト失敗が起きて知らせてくれるので割と便利です。ただし、前提としてテストが数秒で終わらないと作業が止まってので、単体テストの処理時間は短くした方がよさそうです。

それでもテストが増えてくると、そうも言っていられないと思うので、自分が開発中のところだけテストを実行するようにテスティングフレームワークの設定をしておくと良いと思います。
一部をテストさせるやり方はまた後日ブログにのせたいと思います。


2012/02/18

BlogにCoderwallのバッジを貼ろう

Githubのリポジトリの内容をかっこいいバッジで表現してくれるCodewallというサービスがあります。リポジトリの内容、言語の種類やforkされた数などを解析してバッジにしてくれます。

このサービスを利用するメリットとしては以下が考えられるかなと思います。
  • 見た目にもCodewallのバッジはかっこいい。
  • Githubの活用度合いを視覚的に表現するツールとして使える。
  • バッジを増やしていく楽しみもあり、ゲームのようで楽しい。 
バッジを増やすためにがんばる!ってのもどうかと思いますが、がんばった結果がバッジの種類や数として表現されているとなんか勲章のように感じられるかもしれません。

気に入ったので、ちょっとブログのサイドバーにつけてみました。今のところバッジ2つ。C++のリポジトリとJavaのリポジトリを持っていることの証明のようです。今度、種類と数が増やせるようにがんばりたいと思います。

#今、C言語でTDDするコードをコミットしてるので、少なくともC言語のバッジは増えると思います。

ちなみに以下のようなJavaScriptのコードを埋め込むとバッジを表示できます。”yohei1126”は私のアカウント名なので自分のものに置き換えてください。

<script="" type="text/javascript">
    function display_coderwall(args) {
        var badges = args["data"]["badges"];
        for ( var i = 0; i < badges.length; i++ ) {
            document.write('<img '"="" +="" badge"]="" height="48" src="'+ badges[i][" width="48" />');
        }
    }

  <script src="http://coderwall.com/yohei1126.json?callback=display_coderwall"/>
  
</script>


2012/02/05

「Test Driven Development for Embedded C」読書会第1回をやりました #tdd #tdd4ec

Test Driven Development for Embedded C」読書会第1回をやりました。


そもそものきっかけは、2011年の「TDD Boot Camp 東京 for C++」というイベントです。これは組み込みやゲーム業界でC/C++の開発をやっているエンジニアがTDDを実践的に演習するというイベント。

その時に私がポジションペーパーに「Test Driven Development for Embedded Cの読書会をやりたい」と書いたところ、2名が名乗りを上げくれたのでやってみようとなりました。Twitterで呼びかけたところ、10名のエンジニアが参加を表明してくれて、それなりの規模の会になりました。

参加者のモチベーションは?

参加者は、複合機、医療機器、通信機器、家電などの組み込みソフトウェアを開発しているソフトウェアエンジニアです。皆それぞれプロジェクトの中で、レガシーコード(テストコードのない製品コード)を大量に抱えていて、いつも開発時間の大半をデバッグ時間に費やすという不毛な状況に追い込まれているようです。

そのような状況に対して、どうにかしてデバッグ時間を減らすために、不具合を早期に見つけるために、解決策の1つとしてTDDを使えないかと考えていました。

今回読んだ内容

第1回の今回は、第1章「Test Driven Development」、第2章「Test Driving Tools and Conventions」、第3章「Starting a C Module」をやりました。

第1章ではTDDをやる目的、TDDとは何か、TDDをやることで得られる恩恵は何か?を書いていました。
TDDは設計手段の1つとのことで、TDDの目的の1つとして設計改善があることは挙げられます。ただ、私は最大の目的は迅速にテスト結果のフィードバックを受けることで、即場に間違いを見つけること、バグを未然に防ぐことだと思いました。この点は、皆のやりたいことと一致していると思いました。

第2章では、この書籍で扱うテスティングフレームワークの使い方を紹介していました。C向けのUnity、C/C++向けのCppuTestの使い方が紹介されていました。
googletestと同様にCppuTestは自動的にTestRunnerにテストを追加する機能もあり、TDDにはもってこいのツールだと思いました。また、C++の枯れた仕様しか使っていないとのことで、古いコンパイラを使っている人にも安心して使えるツールです。
Unityは単体ではTestRunnerに自動的にテストを追加する機能はないそうですが、Rubyスクリプトでそれを代替しているようです。

第3章では、LEDのドライバソフトを題材に本格的にTDDをやって行く手順について紹介されています。
この章の中では、組み込みの中でのDevendency Injectionのやり方として、物理的なLEDドライバのアドレスを実行時に与えるというやり方を紹介していました。実行時に物理アドレスを与える方法を取ることで、ハードウェアとソフトウェアが分離され、ハードウェアがない状態でもテストできるというメリットが得られるようです。

分からなったこと

分からないなと思ったことが2つありました。
まず1つ目は、第3章のLEDドライバの例はシンプルだからアドレスを渡すみたいな設計にできるんだということです。実際に複雑な例であれば、アドレスを書き換えることによって、別のハードウェアのステータスが変わって・・・という依存関係が複雑になる問題があるので、そういう設計にはしないよねとのこと。

おそらくは、複雑なハードウェアの相互作用、あるいは複雑なタイミングの問題などを全て再現することなく、テストしたいところだけ取り上げてテストできるようにしたりするか(いや、どうするのか分かりませんよ?)。

あるいは、もっとも底辺なレベルのテストをTDDでやらずに、もう1段上のレイヤー、ハードウェアを抽象化している部分のテストをメインにやるのではないかということ。こちらは、全てをTDDしないので網羅的ではないですが、ポイントを絞ってテストすることで、実機を使ったデバッグに専念できるようにする効果はあると思います。

2つ目はレガシーコードが大量にあるシステムに対して、どうやってTDDをやっていくのかという問題。テストを動かすまでの準備が巨大であれば巨大であるほど、最初にTDDをやるモチベーションが下がっています。現場で実戦するなら、初期コストを抑えながら、徐々にTDDを導入する方法が必要です。
どうやらレガシーコードとの戦い方は13章に書いているらしいとのことで、このあたりの考え方は後半解消できるかもしれません。

第1回を終えて

当たり前ですが、第1回では我々の疑問に対する答えは部分的にしか解消できませんでした。しかし、共通した問題意識を持っているメンバーがそろうことができたのが今日の成果だと思います。
この会を重ねていくことで、現実とどう折り合いをつけていくか、何かしらの解を出せるのではと思います。

まず、この会のきっかけを作ってくれた「TDD Boot Camp 東京 for C++」の主催者の皆さんや、「Test Driven Development for Embedded C」の著者James W. Grenning氏には感謝したいです。

さて、主催者として参加者が満足できるような会にしていきます :)


2012/02/02

#読書 2012年1月に読んだ本

なんかbooklogに月単位で読んだ本を整理する機能があったので記念ポスト。

1月に読んだ本の中では「弱い日本の強い円 (日経プレミアシリーズ)」が一番良かったですかね。為替のトレーダーの著者が為替の仕組みを紹介しています。
為替がどういう原理で決まるのか良く知らないのにFXでリバレッジをかけて大損した人多いんじゃないでしょうか?この本で基本原則を理解すると少なくとも長期的なトレンドで失敗することは防げると思います。

legobokuの本棚
2012年01月
アイテム数:5
錯覚の科学
クリストファー・チャブリス,ダニエル・シモンズ
読了日:01月17日
{book['rank']

世界でいちばん!日本経済の実力
三橋 貴明
読了日:01月17日
{book['rank']

powered by ブクログ

2012/01/14

#etrobo 2011東京・南関東・関西合同飲み会をやりました


1/14(土)に東京・南関東地区、そして関西地区それぞれで慰労会をやりました。その中で、Skypeでビデオチャットをつなげて、お互いに質問をやりとりをしてみました。

非常に有意義な会で、お互いに刺激を与え合うことができました。面白い取り組みだと思うので、やり取りの内容を乗っけてみます。

参加チーム

<東京地区>

  • 飛べ! ぼくらの夢ヒコーキ
  • StrayCab06
  • チームSUPRAパンダ
  • 田町レーシング
  • 芝浦雑伎団

<南関東地区>

  • TAKOS
  • みらいウォーカー
  • BNX
  • ほぼ組
  • AEK RUNNER11
  • マイペース

<関西地区>

  • HAK
  • 電子くん
  • R-GRAY NEXT
  • 猪名寺駅前徒歩1分
  • NEXT KOBE 
(東京・南関東地区から関西地区へ質問その1)モデルとソースコードはどこまで一致していますか? by ほぼ組

(関西地区)8~9割一致がちょこちょこです。逆に質問をしたいですが、どこまでやって100%なのでしょうか?完全にモデルから生成するだけで終わっているということでしょうか?

(東京・南関東)静的なクラス構造が一致していることです。関数内部のロジックは問いません。

(関西地区)クラス構造なら一致してるさ!

(関西地区)振る舞いなら100%だけど構造は90%とか謎のセリフも出ています。抽象的な部分は100%だけど具象化部分がもうちょっと、ということのようです。

(関西地区)そっちはどうですか?

(東京・南関東地区)静的構造の90%は一致しているけど、モデリングツールの機能的に難しいところがあり、100%には至りませんでしたた。by ほぼ組


(関西地区から東京・南関東地区へ質問その1)太陽光の影響が強いとのことですが、どのくらいですか?

(東京・南関東地区)試走と本番でセンサ値が違うのはざらです。by 芝浦雑技団

(関西地区)コース上に光の帯が出ている写真を見ましたが、その帯は移動するのですか? by HAK

(東京・南関東地区)ちょっとずつ移動しますよ。 by 田町レーシング2010大西

(関西地区)対応方法はマイマイ式だけですか?何か追加のやり方とか、そのあたりしか使わないとか、そんなTIPSがありますか?

(東京・南関東地区)マイマイを使ったのはチームSUPRAパンダさんだけでした。

(関西地区)それでも走れてしまうのですか??

(東京・南関東地区)うちは光センサ値の移動平均とってました。移動平均を取るだけで、光の帯があるとこでもコースアウトしませんでした。by田町レーシング

(関西地区)そうなんですか。意外でした。


(東京・南関東地区から関西地区へ質問その2)R-GRAY NEXTさんへ。アイコンによるトレーサビリティはどれくらい時間かかりましたか?いつごろ導入しましたか?終盤?最初から?

(関西地区)アイコンを書くのは時間は滅茶苦茶かかりました。アイコンは3~4年前から導入していたので、最初から入っていました。

(東京・南関東地区)導入したのはロボコンですか?業務?アイコン入っている業務用のドキュメントを見てみたい!byほぼ組

(関西地区)業務じゃ使うわけないですよw


(関西地区から東京・南関東地区へ質問その2)SysMLの要求図を実際に業務で使っている方はどのくらいいますか?

(東京・南関東地区)ゼロです。そちらは?

(関西地区)学生さん(電子くん)が少し使ってみたと言われています。社会人は0ですね。

(東京・南関東地区)メリットは感じましたか?

(関西地区)機能と非機能をあわせて考えられたのが良かったです。


(東京・南関東地区から関西地区への質問その3)ロボコンのモデル図やロボコンの経験を業務にどれくらい生かせそうですか?byほぼ組

(関西地区)クラス図は超役立ってます。by R-GRAY NEXT

(関西地区)シーケンス図を書いたらUMLの説明に1時間かかりました…。by HAK

(関西地区)浸透してきたら分かりやすいとコメントされているそうです。 by HAK

(関西地区)ロボコンをやって読めるから書けるにステップアップしました。 by 猪名一

(関西地区)ぼくはよめるようになりました。by みずの

(関西地区)学外の人たちと触れられたのがとても刺激的でした。 by 電子くん

(関西地区)社会人でもこうやってたくさんの社外の人と触れられてつながりが出来るのが一番大きいとは思っています。

(東京・南関東地区)はい。いい意見ですね。たぶん、こっちも同じような意見ですね。


(関西地区から東京・南関東地区への質問その3)南関東・東京では連合活動が多いですが、具体的にどんな事をしましたか? あわせて、連合でどこまで共有してどこまで企業秘密にしているか、というあたりも教えてください。

(東京・南関東地区)月1くらいでモデルレビューしたり、試走会しました。また合宿しての試走会もしました。

(関西地区)合宿!?


(東京・南関東地区)企業の研修施設で、試走したり、モデルについてディスカッションしたり、卓球したり、マッサージチェアでマッサージうけたり。。卓球とマッサージで忙しくてワークショップに遅れたチームが1つ^^;

(関西地区)何??めっちゃ楽しそう!!

(東京・南関東地区)情報共有の程度ですが、企業秘密はあまりなさそうです。ただ、終盤にモデルや競技の完成度が上がるので、結果的に一番大事な部分は共有できません。

(関西地区)コードレベルの共有もあったりしますか?

(東京・南関東地区)コードの共有はないですね。

(東京地区・南関東地区)では、そろそろコラボタイムは終わりですね。ありがとうございました。今年は、ともに上位を狙いましょう!

(関西地区)はい。お互いにがんばりましょう!!


本会を終えての所管


東京・南関東地区の方の〆の挨拶で、若いエンジニア達が企業の枠組みを超えて交流し、お互いに切磋琢磨していくことで、我々から日本をよくしていこう。経済を立て直していこうという、幾分か壮大な、でも本当にそうだと思える意見が出ました。


僕が個人の時間を使って、こういう活動をしている目的の一つと一致していると思いました。もちろん、個人の成長や仕事での成果につなげたいという個人的な気持ちはありますが。。がんばっている同世代の人たちを応援したいという気持ちが強いです。


今後も、企業とかチームとか地区とかせまいコミュニティだけでなく、参加者全体が切磋琢磨して成長していきましょう。それが自分のためにもなります。