1. ホーム
  2. unit-testing

[解決済み] 既存のプロダクションプロジェクトにユニットテストをうまく追加することができますか?もしそうなら、どのように、そして、それは価値があるのでしょうか?

2022-04-28 09:48:02

質問

生産中の既存プロジェクトにユニットテストを追加することを強く検討しています。それは、私がTDDの利点を本当に理解する前に、1年半前に開始されました。 (顔面掌握) そのため、現在では多くのプロジェクトを含むかなり大規模なソリューションとなっており、ユニットテストを追加するために何から始めればいいのか見当もつきません。私がこのことを考えるようになったのは、時々古いバグが再浮上してきたり、バグが修正されたとチェックインされても 本当に を修正しました。ユニットテストは、このような問題の発生を抑えたり、防いだりすることができます。

読むことで 同様 SOの質問で、バグトラッカーから始めて、回帰を防ぐためにバグごとにテストケースを書くなどの推奨を見かけました。しかし、私は、全体像を見失い、最初からTDDを使用していれば含まれていたであろう基本的なテストを見逃してしまうことになるのではないかと心配しています。

既存のソリューションが、より良いものであるために、遵守すべきプロセスやステップはありますか? 正しく ユニットテストが必要ですか?どのようにすれば、テストが良い品質であること、また、単なるケースとしてではなく テストはないよりあったほうがいい .

だから、私が聞いているのも、そうなんだと思います。

  • のために努力する価値はありますか? 既存のソリューションが稼働しているか?
  • テストは無視した方がいいのか? このプロジェクトでは 将来的に書き直す可能性がありますか?
  • をかけるのと、どちらが有益でしょうか? 数週間かけてテストを追加するか、数週間かけて 機能を追加するのに数週間かかるか?

(もちろん、3つ目のポイントに対する答えは、あなたが経営者と話しているのか、それとも開発者と話しているのかによって、まったく異なります)


懸賞金の理由

懸賞金を追加することで、より幅広い回答を集めようとするもので、私のこれまでの疑念を確認するだけでなく、反対の理由もいくつかあります。

私はこの質問を後で書いて、将来の製品開発をTDDに移行するために工数を費やす価値があることを経営陣に示そうと、賛否両論を述べようと思っています。私はこの課題に取り組み、私自身の偏った視点を持たずに自分の推論を展開したいのです。

どのように解決するのか?

以前はユニットテストを導入していなかったコードベースに、ユニットテストを導入したことがあります。私が関わった最後の大きなプロジェクトでは、私がチームに参加したとき、その製品はすでに生産に入っていて、ユニットテストはゼロでした。2年後に私が退職したときには、230,000以上のプロダクションLOC(リアルタイム金融Win-Formsアプリケーション)のコードベースで、約33%のコードカバレッジをもたらす4500以上のテストがありました。この数字は低く聞こえるかもしれませんが、結果的にコード品質と欠陥率を大幅に改善し、さらに士気と収益性も向上させることができたのです。

関係者の正確な理解とコミットメントの両方があれば、それは可能なのです。

まず、ユニットテストはそれ自体がスキルであることを理解することが重要です。従来の基準では非常に生産的なプログラマーであっても、大規模なプロジェクトでスケールするような方法でユニットテストを書くことに苦労することがあるのです。

また、あなたの状況に特化して言えば、テストがない既存のコードベースにユニットテストを追加することも、それ自体が専門的なスキルなのです。あなたやあなたのチームの誰かが、既存のコードベースにユニットテストを導入することに成功した経験がない限り、私は、以下の本を読むことをお勧めします。 フェザーの本 は必須条件です(オプションや強く推奨するものではありません)。

コードのユニットテストへの移行は、コードベースの品質と同様に、人材とスキルへの投資となります。このことを理解することは、考え方や期待値を管理する上で非常に重要です。

それでは、コメントと質問をお願いします。

<ブロッククオート

しかし、最初からTDDを使っていれば入っていたはずの根本的なテストが抜けてしまい、全体像が見えないまま終わってしまうことが心配です。

短い答えです。そうです、テストは失敗するものです。また、当初は未知の状況でのテストとは異なるかもしれません。

深いレベルの答えはこうだ。それは重要ではありません。テストがない状態からスタートします。テストを追加し、リファクタリングしながら進めていきます。スキルレベルが上がったら、プロジェクトに新しく追加されるコードのハードルを上げ始める。改善し続けること...

さて、この行間を読むと、「行動を起こさない言い訳としての完璧さ」という考え方からきている印象を受けます。もっと良い考え方は、自己信頼に焦点を当てることです。まだどうすればいいかわからないかもしれませんが、やっていくうちにどうすればいいかわかるようになり、空白を埋めていくことができます。だから、心配する必要はないのです。

