単体テストまたはテスト駆動開発は価値がありますか?


48

仕事中の私のチームはスクラムに移行しており、他のチームは単体テストとユーザー受け入れテストを使用してテスト駆動開発を始めています。私はUATが好きですが、テスト駆動開発または一般にテスト駆動開発の単体テストで販売されていません。

テストを書くことは余分な作業であり、実際のコードを書くときに人々に松葉杖を与えるようで、あまり効果的ではないかもしれません。

ユニットテストがどのように機能し、どのように記述するかを理解していますが、それは本当に良いアイデアであり、努力と時間の価値があると主張することができますか?

また、スクラムにとってTDDが特に優れているものはありますか?


27
ソフトウェアが頻繁に故障し、多かれ少なかれ完全に保守不能であり、実際に生産の準備が整う前に交換する必要があることを確認したい場合。その後、ユニットテストを完全に省き、TDDを学ぶのに時間をかけないことをお勧めします。
ダウッドはモニカを復活させると

3
リファクタリングの希望/必要性について考えてください。不注意で何かを壊してしまったときにキャッチするための包括的な単体テストのセットを使用して、または使用せずに、実際にリファクタリング(任意の規模)を行うことに自信がありますか?
マルジャンヴェネ

2
「実際のコードを書くとき、人々に松葉杖を与えます」?ほとんどのベストプラクティスをこのように説明することはできませんか?
user16764

4
@DavidWallace:これは無能な開発者の問題であり、TDDの不足ではありません。さらに、TDDが広範に使用されている場合でも、行った変更が何も壊さないという保証はありません。
コーダー

6
@NimChimpsky:私はTDDに否定的ではありません。誇大宣伝をしていません。プラス面もマイナス面もあります。セキュリティの誤った感覚はそれらの1つです。
コーダー

回答:


68

短い回答:絶対に肯定的です。

ロングアンサー:ユニットテストは、職場(大規模銀行、FX取引)で私が試み、影響を与える最も重要なプラクティスの1つです。はい、彼らは余分な仕事ですが、それは何度も返済する仕事です。自動化された単体テストは、書いているコードを実際に実行し、もちろん期待を検証するのに役立つだけでなく、あなたや他の誰かが行うかもしれない将来の変更に対する一種の監視役としても機能します。誰かがコードを望ましくない方法で変更すると、テストが破損します。ユニットテストの相対的な価値は、コードベースの予想される変化と成長のレベルと相関して低下すると思いますが、予想される変化が少ない場合でも、コードが何をするかを最初に検証することは価値があります。単体テストの値は、欠陥のコストにも依存します。欠陥のコスト(コストは時間/お金/評判/将来の努力の損失)がゼロの場合、テストの相対値もゼロです。ただし、これは商用環境ではほとんどありません。

通常、作業の一環として日常的にユニットテストを作成しない人はもう採用しません。これは、毎日のように期待することです。私は単体テストを持つことの純粋な費用便益分析を見たことはありません(誰かが私に1つを指すことを遠慮なく感じます) 。また、私が書いたコードが(ある程度まで)動作していることを知っているので、夜もよく眠れます。

私の考えでは、テスト駆動開発はテスト手法ではありません。実際には、作業システムと一連の単体テストを出力する設計アプローチ/プラクティスです。このプラクティスは、開発するのが非常に難しく、完璧なスキルであるため、私はこの信仰についてあまり信仰を持ちません。個人的には、システムを構築していて、それがどのように機能するか明確にわからない場合は、暗闇の中で自分の道を見つけるのを助けるためにTDDを採用します。ただし、既存のパターン/ソリューションを適用する場合、通常は適用しません。

単体テストを書くことが理にかなっているという数学的な証拠がない場合、長期間にわたって試してみて、自分でメリットを体験することをお勧めします。


5
私が付け加えたいのは、ユニットテストはインターフェイスの設計についても考えさせることです。「プライベートメソッドを単体テストする方法」と思われる部分に到達すると、おそらくインターフェイスが間違っていることがわかります。
TC1

1
「長期間にわたって試してみて、自分でメリットを体験することをお勧めします。」一度試してみるだけで十分でしたが、その利点は明らかでした。
ニムチンプスキー

1
「通常、作業の一部としてユニットテストを定期的に作成しない人はもう採用しません」私は最近、時間の無駄であり、コードを自分でテストできるので、自動テストを書くのは好きではないと他の欠点の中で強く宣言した候補者を拒否しなければなりませんでした。
-ftr

4
自動テストを使用するだけでは、重要なコードが関連する方法で機能すること証明することはできません。自動テストでは、コードがテストに合格したことのみを証明できます。テストがユースケースの100%をカバーしている場合、おそらく「一定のレベル」が得られますが、それでもコードが「確実に機能する」ということにはなりません。真の証明可能性を得るには、en.wikipedia.org / wiki / Formal_verificationが必要です。そのため、ここでは「証明可能」という間違った用語を使用しています。
vaxquis

