開発生産性指標を向上させるためにやってはいけないアンチパターン

こんにちは!ファインディでFindy Team+開発チームのEMをしている浜田です。

昨今、開発生産性を高めるための取り組みを行っている組織が増えてきていると感じています。 開発生産性を向上させるためには、まずは定量的に可視化することが重要です。 可視化することで現状を把握して、開発組織の伸びしろを発見したり、課題を明らかにし、改善活動に取り組みやすくなります。

一方、定量的な指標に焦点を当てすぎてしまい本質的ではない対応をしてしまい、指標は向上したものの実際の生産性は向上していなかったり、むしろ悪化してしまうこともあります。

この記事では、開発生産性指標を向上させるためにやってはいけないアンチパターンについて紹介します。

デプロイ頻度を向上させるために、デプロイプロセスは変更せずに実施回数を増やした

デプロイ頻度はDORAが提唱するDevOpsの4つの指標(Four Keys)の1つであり、開発生産性の高い開発組織はこの数値が高いとされています。 そのため、開発生産性を向上させようと考えたときに最初に取り組むことが多い指標です。

デプロイ頻度はただ向上させるだけであれば簡単に向上させることができます。 現状のデプロイプロセスのまま実施回数を増やせば良いのです。

デプロイする回数を増やすだけでデプロイ頻度が向上して開発生産性が向上することもありますが、ほとんどの場合はデプロイ頻度だけが向上するだけで開発生産性は向上しません。

高いデプロイ頻度は、CI/CDが自動化されていたり、小さなパッチ単位でコードベースに変更を入れることができていたり、テスト自動化により変更のリスクが低減されているなど、様々なプラクティスが実践できている結果として得られるものです。

これらの前提を満たさないままデプロイ頻度を向上させることは、変更障害率が上がって障害対応する時間が増加したり、デプロイをすること自体の手間で開発する時間が減ってしまうなど開発生産性を悪化させる可能性があります。

無理やりデプロイ頻度だけを増やすのではなく、前述したプラクティスを実践するとことで、無理なくデプロイ頻度を向上させていきましょう。

リードタイムを短縮するために、全て実装し終わってからコミットする

開発生産性を可視化する際、リードタイムを指標として設定することは有効です。 なお、リードタイムには様々な定義がありますが、今回はGit/GitHubを活用し、コミットしてからメインブランチにマージされるまでの時間をリードタイムと定義します。

上記のリードタイムの定義には欠点があります。Gitの仕組み上ブランチを切った時間が記録されないため、開発に着手してからファーストコミットまでの時間が入っていません。 そこを逆手にとって、リードタイムを短縮するために全て実装し終わってからコミットするというアンチパターンが生まれます。

ただ、このようなことをしても数値だけが短縮されるだけで開発に使っている時間は変わりません。 それどころか、コミットを適切な粒度で行わないことで、コミットログが見づらくなったり、少し前の状態に戻したりすることが困難になります。 本来やりたいことは正しい指標を取得して伸びしろを見つけて本質的な改善に繋げることです。

このような数値ハックは、ただ無意味なだけではなく、コード管理の履歴が活用しづらくなったり、正しく数値を可視化していたら気づけるはずだった課題を見逃してしまう可能性もあるためやめましょう。

リードタイムを短縮するために、必要以上に細かいプルリクエストを作成する

リードタイムを短くするプラクティスとして、1つ1つの変更を小さくすることがあります。 1つ1つの変更が小さいことで、実装の時間が短くなり、影響範囲が小さいためテストも容易になり、リードタイムが向上します。

変更サイズが小さいことを可視化するためには、プルリクエスト数を指標とすることがおすすめです。 変更サイズが小さい→さくさくプルリクエストがマージできる→プルリクエスト数が増加。というロジックです。

ただ、プルリクエスト数を指標とした場合、必要以上に細かいプルリクエストを作成するアンチパターンが生まれます。

例えば一括変換でできた機械的な修正であれば、それが複数ファイルに渡っていたとしても1プルリクエストにまとめるべきです。 これをファイルごとにプルリクエストを分割した場合、プルリクエスト数は増加しますが、分割の手間やレビュアーの負荷が増加することで開発生産性は悪化します。

プルリクエスト数はあくまで適切な粒度に分割できていることを確認するための指標なので、数だけを追い求めないようにしましょう。

プルリクエストの粒度については別の記事で詳しく紹介していますので、ぜひご覧ください。

tech.findy.co.jp

レビュープロセスに時間がかかるので、コードレビューを省略してマージする

リードタイムに着目した際、コードレビューに時間がかかっていることが課題として浮かび上がることがあります。

この課題を正攻法で解決する場合、コードレビューに時間がかかっている理由を分析して、課題を解消する必要があります。

以下によくある課題と解決例を挙げます

  • レビュアーが特定の人物に集中しているのでレビュアーを増やして分散する
  • プルリクエストのサイズが大きいことでレビューに時間がかかるので、プルリクエストのサイズを小さくする
  • インデントや書き方の指摘が多いので、リンターやフォーマッタを導入して機械的に検知できる指摘は自動化する
  • 指摘が多くなりやり取りに時間がかかっているので、ペアプロ/モブプロを導入する

一方でレビューにかかっている時間を最も簡単に削減する方法はコードレビューを省略することです。

