ペアプログラミングとテスト駆動開発でアプリ開発の課題を解決
本セッションの前半は、山下真一郎氏が「ヤフオク!公式アプリが品質と技術を高めるために取り入れた開発手法」について語った。
山下氏が担当しているヤフオク!公式アプリが抱える課題は大きく分けて2つある。
1つ目はビルド時間が増え続けていること。ヤフオク!公式アプリのリリースは2010年で、以後6年以上開発が続いている。その間、さまざまな機能が追加されてソースコードの量が膨大になった結果、ビルド時間も大幅に増加してしまった。ビルドの待ち時間が増えた影響で開発効率も低下している。
2つ目の問題は単体テストが書きにくい設計になっていること。自動化できる単体テストの総量が少ないため、それだけでは全機能の動作を保証することができない。手作業のテストで品質を支えている状態だが、時間がかかるためコードを変更してからリリースするまでのリードタイムも増加している。
「開発フローを見直さなくてはいけない」、そんな課題感をメンバー全員が持っていた。
これらの問題を解決するきっかけとなったのが、アジャイル開発が体得できるサービスを企業向けに提供するPivotal Labs社での修行である。同社では「リーンソフトウェア開発」、アジャイル開発の一種である「エクストリームプログラミング」を実践している。
リーンソフトウェア開発は「ユーザーに価値のあるものを届ける、それ以外は全てムダ」という考え方、エクストリームプログラミングはソフトウェア開発をするときのルールを定義した開発手法である。両者を組み合わせた開発手法をPivotal Labs社では「LEAN XP」と呼んでいる。参加メンバーは同社で2カ月間LEAN XPを学び、ペアプログラミングやテスト駆動開発を実践。Yahoo! JAPANに戻ってからもシャドーイングしている。
LEAN XPはプロダクトマネージャー、デザイナー、エンジニアが三位一体で開発していく手法であり、特徴の1つに、エンジニアが必ず2人1組のペアでプログラミングを行うことが挙げられる。
始めに、プロダクトマネージャーが開発する機能を小さく分解する。それらに優先順位を付けてから各ペアにタスクを割り振っていき、各ペアは実装を始める。
次の日、各タスクには前日の担当者が必ず1人残り、新しい人とペアを組む。そこで前日の担当者は、新しく来た人に仕様を説明する。ペアは毎日入れ替わるので、結果的にチームは、案件の仕様に全員詳しくなる。
「このペアプログラミングにより、メンバーは自分が今まで知らなかった実装方法、トラブルシューティング、ショートカットなどさまざまなことを学習し、技術力が短期間で一気に底上げされた」と、山下氏は語る。
ペアプログラミングではソースコードの共同所有という考え方が意識され、山下氏のチームでもそれを徹底している。担当タスクと無関係な場所で問題を見つけた場合でも積極的に解消するなど、助け合いの精神が非常に強くなっている。
ただ、ペアプログラミングには「プライベートな時間が確保しにくい」という側面もある。「私のチームではペア以外で作成したコードは認めていないので、仕事は定時までやって、その後は速やかに帰るよう促している」という。
チームに変化を与えるために、山下氏が重要だと考えているのがテスト駆動開発である。この手法はペアプログラミングと非常に相性が良い。ペアには「ナビゲーター」「ドライバー」の役割がそれぞれ与えられる。最初にナビゲーターが失敗するテストを書き、次にドライバーがテストを通すコードを書く。このコードはテストを通すため、最小限の設計になっている。テストが通ると、ナビゲーターがリファクタリングを行う。テストをパスした実績があることにより、安心してコードを大胆に書き換え、整頓することが可能になる。
しかし、エンジニアに「失敗するテストを書いてほしい」と言っても、いきなりそれを実行するのは難しい。そこで、プロダクトマネージャーは失敗するテストを書きやすくするためのタスクを準備する。
タスクの優先順位と粒度は、プロダクトマネージャーが管理する。それぞれのタスクは、ペルソナ(架空の顧客像)から生まれている。まずは「ペルソナがアプリを起動し、終了する」までの一連の流れからシナリオを抽出する。そこからタスク(LEAN XPではストーリーと呼ばれる)へ分解していく。
ヤフオク!公式アプリの例では、「ケンジ(人名)がJRの中央線でアプリを立ち上げ、ポールスミスのシャツをウォッチリストに登録し、入札する」までの流れを追っている。ポイントは実際にユーザーの気持ちになり、物語を作成することだ。リアルな文章を作成することで、起きうることを実感することができる。
ロジックとデータポイントを抽出すると、その一つひとつが複数のストーリーになる。ウォッチリストに登録するのがロジックで、商品の名前や価格がデータポイントだ。
ストーリーは受け入れテストをしやすくするため、最小単位になっている。例えば「ケンジが商品詳細画面上の入札ボタンをタップすることができる」流れを、ケンジになったつもりでストーリー文にすると以下の通りになる。
- GIVEN 私は商品詳細画面を表示している
- WHEN 私は「ウォッチリスト登録」ボタンを見た
- AND 私はその隣に「入札する」ボタンを見た
- THEN 私は「入札する」ボタンをタップすることができるはずだ
頭にある英語の接続詞は、ガーキン(Gherkin)フォーマットと呼ばれている。GIVENは「前提条件」、WHENは「もし」、ANDは「かつ」、THENは「ならば」である。このフォーマットはエンジニアがテストを書きやすくし、非エンジニアでも理解できるものである。また、ストーリーの粒度を一定にすることにも役立つ。
ストーリーを書いて優先順位が確定したら、プロダクトマネージャーからエンジニアにストーリーを渡す。IPMと呼ばれる見積もりミーティングを実施し、エンジニアに「それぞれのストーリーがユーザーにとって価値があるものか」聞いていく。そして技術的な課題の検討が終わったら、ジャンケン見積もりを開始する。
実装はテスト駆動開発で行い、完了したらエンジニアではなくプロダクトマネージャーが受け入れテストを行う。重要なポイントは、「作った人がテストをしない」ことだ。
LEAN XPを取り入れた結果、以前のプロジェクトと比較して、受け入れテストの失敗率が20%から3%に激減した。さらにリードタイムも1/8まで削減できた。
実は、LEAN XPを取り入れたこのプロジェクトの前に、山下氏は凍結してしまったプロジェクトを経験していた。そのプロジェクトでは受け入れテストの失敗率が高く、さらにテストの内容も粗いものだった。現場の雰囲気もどんどん悪くなり、途中まで作ったものをリリースすることができず、苦い思いをした。しかし、「今は小さく価値のあるもの順に作り、常にリリースできる状態にしているので、変化に強いチームになったと感じている」と力強く語る。
山下氏は最後にまとめとして、Pivotal Labs社で学んだ、3つの重要な考えを提示してセッションを締めくくった。
- より小さくより価値の高いもの順に実装を行う
- 単体テストが壊れたら最優先に修復する
- 自分の実装は自分以外が確認する
アジャイル開発におけるテスト自動化を自発的に行わせるためのアプローチ
セッションの第2部のメインテーマは「テスト自動化」で、伊藤宏幸氏が社内コーチとして行った現場支援の事例をベースに語られた。
昨今「Time to Market」の短縮が要望されているが、同時に品質の維持も求められている。となると「テスト自動化は製品開発の必須要素」である。
ただ、テストの自動化自体が難しいイメージを持たれている。現場からは「どう実施すればいいのか? 本当にメリットがあるのか? 工数が余計にかかるだけでは?」と、懸念が聞こえてくる。
伊藤氏たちコーチの役割は、そうした疑問に一つひとつ回答して施策をドライブすることで、テスト自動化が自発的に実施されるようにすることにある。
まず、テストの自動化はどのように始めればいいのか。伊藤氏らYahoo! JAPANのコーチは、原則としてユニットテスト(単体テストと同義)から始めることにしている。1つ目の理由は、他の受け入れテストや結合テストなどと比較して導入が簡単で、すぐに効果を出すことができるからだ。2つ目の理由は、ユニットテストは実行が簡単な上に実効性が高いこと、つまり各種テストの中で最もROIが高いといえるからだ。
こうして自動化に取り組み始めると、座学やワークショップに参加したり、実際にテスト自動化を実践している現場の見学に行ったりしがちだ。しかし伊藤氏は自らの経験から「ほとんど役に立たない!」と断言。「ハンズオンなどで実際に手を動かして、その価値を“体感”しない限りは効果が見込めない」と語る。
そこで伊藤氏は、次の学習方法を提案。
まずは学びのフリークラウドサービスCyber Dojoでテスト駆動開発やペアプログラミングを“体感”する。次にプロダクションコードへユニットテストを追加。つまり即実践で鍛える。そして必要になってから、理論やテクニックを学ぶ。
伊藤氏はここでCyber Dojoのデモを実施。Cyber Dojoは、5人から10人の集団でテスト駆動開発やペアプログラミングを学ぶには、非常に有効なサービスだという。
デモを終え、続いては「テスト自動化を進める上で、注意するべき落とし穴とその回避方法」が、アンチパターンとして紹介された。
1つ目は「コードカバレッジの罠」。伊藤氏がコーチングしたチームで、コードカバレッジの達成が自己目標化してしまっている事例が挙げられた。これでは「品質の確保」というテスト本来の目的を見失ってしまう。伊藤氏は「『価値あるテストを作る』という意識付けが必要」と痛感。障害が頻発する箇所などを重点的にテストし、そこを集中して自動化することがポイントとなる。
2つ目は「プロダクションコードが複雑すぎて解読できない場合」の対処法だ。伊藤氏は「テストをしやすくすればいい」と語る。まずはテストを補助するツールを探し出して適用する。例えばJavaなら「Mockito」、PHPなら「Phake」「AspectMock」といったものである。
また、テストを実施しやすいアーキテクチャに変えることも重要だ。そのためには仕様化テスト(現状のコードをベースにして作成するテスト)を整備した上で、リファクタリングを行うと良い。
3つ目の落とし穴が「目的を見失い、作業がマンネリ化する」ことである。改善活動を継続していくと、伸び悩み(プラトー)が生じる。しかし「そういうときこそ、壁を乗り越えてさらに伸びるチャンス」と、伊藤氏は語る。コーチにはチームに適切な刺激を与え、自発的な成長を促すことが求められる。
一番の解決策は「短期の目標設定と振り返り」を行うことだ。定期的に目標を設定させ、一定期間が経過したら目標の達成度合いを確認し、KPTベースで振り返りを行う。そして定期的かつ自発的に、次の改善アクションを提案・実施させる。このような刺激を与えるだけでも効果があり、自発性が刺激されてチームメンバー自ら解決策を考え出すようになる。
もう1つの解決策は「自主的なテストルールの策定」である。チームにテストのコーディング規約やテスト範囲などを決めさせ、ルール自体の定期的な見直しなどをしていく。すると自分たちで考えるクセがだんだんとついていき、そのチームがどんどん成長していく。
いずれにしても重要なのは「目的のために、良い手段を選ぶ」ことだ。
続いて、伊藤氏は「テスト自動化のためのステークホルダーマネジメント」について解説。
伊藤氏はある日、コーチングしていたチームから相談を受ける。内容は「部長、リーダー、サブリーダーからそれぞれ別途にチームの活動目標を提示するよう求められたため、チームが混乱状態に陥ってしまった。どう対処すればいいのか」というものだ。
調査の結果、ステークホルダーの人数がそもそも多い問題が判明した。それだけではなく、ステークホルダーごとの情報伝達度に差があり、ステークホルダー間の情報共有もうまくできていなかった。つまり、コミュニケーションマネジメントに問題があるということだ。
そこで伊藤氏は「コミュニケーション管理をやるべきだ」と提案。それに対しチームは「私たちはエンジニアだから、ユニットテストのコードを書くことに集中したい。ステークホルダーたちの問題だから、自分たちは関係ない」と主張し、状況を自ら改善することに消極的だった。しかし「情報の交通整理はステークホルダーを喜ばせる。それは仕事に集中できる環境作りにプラスとなるし、テスト自動化実現のための立派な行為である」と、伊藤氏は説得。
その結果、チーム自らステークホルダー全員が会する場を設定し、腹を割って話す機会を設けてくれた。すると、わずか30分間で必要な情報共有と次のアクション決めが達成され、全ての問題が解決した。
この成功体験から、そのチームは自発的にステークホルダーとの調整を進め、情報の齟齬がないよう振る舞うように変わった。現在、チームはコーチ陣の手を離れて自走しているという。
このように、テストの作成に集中でき環境を作ることも、立派なテスト自動化といえる。そのためにも、適切なステークホルダーマネジメントは重要だといえる。
伊藤氏は最後に「ここまでお話したことが“当たり前”ではなく、できないのであれば、そのチーム・組織・会社には問題があるといえる。そうした問題を解決・克服して“当たり前”に振る舞えるか? それが、市場で勝ち続けるための品質を確保することにつながるだろう」と語り、セッションを終了した。
お問い合わせ
ヤフー株式会社