1
@vaxquisはい、用語証明の使用について厳密に正しいです。しかし、テストの存在(またはTDDの実践)が、テストの不在よりも動作しているシステムのより良い証拠であると思います。
-rupjones

16

以前に見つかったエラーは、後で見つかったエラーよりも修正にかかる費用がかかりません。TDDは、システムの正確性を確認するのに役立ちます。あなたはもう少し前もって投資しますが、後でそれを取り戻します。グラフは少し誇張されていますが、アイデアがよく表れています。

ここに画像の説明を入力してください

画像ソース


伝統的とはどういう意味ですか?TDDではないものは何ですか?
ジョルジオ

このグラフは実際の統計に基づいているようには見えません。2006年にこのブログエントリを書いた1人の人の経験を表しているだけです。まったく間違っていると言っているわけではありません。
Doc Brown

9

単体テストまたはテスト駆動開発は価値があるのですか?

はい、そうです。ボブおじさん(ロバートCマーティン)はプレゼンテーションでaに語った。

開発者が、コードを叫んで、歌ったり、踊ったりするよりも、テスト書いて合格する方がうまく機能していることを証明します。

そして、あなたはテストを削除するつもりはないので、テストがパスである限り、機能が機能していると確信します -回帰問題は解決されます。

たくさんのものが書かれていますが、

  1. その機能を動作させるのはあなたの責任です。テストを書きます。早くやれよ。
  2. 単体テストを統合テストに置き換えるタイミング

SCRUM、ユニットテスト、TDDは関連していますか?

まもなく、あなたがマスターであるとき、あなたはUnit testing近くになりTDDます。SCRUMはこれとは何の関係もありませんが、彼らが言うように、素晴らしいことがうまく混ざり合っているため、ソフトウェアを開発するこれらの技術は、試していない場合は優れたスタックになります。

TCRをSCRUMに特に適したものにしているものはありますか?

言ったように、彼らは良い組み合わせを作ります。自動化テストを追加すると、より特別なものになります。


8

テストを書くことは余分な作業であり、実際のコードを書くときに人々に松葉杖を与えるようで、あまり効果的ではないかもしれません。

単体テストは松葉杖として価値があります。開発作業をサポートし、アプリケーションが必要に応じて動作しなくなることを恐れずに実装を変更できます。ユニットテストは、実装が要件を満たしていることを検証できるツールを提供するため、松葉杖以上のものです。

単体テスト、受け入れテスト、統合テストなど、すべてのテストは、それらを使用する人と同じくらい効果的です。作業にだらしなく近づくと、テストが粗雑になり、実装に問題が生じます。なぜわざわざ?あなたは、あなたのソフトウェアが機能することを自分自身とあなたの顧客に証明する必要があり、ソフトウェアの使用を妨げる可能性のある問題がないため、テストを煩わせます。はい、テストは間違いなく余分な作業ですが、テストの進め方によって、リリース後にバグを修正するために必要な労力と、コードの変更と保守に必要な労力が決まります。

ユニットテストがどのように機能し、どのように記述するかを理解していますが、それは本当に良いアイデアであり、努力と時間の価値があると主張することができますか?

TDD、および実際にコードを作成する前にテストを記述する必要がある方法は、将来の技術的負債の頭金として早期に努力するアプローチを取ります。プロジェクトを進めていくと、見逃したり、うまく実装されていないものはすべて、メンテナンスの難しさが増すという形でより多くの技術的負債を被り、将来のコストとリソース要件に直接影響します。前もってテストすることで、将来の技術的負債に対処する努力をするだけでなく、コードを実行するだけで要件を検証できるように要件をエンコードすることができます。また、最初にテストを行うと、コードで問題を解決する前に、問題の領域に対する理解を検証する機会が得られ、実装の取り組みが検証されます。

コードのビジネス価値を最大化しようとすることになります。ほとんどテストされておらず、維持が難しいコードは、一般に安価で作成が速く、リリース後の製品の寿命にわたって維持するのに非常にコストがかかります。ユニットレベルで徹底的にテストされたコードは、一般に作成するのに費用がかかりますが、リリース後の製品の寿命にわたって維持するのに比較的費用はかかりません。

また、TDDをSCRUMに特に適したものにしているものはありますか?

TDDは特定の方法論には特に適していません。これは単なるツールです。特定の成果を達成するために、開発プロセスに統合できるプラクティス。したがって、質問に答えるために、TDDは、SCRUMであろうと他のアプローチであろうと、あなたの方法を補完します。


6

