はじめに
今回の現場はレガシーな現場で、TDDが浸透しておらず、今回試みた結果を展開しようかと思います。
なお、TDDとはなにか?については触れません。知りたい方は以下の動画・書籍がオススメです。
- 動画:50 分でわかるテスト駆動開発(de:code 2017):概要を理解するのに一番良い。
- 書籍:テスト駆動開発:理論を理解するのに一番良い。「付録C:訳者解説:テスト駆動開発の現在」から読むのが理解しやすいと思ってる。
- 書籍:実践テスト駆動開発:BDDとかそこらへんを理解するために。
個人的には、上から順番に見ていくのが一番理解しやすいと思う。
「書籍:テスト駆動開発」の第一章はすごく癖のある書き方なので、正直、読みにくい。
動画では、読みにくかった部分が、非常に分かりやすく解説されているので、ぜひ動画から見ることをオススメします。
そのあとは、第一章を写経するのがおすすめです。
TDDを現場に導入した話
「[speaker deck - 50分でわかるテスト駆動開発 / TDD Live in 50 minutes](https://speakerdeck.com/twada/tdd-live-in-50-minutes)」より引用前提
- 現場について
- 会社について(正確に言えば、所属部門について)
- いわゆるSIer
- 他部門ではサービス開発とかもやってる
- 対象システムについて
- 金融業界
- サーバサイド系(オンプレ・Java)
- WEB-APIが基本。バッチ処理および、管理者用画面もある。
- 開発プロセス・文化・体制とか
- 50名くらいの保守開発(新規開発ではない)
- 開発はスクラムのプロセスに則って行っている。(Undoneをいかに減らすか日々悩んでる)
- CI/CDは導入済み。(jUnitテストもちゃんと書いてる)
- TDDに関して
- 大半のメンバーはTDDについて「聞いたことがある」程度の理解。
- 一部メンバーは実践したことはあるが、現場適用の仕方をイメージできてない。
- 会社について(正確に言えば、所属部門について)
- 私について
- 組織に対する信頼貯金がそこそこある状態(10年目)
- TDDについては以下で学習した状態
- この現場には、配属されて1週間。(横のプロジェクトだったので、以前から話は聞こえていた。)
- スクラムマスターとして配属された。
なぜ、TDDを導入しようと思ったのか?
以下を期待してTDDを導入しました。
-
TDDを組み込む。
-
TDDを組み込むことによって、リファクタリングがプロセスに組み込まれる。
-
リファクタリングがプロセスに存在する = ソースコードの変更容易性を維持/向上する機会が存在する & より良いコードを追求する機会が存在する
-
ソースコードの変更容易性を維持/向上する機会が存在する = ビジネス変革についていける可能性が高まる
-
より良いコードを追求する機会が存在する = プログラミング力を上げる機会が増える
TDDが実現するのは「~する機会を提供する」までだと思っています。
その機会を活かして「ビジネス変革についていけるシステムを実現する」「プログラミングの技術力を上げる」のは、開発者次第。
とはいえ、そういった機会はあったほう良いので、ぜひ導入すべきだ!と決意しました。
(お客様や自社内に対しても同じ説明をして、納得してもらった。)
結論
さきに結論書いちゃいますが、導入はうまく行きました。(お客様・上長・現場の3者が喜んでいる状態)
期待した効果がでているのか?については少し長い目で見ないと分からないので、引き続きウォッチしていきたいと思っています。
「やったこと」と「わかったこと」
推進役の選定
[^手旗信号をする黒子]◆なぜこのアクションを行ったか?◆
このアクションは、どのような課題を解決したくて行ったのか?
- 「カイゼン」ができる人を増やしたい。
- 「現場目線」で現場に伝わるようにするには、現場の人間が説明するのが良いと思ったから。
◆やったこと◆
- 意欲的なメンバー(8年目)を「推進大臣」に任命
- 一緒に進め方を話し合う
- 部分的な試行
- 全体展開のための説明資料作成
- 既存のプロセスとの差異など
- 任せる&背中を見せる
- 「方針を共有」した上で、まず任せる。
- 「任せたけどできない」場合 → 「方法」を一緒に具体化する。
- 「方法は分かるけど、できない(具体的なイメージが沸かない)」場合 → 「実際にやってみせる」(背中を見せる)
- なぜ推進大臣に任命したのかの「期待」をちゃんと説明する。
- 誰にどんな期待で任せるのかはケースバイケースですが、自分が任命した相手にはこんな期待を寄せていました。
- 「カイゼン」ができる人が増えて欲しい。
- 現場も分かってて、意欲もあり、ちゃんと学習ができているメンバーは少ない。
- ぜひキミにお願いしたい!
- 誰にどんな期待で任せるのかはケースバイケースですが、自分が任命した相手にはこんな期待を寄せていました。
- 一緒に進め方を話し合う
基本的には二人三脚で進めるようなイメージ。
必ず推進大臣を立てる。
「立てる」は、「役割として任命する」かつ「リスペクトして任せる」の両方の意味で。
◆わかったこと◆
- 基本的に、「方針」・「方法」・「実践」の3段階での説明が必要。
- 一気にやっても伝わらない。相手の段階をみきわめながら説明することが大事。
- 上記3段階以外に「根回し」という作業が存在する。
- 組織の方向性とフィットしないと、思わぬ攻撃を受けることがある。
- 「根回し」は勘でやってる人が多いので、ノウハウが伝達されにくい。
- 今回は自分がやってしまったが、伝達していかねば・・・
部分的な試行
[^浄土平にかかる一部改修された木道]◆なぜこのアクションを行ったか?◆
このアクションは、どのような課題を解決したくて行ったのか?
- いきなり全面適用すると、影響が多き過ぎて、現場が混乱するため。
◆やったこと◆
所属プロジェクトでは、スクラム開発をおこなっているのが3チームありました。
その内、1チームを対象に導入してもらいました。
具体的には以下です。
- TDDについての理論面の説明(講義形式で30分)
- 「動画:50分でわかるテスト駆動開発 by t-wadaさん」のデモ部分を省略しつつ説明。
- このプロジェクトとしてTDDをどう定義したか?
- TDD自体は「品質保証」ではなく、「開発者支援」という位置づけである。(賛否あるのは知ってる)
- jUnitテストコード自体は 最終的には 「品質保証」という役割を担ってもらう。(そのようにリファクタリングするか、もしくは別途作成すること)
- 実践(モブプロで90分:実際の案件を通して実践してもらった)
- 実際にやったこと
- 「Todoリストを書いて下さい」
- 何を書けば良いか分からず止まってしまう ← 「最終的に何を実現したいかを書いてみよう!」
- 最終的なゴールを書いて止まってしまう ← 「具体的に、どんな引数で、どんな結果が返ってくることを期待してる?」
- 書けた。(ひとまず)
- 「Todoリストから一つ選んで、テストコードを書いて下さい」
- 何を書けば良いか分からず止まってしまう ← 「テストコードの一番下から書いていこう。assert文はどう書く?」
- 「assertしてる内容」と、「todoリストで選んだ内容」が異なる ← 「今やってるのはtodoリストから選んだヤツ?違うなら、別のtodoとして扱おう。」
- 最低限のテストコードが書き上がる。
- 仮実装でのRed/Green/Refactorの実践
- 動かすと、当然Red。 ← 「期待通りRedになったね!良かったね!次はGreenにしてみよう!」
- 最低限Greenにできる実装をする。 ← 「やった!進んだね!これが仮実装だよ!仮実装はテストコードのテストという役割もあるのを知っておこう!次はRefactorだ!」
- 実コードをちゃんと書いてくれる ← 「いいね!ちなみに、三角測量ってやり方もあってね・・・(割愛)」
- みんな理解できた。
- 「Todoリストを書いて下さい」
- 実際にやったこと
- 現場からのQA対応
- Q:「TDDの方が効率的なんですか?」
- A:「正直にいえば、製造作業に限って言えば、やること増えてるので、作業量増えます。ただ、単体テスト実装を先に出来ていたり、リファクタリングを通してプロダクトとしての品質が上がることで、手戻り減少等を踏まえ、開発全体で見た時に効率的になることを期待しています。」
- Q:「本当に品質は上がりますか?」
- A:「TDDはサポートするだけです。品質をあげるのは開発者であるみなさんです。リファクタリングがプロセスとして組み込めたり、テストファーストな考え方になっていったりすることで、開発者としてのスキルを追求する機会が増え、結果としてスキルが上がり、さらにその結果として品質が上がる、そんな流れを期待しています」
- Q:「TDDの方が効率的なんですか?」
◆わかったこと◆
- 若手メンバーからの意見
- 「TODOリスト」で何を実装しているかが明確になるので、分かりやすい。
- TODOリストが無いと、横道にそれた瞬間に、混乱してしまう。(自分が分かってないのか、横道にそれたのか判断できない。)
- 「下から書く」ので、次に実装スべき内容をIDEが教えてくれるので、分かりやすい。
- 上から書いていく場合、たまについて行けてない時がある。(そのコードがなぜ必要なのかが分からない)
- 「TODOリスト」で何を実装しているかが明確になるので、分かりやすい。
- ベテランの新規参画メンバーからの意見
- 「テストを実行しながら実装する」ので、既存の挙動を理解しやすい。(特に、カバレッジ取得しながらやると、どこまで動いたか一発でわかるので、楽。)
- 私的な気付き
- テストコードのメソッド名を日本語にするだけで、こんなに読みやすくなるとは!(既存のテストコード読みにくい。すごい読みにくい。)
全体説明
[^ホワイトボードに書いて説明する美人広報]◆なぜこのアクションを行ったか?◆
このアクションは、どのような課題を解決したくて行ったのか?
- TDDに対する理解度を上げ、「これからはTDDやるんだ!」と現場に認識してもらうため。
◆やったこと◆
- 説明資料のための材料は自分が用意。
- 現行プロセスとの違いはどこか?
- なぜそのような基準にしたかの根拠
- 「既存のプロセス」をベースに「JSTQB - Foundation Level Extension シラバス アジャイルテスト担当者」の内容をマージ。
- 結果としては、「JSTQB - Foundation Level Extension シラバス アジャイルテスト担当者」をベースに、「既存のプロセス」を味付け。程度になった。
- 説明会自体は、「推進大臣」にお任せ。
- 自分がしゃべってしまうと、本当に現場に伝わるのか怪しいので、現場が長い「推進大臣」におまかせする。
- 「推進大臣」がちゃんと理解してしゃべれるなら、きっと現場に伝わるだろう、という期待から。
◆わかったこと◆
- 現場キーマンを全部巻き込むと、質問が出てこない。一部は「あえて巻き込まない」っていうふうにしても良かったかも。(現場の理解度向上を考えると、質問が出たほうが望ましい。)
TDD導入に際して悩んだこと
[^グラビアポーズが悩んでいる姿にしか見えない黒子]TDDはどういう場面で使うべきか?
- テスト駆動開発(TDD)は以下の条件に合致した場合に実施する(無理にTDDで開発しなくても良い)
- これから作るプログラムの入力と出力の仕様が明確である
- なおかつ、テストコードの書き方がぱっと頭の中に思い浮かぶ
「Qiita - 【初心者向け】テストコードの方針を考える(何をテストすべきか?どんなテストを書くべきか?)」より
TDDは開発スタイルの一つですし、フィットする場面とフィットしない場面とあると思います。(言うほどTDDで実践できてないので、まだ自分の中で基準が明確ではない。)
現場がTDDに慣れていない場合は、慣れることを目的に、一定期間強制的にやってもらうとかはありだと思っています。(当然、ちゃんと現場のアラートに気づいて対処できる人が居る場合に限るけど。)
今回は「一定期間は強制」と宣言し、「一定期間後は自由」としています。(1~3ヶ月くらいの予定。現場の雰囲気を見て解除予定。)
「TDDのテストコード(開発者支援)」と「テストとしてのテストコード(テスト)」は地続き?別モノ?
(前略)「新機能をテスト駆動で開発するところで活躍してくれたテストだけど,そういう小さいテストたちは今やもう役目を終えたので,メンテナンス対象から外してしまいましょう。消してしまいましょう」(後略)
「[動画で解説]和田卓人の“テスト駆動開発”講座」より
※2007年の記事ですので、あしからず。(古い情報なので、ご本人の意見も変わってるかもしれない。)
直接は表現されてないですが、この表現から見るに、t-wadaさんは「地続き」っぽいように読み取れる。
また、手近な範囲でヒアリングしてみたんですが、「地続き派」と「別モノ派」はそれぞれいるっぽい。
ちなみに、自分個人は「地続き派」。テストコードもリファクタリングしていけば、ちゃんと「テスト」に相当したテストコードになるという体験から。
なお今回の現場では、最終的に残すのは「テストとしてのテストコード」という宣言だけして、地続きで作るか、別モノとして作るかは、開発者におまかせしました。(ここまで強制させるのはちょっと自由度が低すぎると思ったので)
リファクタリングのゴールをどう定義するか?
個人的にはリファクタリングを推進していきたい。TDDを入れた理由としても、個人的には「リファクタリングをプロセスに組み込めること」が大きい。
なぜなら、悩んで考えてリファクタリングを多く実践することが、プログラミングスキルの向上につながると思っているから。(特に根拠は無いけど)
でも、リファクタリングをやってきてない文化でリファクタリングを導入しても、ぶっちゃけ大してリファクタリングはされない。
なぜなら、どういう時にリファクタリングをして良いのか分からないから。
ひとまず、「新装版 リファクタリング―既存のコードを安全に改善する― 」や「増補改訂版Java言語で学ぶデザインパターン入門」をみんなの見える位置に置くくらいで留めてます。
リファクタリングの推進は次のステップで考えようかなーって、ぼんやり考えてます。
TDDを導入してみて
個人開発ではTDDでやってたんですが、実際の現場でTDDやってなかったんですよねー。
実際に導入してみて思ったのは、「既存の開発でのTDD導入は、既存テストコードに大きく依存しそう」という印象。
また、すでにjUnitテストコードをちゃんと書いている現場なら、すぐにでも導入できるな。と感じました。
あと、jUnitテストに時間がかかりすぎていると、TDDのサイクルがうまく回らないので、廃れていきそう。
廃れる前に、如何にスリム化するかが次の課題だなーと感じております。
さいごに
「TDDについては、オレに語らせろ!」みたいな方も多いと思います。
ぜひコメント欄にでも聞かせて下さい!
あ、マサカリは、オブラートに包んで欲しい派です。ご容赦下さい。
以上です!
-
ちゃんと写経しました。写経すると理解度が全然違うなぁと、やってみて感じた。 ↩