web-dev-qa-db-ja.com

ユニットテストの追加は、よく知られたレガシーコードに対して意味がありますか?

  • 私はTDDの意味で ユニットテスト について話しています。 (自動化された「統合」、またはテストと呼ぶものではありません。)
  • レガシーコードの例:(C++)テストなしのコード。 (参照:Michael Feathersの レガシーコードを効果的に使用する
  • しかし、次のようなレガシーコード:私たちのチームが過去10〜5年間取り組んできたコードなので、かなり良いアイデアを持っていることがよくあります何かを変えるために物事を置く場所の。
  • 私たちはを実行しています(Boost.Testを介して)some後で来た、または単体テストに「自然」に適合したモジュール(一般的なアプリ固有のコンテナー、文字列のもの、ネットワークヘルパーなど)
  • 適切な自動受け入れテストはまだありません。

さて、最近、私は3つの新しいユーザー向け機能を実装する「楽しみ」がありました。

それぞれに、変更する必要があるコードパーツを理解するのに約1〜2時間、変更する必要がある(小さな)コードを実装するのに1〜2時間、アプリを確認するのにさらに1〜2時間かかりました。その後正しく実行され、実行されるはずでした。

今、私は本当に小さなコードを追加しました。 (私は1つのメソッドと各機能のいくつかの呼び出し行を考える。)

WEwLC で提案されている方法のいずれかを使用してこのコードを分解すると、単体テストが理にかなっています(完全なトートロジーではない)簡単にさらに2〜4時間かかります。これにより、各機能に50%〜100%の時間が追加されますが、直接的なメリットはありません。

  1. コードについて理解するために単体テストは必要ありませんでした
  2. コードがアプリの他の部分に正しく統合されているかどうかをテストする必要があるため、手動テストは同じ量の作業です。

確かに、if、後で「誰か」がやって来てそのコードに触れたところ、理論的にはその単体テストからいくらかの利益を得ることができました。 (理論的には、テストされたコードの島はテストされていないコードの海に住んでいるためです。)

だから、「今回」は単体テストを追加するというハードワークを行わないことを選択しました:テスト対象のものを取得するためのコード変更は、取得するコード変更よりもはるかに複雑でしたこの機能は正しく(そして完全に)実装されています。

これは強力に結合されたレガシーコードの典型的なものですか?私は怠惰ですか/チームとして間違った優先順位を設定しますか?それとも私は賢明ですか、オーバーヘッドが高すぎないものだけをテストしていますか?

23
Martin Ba

あなたはこれらの状況について実用的でなければなりません。すべてにビジネス上の価値がなければなりませんが、ビジネスは技術的な仕事の価値を判断するためにあなたを信頼しなければなりません。はい、ユニットテストを行うことには常にメリットがありますが、そのメリットは費やした時間を正当化するのに十分なものですか。

新しいコードではalwaysと主張しますが、レガシーコードでは、判断を下す必要があります。

あなたはこのコードの領域に頻繁にいますか?次に、継続的な改善のケースがあります。重要な変更を行っていますか?次に、それがすでに新しいコードである場合があります。ただし、おそらく1年間は再度操作されない複雑な領域で1行のコードを作成する場合、もちろん、リエンジニアリングのコスト(リスクは言うまでもありません)は高すぎます。そこに1行のコードをたたいて、すぐにシャワーを浴びてください。

経験則:常に自分自身のことを考えてください。「この結果として遅れる予定の仕事よりも、私がやるべきだと思うこの技術的な仕事のほうが、ビジネスに利益があると思いますか? = "

20
pdr

TDDの意味での単体テストの利点は、安定したチームによって何年にもわたって構築された口頭の伝統を必要とせずに、それ自体で立ち上がるものを得ることです。

同じチームが長い間同じプロジェクトに取り組んできたのは幸運です。しかし、これは最終的には変わります。人々は病気になり、退屈し、または昇進します。彼らは移動、引退、または死にます。新しいものには新しいアイデアがあり、学校で学んだ方法ですべてをリファクタリングしたいという衝動があります。企業は売買されます。経営方針が変わります。

プロジェクトを存続させたい場合は、変更に備える必要があります。

10
mouviciel

ユニットテストの記述は、コードの将来の保証です。コードベースにテストがない場合、コードのビットを少しだけ堅牢にするため、すべての新機能に新しいテストを追加する必要があります。

テストを追加すると、レガシーコードでも、中長期的にはメリットがあることがわかります。あなたの会社が中長期的に気にしない場合は、別の会社を探します。加えて、私は手動でテストするのに、セット単体テストを書くよりも長くはかからないと思います。もしそうなら、あなたはテストを書くことに焦点を当てたコードカタを練習する必要があります。

確かにベストプラクティスでは、変更するコードはすべてユニットテストする必要があります。しかし、実際のコーディングは多くの妥協を伴い、時間と材料は有限です。

あなたがする必要があるのは、バグを修正し、単体テストなしで変更を加えるという点で実際のコストを評価することです。次に、これらのテストの作成への投資を評価できます。単体テストは、将来の作業のコストを大幅に削減しますが、現在は高くつきます。

結論としては、システムがめったに変更されない場合、単体テストを作成する価値はないかもしれませんが、定期的に変更される可能性がある場合、それは価値があります。

2
Tom Squires

テストを作成しないというこれらの小さな合理的な決定のすべてが、誰かが去って新しい採用者が入ってきてスピードを上げなければならないときにあなたを悩ませるようになってしまう、壊滅的な技術的負債を積み上げています。

はい、単体テストの作成にはさらに2〜3時間かかる可能性がありますが、テストからコードが返送された場合は、すべてを手動で再度テストし、テストを再度文書化する必要があります。そうでなければ、誰がどのようにあなたがテストしたものとあなたが使用した値をどのように知っていますか?

ユニットテストは、コードの予想される動作を文書化し、テストデータが機能をチェックするために使用し、変更を行うときに何かを壊していないことを新しいプログラマーに合理的に確信させます。

今日は手動テストよりも数時間かかりますが、変更を行うたびにテストしているため、コードの存続期間にわたって時間を節約できます。

ただし、コードが数年で廃止されることがわかっている場合は、コードへのテストの配置が完了せず、その効果が得られないため、すべてを変更しました。

1
mcottle

それぞれに、変更する必要があるコードパーツを理解するのに約1〜2時間、変更する必要がある(小さな)コードを実装するのに1〜2時間、アプリを確認するのにさらに1〜2時間かかりました。その後正しく実行され、想定されていた動作を実行しました。

変更されたコードがyoが期待どおりに動作することをテストしました。

次の点も確認しましたか?

  • それを作るすべてのものfail、または
  • あなたがすることそうでないかもしれませんがそれを行うと期待していましたか?

テストしないでくださいコードの正確性を証明今日。それを行うには、必要なことを実行するコードを記述します。そのため、「2回」の作業を行うのに「無駄」な努力をしているように感じます。 1回はコードを記述し、もう1回はテストを記述します。

テストcanコードの継続的な正確性を証明します時間の経過。あなた(または他の誰か)意志数か月および数年後にコードを変更します。これはソフトウェアの性質にすぎません。テストにより、あなた(または彼ら)は何も壊さないことが保証されますあなたが意図していないこと。

コードがアプリの他の部分に正しく統合されているかどうかをテストする必要があるため、手動テストは同じ量の作業です。

テストが作成され、テストされると、明らかに:-)-その後、テストにかかる「作業」の量は実質的にゼロになります。テストを実行するだけです。 Any手動テストの量はほぼ確実にmoreこれよりも多くなります。

0
Phill W.

単体テストの価値は、それが開発されたときに新しい機能をテストすることにあるだけではありません。単体テストの利点は、主に将来的に得られます。

はい、レガシーコードをテスト可能にするために、見た目が非常に長い時間を費やす必要がある場合があります。

しかし、そうしない場合は、または確実にすべきです、機能のテストにさらに多くの時間を費やします。最初の開発だけでなく、ソフトウェアのすべての新しいバージョンで。単体テストやその他の自動テストがなければ、機能自体が変更されていない場合でも、何時間もかけて手動テストを行い、機能が不注意で壊れていないことを確認するしかありません。

0
Marjan Venema