人々はそれが前もって行われている活動だから、それは余分な努力だと思う。今、あなたが時間内に失うものは、後で戻ってきます。

単体テストの理由は次のとおりです。

ターゲットを与えます:ソフトウェアが何をすべきかわからない場合、テストを書くことはできません。これにより、仕様の問題を後ではなく早期に取り除くことができます。

進歩の感覚を与えます。

コードの変更によりコードの他の領域の出力が変更された場合に警告します。これにより、リファクタリングが容易になります。

追加のドキュメント層を提供します(特にテストを適切にコメントする場合)。

あらゆる種類の優れた実践を奨励します。テストは高速に実行される必要があるため、分離され、モッキングをサポートするコードを記述することをお勧めします。これはすべてリファクタリングを支援します。

他にもこのスレッドの他の投稿で取り上げられているものがあります。それは価値があります。


2

単体テストまたはテスト駆動開発は価値がありますか?

間違いなくはい(他の回答を参照)

[それは]本当に良いアイデアであり、努力と時間の価値がありますか?

  • はい、何か新しいものを開始する場合(新しいモジュールまたは完全に新しいアプリケーションを追加する場合)
  • ノーテスト駆動開発されなかった、それは(レガシー)を拡張する必要があり、既存のコードの多くは、すでに存在する場合。

私の意見では、実際のコードのに単体テストを書く場合、テスト駆動開発が最も効果的です。このように、テストを実行するコードは、簡単にテストできる最小限の外部参照で明確に分離されます。

ユニットテストなしでコードが既に存在する場合、コードは簡単なテスト用に作成されていないため、通常、ユニットテストを後で書くのは多くの余分な作業です。

TDDを行うと、コードは簡単にテストできます。


2

反対側からこれにアプローチさせてください。単体テストなしで重要なアプリケーションを開発するとどうなりますか?質の高いQA部門がある場合、最初に発生することの1つは、報告された問題が大量にあることに気付くことです。実行したことをテストせず、それが機能すると仮定し、要件にそれほど注意を払わず、アプリケーションが要件を満たしていないためです。描画ボードに戻って書き直して修正します。これで、QAにプッシュする前に修正が他に影響を与えなかったことを確認する方法がなかったため、修正を行い、まったく新しい一連の問題を見つけました。おっと、期限が来てなくなり、管理が動揺しています。

質の良いQA部門がないと状況は悪化します。ユーザーがバグを見つけ、上司を不幸にするだけでなく、実稼働環境がひどくなり、数百人または数千人の人々が単体テストが妨げていたバグを修正する間、停止します。これは良いキャリア選択ではありません。

このカウボーイアプローチが何年も続くと仮定しますか?今では、些細な変更であっても、すべての変更が、疑いのない新しい問題を発生させるようです。それだけでなく、アプリケーションの動作を改善するためにやりたいことの多くは、リスクが高すぎるか高価すぎるか、またはその両方であるため実行できません。そのため、パッチにパッチを適用すると、システムがますます複雑になり、バグが増えて使いにくくなります。

ユーザーは時間の見積もりに疑問を抱き始めます。なぜなら、彼らはどんどん大きくなり続けており、システムが非常に複雑になっていることを説明するのが難しく、変更を加える場所を見つけるのが難しく、それを確認するのがさらに難しいからです」 tは何かを壊します。

私はこのような場所で働いていましたが、10年の開発の後、何百ものカスタマイズされたクライアントアプリケーションのどれが壊れるかわからなかったため、実際の問題を修正するために私たちがやりたいことはほとんど何もできませんでした。最初の開発者は、非常に「ユニットテスト、悪臭を放つユニットテストを必要としない」種類の開発者でした。彼らの後を追った誰もが彼らの近視のおかげで苦しんだ。

単体テストがなければ、ソフトウェアはバグが多く、初期開発と保守の両方に時間がかかります。一体どうして単体テストをしたくないのですか?テストの作成に費やす時間は、以前に発見したはずの問題の修正に費やす時間よりもはるかに短く(バグの発見が早いほど、修正に要する時間は短くなります)、テストを書くことで完全に回避できた問題まず、コーディングを開始する前に要件をよりよく理解します。


1

作成するコードはすべて、ある時点でテストする必要があります。一度にすべてを書いてから、コンパイルボタンを押して指をクロスさせたくはありません。小さなブロックを作成してコンパイルし、コードに入念に作成された入力を送信して、意図したとおりに動作することを確認します。次に、通常、アドホックテスト装置を削除し、次のコンポーネントに進みます。

単体テストを使用すると、このプロセスが簡素化され、テストを維持する口実が得られます。そうすれば、過去にテストしたものを壊すような変更を加えた場合、コードの他の部分に影響を与えるのではなく、そのリグレッションを明示的にキャッチできます。その中に本当の価値があります。