ただし、コードレビューを省略することはお勧めできません。 コードレビューをすることでバグの発見やコード品質の向上につながったり、コードの内容を実装者とレビュアーで共有することでコードの属人化を軽減できたり、レビュアーの目を通すことで第三者が読みやすいコードになり保守性が向上します。

コードレビューはとても有意義な活動なので、省略せずに根本解決することで有意義にレビューしつつリードタイムを向上させましょう。

プルリクエストのサイズを小さくするためにテストコードを別のプルリクエストにする

意味のある最小単位でプルリクエストを作成して、小さい単位でサクサクマージしていくことは開発生産性を向上させるための有効なプラクティスです。

プルリクエストを小さくする際、テストコードを別のプルリクエストに分けたくなることがあります。 1つ目のプルリクエストでテストコードなしのコードのみ実装して、2つ目のプルリクエストでそのテストコードを書くという方法です。

この方法はプルリクエストのサイズを小さくできますが、一時的とはいえテストコードで守られていないコードがメインブランチに混入することになります。 テストで守られていないコードは何かしらの変更で不具合が混入しても気づくことができないため、品質低下につながります。 また、すぐにテストコードが追加されれば良いですが、別にすることでテストコードの実装を忘れてしまう可能性も高まります。

コードと対応するテストコードは1つのプルリクエストに含め、テストコードで守られていないコードがメインブランチに混入しないようにしましょう。

変更障害率を下げるために、デプロイ頻度を下げる

変更障害率はDORAが提唱するDevOpsの4つの指標(Four Keys)の1つであり、デプロイを起因とした本番障害の発生確率を指しています。 また、開発生産性に関係なく、変更障害率は関係者全員が低く保ちたいと願っているのではないでしょうか。

本番障害が発生する最大の原因はデプロイで不具合を混入させてしまうことです。 そのため、デプロイすることに慎重になり、デプロイ頻度が低下してしまうことがあります。

しかし、変更障害率を下げるためにデプロイ頻度を下げることはアンチパターンです。

デプロイ頻度を下げて、1回のデプロイに含まれる変更量が増えることで次の問題が発生します。

  • 変更内容が複雑になり、相互作用や予期せぬ結果が発生する可能性が高くなり、本番障害が発生するリスクが高まる
  • テスト範囲が広くなるため、テスト漏れが発生する可能性が高くなり、本番障害が発生するリスクが高まる
  • 障害が発生した際、原因特定に時間がかかり、平均修復時間が増加する
  • 影響範囲が大きくなるため、障害の影響範囲が広くなる可能性が高まる

変更障害率を下げるためのプラクティスは、デプロイ1回あたりの変更量を小さくすることです。 変更量が小さいことで、変更範囲を正確に把握できるので、テストが容易になってテストのリードタイムを短縮できたり、テスト精度が向上することで品質が向上します。 また、頻繁にデプロイするためには自動テストを充実させることも重要です。自動テストが充実していることで既存機能が壊れていないことを自動的に確認できるためリードタイムの向上や品質の向上につながります。

デプロイを過度に恐れず、デプロイあたりの変更量を小さくしたり、自動テストを充実させるなど開発生産性を向上させるプラクティスを取り入れることで変更障害率を下げましょう。

変更障害率を下げるために、hotfixでの対応を出し惜しみする

変更障害率を可視化するために、hotfixの数から算出することがあります。

前述した通り、変更障害率は誰もが低く保ちたい指標です。 そのため、本来はhotfixで即対応した方がベストだとわかっている場合でも、通常フローで対応してしまうことがあります。

hotfixを使わないことで、変更障害にカウントされないので結果として変更障害率は下がるかもしれません。 ただし、hotfixを使わなかったからといって発生した障害がなるなるわけではありません。 また、本来は変更障害率に計上されるべきものを計上しないことで、振り返りなどで課題に気づきづらくなり、自分たちの成長機会を妨げる可能性があります。

開発生産性の可視化を自分たちの成長機会に繋げるためにも、数値を良くすることばかりに注目するのではなく、正しく取るように心がけましょう。

まとめ

ここまでで紹介したアンチパターンは開発生産性の数値を高めるための組織の能力に注目せずに、数値を向上させることだけを目標に設定してしまったために発生しているものが多いです。

このことは「グッドハートの法則」として広く知られています。

以下、ChatGPTによる説明です。

グッドハートの法則(Goodhart’s Law)は、経済学者チャールズ・グッドハートが提唱した概念で、「特定の統計的指標が政策目標として使われると、その指標はもはや信頼できるものではなくなる」という法則です。 つまり、ある指標が目標となると、人々はその指標を達成するための行動を取り始めるため、指標自体の本来の意味や有用性が失われるということです。

定量的な目標を設定することは開発生産性の現在地を把握するためには有効ですが、目標を達成するために本来備えておくべき能力を理解せずに数値だけを追い求めないようにしましょう。

なお、開発生産性の高い組織を目指すために備えるべき能力は、Google CloudのDevOpsの能力がとても参考になります。

また、DORA Core Modelにも開発組織のケイパビリティと開発生産性指標との関係が示されていますので、ぜひ参考にしてみてください。

出典: DORA’s Research Program


6月28日(金)・29日(土)に『LeanとDevOpsの科学』の著者であるNicole Forsgrenの来日、テスラ共同創業者元CTOの登壇など、国内外の開発生産性に関する最新の知見が集まるConferenceを開催します。 開発生産性に関する他の企業の取り組みや海外の事例に興味がある方は、ぜひお申し込みください!

dev-productivity-con.findy-code.io