繰り返しになりますが、そのスキルです。テストゼロからTDD完璧まで、1つの"プロセス"や"ステップバイステップ"料理本のアプローチで、直線的に行くことはできません。それはプロセスなのです。あなたの期待は、徐々に、そして漸進的に進歩し、改善することであるはずです。魔法の薬は存在しないのです。

良いニュースは、数ヶ月(そして数年)経つと、あなたのコードは徐々に"proper" well factored and well tested codeになり始めるということです。

余談ですが 古いコードベースにユニットテストを導入する際の主な障害は、まとまりのなさと過剰な依存性であることがわかると思います。したがって、おそらく最も重要なスキルは、実際のユニットテストを書くことよりも、既存の依存関係を断ち切る方法とコードのデカップリングになることが分かるでしょう。

<ブロッククオート

既存のソリューションが適切にユニットテストされていることを確認するために、順守すべきプロセスやステップはありますか?

すでに持っている場合を除き、ビルドサーバーをセットアップし、継続的インテグレーションビルドをセットアップして、すべてのチェックインで、コードカバレッジを含むすべてのユニットテストを実行するようにします。

人材を育成する

どこかから始めて、顧客視点で進捗を見ながらテストを追加していく(下記参照)。

コードカバレッジは、実運用コードベースのうちどれだけがテスト対象になっているかを示す指針として使用します。

ビルド時間は常に高速であるべきです。もしビルド時間が遅いなら、あなたのユニットテストのスキルは遅れています。遅いテストを見つけ、それらを改善しましょう(プロダクションコードとテストを分離してください)。うまく書けば、何千ものユニットテストがあっても、10分以内にビルドを完了させることができるはずです(~1-数ms/テストが良い目安ですが、非常に大雑把なものです。)

検査し、適応させる。

<ブロッククオート

どのようなテストでもないよりはまし、というようなテストではなく、質の高いテストを行うにはどうしたらよいでしょうか。

自分自身の判断が、現実の第一の源でなければなりません。スキルに代わる指標はないのです。

その経験や判断力がない場合は、そのような人と契約することも考えてください。

二次的な指標としては、トータルコードカバレッジとビルドスピードの2つが目安になります。

<ブロッククオート

本番稼動している既存のソリューションに対して、努力する価値があるか?

カスタムメイドのシステムやソリューションにかけるお金の大半は、本番稼動後に使われるものです。そして、品質、人材、スキルへの投資は、決して時代遅れであってはなりません。

今回のプロジェクトではテストを無視し、将来的に書き直す可能性がある場合に追加する方が良いでしょうか?

人材やスキルへの投資だけでなく、TCO(総所有コスト)やシステムの期待寿命も考慮する必要がありますね。

しかし、例外があることは承知しています。

<ブロッククオート

数週間かけてテストを追加するのと、数週間かけて機能を追加するのと、どちらが有益でしょうか?

どちらでもない。あなたのアプローチは、機能面で進歩しながら、コードベースにテストを追加することです。

繰り返しになりますが、これは人材、スキル、そしてコードベースの品質への投資であり、それゆえ時間が必要です。チームメンバーは、依存関係を断ち切る方法、ユニットテストの書き方、新しい習慣の習得、規律と品質意識の向上、より良いソフトウェア設計の方法などを学ぶ必要があります。テストを追加し始めると、チームメンバーはそのアプローチを成功させるために必要なレベルのスキルをまだ持っていない可能性が高いので、多くのテストを追加するためにすべての時間を費やすことを止めることは、単にうまくいかないことを理解することが重要です。

また、プロジェクトの規模に関わらず、既存のコードベースにユニットテストを追加することは、コミットメントと粘り強さを必要とする大きな仕事です。基本的なことを変更し、その過程で多くの学習を期待し、ビジネス価値の流れを止めることでROIを期待しないようにスポンサーに求めることはできません。それはうまくいきませんし、正直言って、そうすべきでもありません。

3つ目は、ビジネスにフォーカスした健全な価値観をチームに浸透させることです。品質は決して顧客の犠牲の上に成り立つものではなく、品質なくして高速化はあり得ません。また、顧客は変化する世界に生きており、あなたの仕事は、顧客が適応しやすいようにすることです。カスタマーアライメントには、品質とビジネス価値の流れの両方が必要なのです。

あなたがやっていることは、技術的な負債を返済することです。そして、常に変化し続ける顧客のニーズに応えながら、そうしているのです。負債が返済されるにつれて、状況は徐々に改善され、顧客により良いサービスを提供し、より多くの価値を提供することが容易になります。などなど。この前向きな勢いこそが、持続可能なペースの原則を強調し、開発チーム、顧客、利害関係者の双方にとって、モラルを維持・向上させるものだからです。

ご参考になれば幸いです。