TDDへの赤緑リファクタリングアプローチについては、少し面倒です。しかし、それぞれに彼自身。


1
私の2cの場合:テストが実際に機能しているかどうかを確認するには、合格する前にテストが失敗することを確認する必要があります。悲しいことに、多くの開発者が動作しているように見えるテストを書いているのを目撃しましたが、テスト条件が変更された場合、コードは失敗するはずですが、テストに合格します。テストが最初に失敗し、2番目に合格した場合、エラーなしでテストを作成した可能性が高くなります。コードが変更された後にテストを変更することになった場合、コードが正常であると確信することはできません。はい、それは退屈ですが、正確である可能性が高くなります。:
S.ロビンズ

0

ほとんどの場合、開発者はテストを書くという考え方に対して回復力があります。テストには価値がないと主張するのではなく、特定の問題を解決する方法を見つけるための手段にすぎないということです。通常、この問題はコンテキストに基づいて変わります。それが完了すると、テストは目的を果たさず、同様に削除される可能性があります。ここに、私の同僚が過去にテストを書く時期を決定する方法について与えたコンテキストのサンプルがあります、そして、あなたは彼らによる唯一の可能な答えが決してないことを見つけるでしょう:

  • 手元にある問題は、スタックや計算機などのTDDの教科書の例でなければなりません
  • 些細なコードはテストしないでください(前の引数を無効にします)
  • 重要または困難なコードは徹底的にテストする必要があります(前の議論で暗示されています)
  • 抜本的なリファクタリングを可能にするために、テストを実装に密結合しないでください(前の引数を無効にします)
  • 特定のペイロードでサードパーティのサービスを呼び出すなどの副作用のテストは必要ありません(したがって、ブラックボックステストはありません)

実際、私が一般に受け入れられ、最終的には役に立たないと信じているテストのタイプがあります。すなわち、セレン、ウェブドライバー、ワティールまたはアルキリアンを使用するなどによるGUIベースのテスト。これは、TDDプロジェクトで5分間のビルドサイクルではなく、7時間のビルドサイクルを取得する方法です。

これらの同じ開発者は、通常、コードがどれほど悪いか、以前の開発者がどれほど無能であったに違いないかを他のすべての人に訴えます。また、ホワイトボード、MSオフィス、またはWikiを使用して適切なデザインを作成し、このデザインが最新の状態に維持されるように細心の注意を払うことが非常に重要であると感じています。

最後の1つは、このような開発者が詐欺であることに本当に気付いた理由です。単体テストではない設計ドキュメントは古くなっており、メンテナンスコストがかかるため、最新の状態に保たれないことがわかっています。実際、コードを書く前と後の両方で有用で読みやすいデザインのアイデアをMS Office形式で表現するための優れた手段を考えてみました。私はすべてのケースで失敗しましたが、MSオフィスのドキュメントを作成することができた人はいるようですが、実際にこれらのドキュメントも役に立たなかったのです。

だから、あなたには選択肢があります。私の10年の開発経験に基づいて、そのようなドキュメントを作成する唯一の既知で実績のある方法であるTDDを実践することにより、設計とドキュメントを作成できます。または、政治に入ることができます。


1
テストはドキュメントではありません。TDDは良い習慣ですが、開発者はあまりにも単純化されたテストスタブを吐き出すauto-genツールを使用することが多すぎます。これに抵抗する開発者がいる場合は、きめ細かいテストを作成する代わりに、製品全体をより多く実行する大きなテストハーネスを作成してみてください。彼らは明らかにそれが便利だと思うでしょう。ただし、適切なドキュメントを作成する必要がありますが、そこから抜け出すことはできません。
gbjbaanb

@gbjbaanb:開発者が自動生成ツールを使用する場合、ユニットテストを作成することもありますが、TDDは作成しません。TDDでは、メソッドの前にテストを書くことになっています。まだ存在しないメソッドのテストのスキャフォールディングを自動化することはできません。また、よく書かれたテストドキュメントです(プロジェクトの開発者向けのテクニカルドキュメントであり、ユーザーマニュアルでも要件でもありません)。よく書かれ保守されている単体テストは、メソッドがどのようにテストされるべきかを示しています。また、テストが定期的にチェックされ、成功する場合、それらは明らかに古いドキュメントよりも正確です。それを否定することはできません。
クリス

ユニットテストは、APIの使用方法の例を示しているため、非常に優れた開発者向けドキュメントになります。
k3b

セレン、Webドライバーなどのポイントは、Webサイトをそれほど手動でQAする必要がないことです。したがって、ビルドプロセスから削除することで時間を節約することはできません。なぜなら、それら自体が時間を節約するためのものだからです。
-Muhd
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.