TDDが機能する理由 [閉まっている]


92

最近、テスト駆動開発(TDD)が大きくなっています。プログラマーSEやその他の会場で、さまざまな問題の解決策として推奨されることがよくあります。なぜ機能するのだろうか。

エンジニアリングの観点から見ると、2つの理由で困惑しています。

  1. 「書き込みテスト+合格するまでリファクタリングする」アプローチは、信じられないほどアンチエンジニアリングに見えます。たとえば、土木技師が橋の建設にそのアプローチを使用したり、車の車の設計者を使用すると、非常に高いコストで橋や車の形状を変更することになり、その結果、よく考え抜かれたアーキテクチャのないパッチアップされた混乱になります。「リファクタリングまでのパス」ガイドラインは、多くの場合、アーキテクチャ設計を忘れ、テストに準拠するために必要なことをすべて実行することを義務付けられています。つまり、ユーザーではなくテストが要件を設定します。このような状況で、結果の良い「虚偽」、つまり正しいだけでなく、拡張性、堅牢性、使いやすさ、信頼性、安全性、安全性などの最終結果をどのように保証できますか?これは、アーキテクチャが通常行うことです。
  2. テストでは、システムが機能することを保証できません。そうでないことを示すだけです。言い換えれば、テストは、テストに失敗した場合にシステムに欠陥があることを示しますが、すべてのテストに合格したシステムは、テストに失敗したシステムより安全ではありません。ここでは、テスト範囲、テスト品質、およびその他の要因が重要です。「すべてがグリーン」な結果が多くの人々にもたらす誤った安全感情は、民間および航空宇宙産業では非常に危険であると報告されています。テスト戦略として」。多くの場合、テスト戦略はチェックされません。または、誰がテストをテストしますか?

要約すると、私は「テスト」ビットよりもTDDの「ドリブン」ビットに関心があります。テストはまったく問題ありません。私が得られないのは、それを行うことで設計を推進することです。

ソフトウェアエンジニアリングのTDDが優れた実践である理由と、ソフトウェアの場合に上記で説明した問題が関連性がない(または関連性が十分でない)理由を含む回答をご覧ください。ありがとうございました。


53
橋、車、その他の物理的な設計は、ソフトウェアほど柔軟ではありません。これは重要な違いであり、ソフトウェアと実際のエンジニアリングの比較は必ずしも適切ではないことを意味します。ブリッジで機能するものはソフトウェアでは機能しない可能性があり、逆もまた同様です。
ラースヴィルゼニウス

9
私はあなたの疑いにいくらか同意します。たとえば、テストスイートがあると、コードを記述する際に副作用として何らかの形で「ソフト化された」注意を払うことができるという印象を受けました。もちろん、テストは良いことです(リファクタリングの可能性が必要な場合は必須です)が、テストが詳細、境界ケース、効率性または拡張性に注意を補足する場合であり、それらを置き換える場合ではありません。
6502

2
@ 6502:どうしても!TDDは特効薬ではなく、ソフトウェア開発中に発生するすべての問題を解決するわけではありません。ただし、ワークフローを整理する便利な方法です。たとえば、すべての境界ケースがテストでカバーされるという要件を課すことができます。これらの境界ケースが何であるかをまだ知る必要がありますが、コードがそれらを正しく処理しているかどうかをチェックするツールもあります。
-Mchl

2
@CesarGon、あなたは私が先ほどSOで尋ねたこの質問にも興味深いかもしれません...まったくTDDではなく、関連しています...そこにいくつかの非常に啓発的な答えがあります。
AviD

6
土木工学/ソフトウェア開発のアナログが耐えられないことは驚くべきことです。同じ方針に沿って、芝生を刈るのと同じ方法でパンケーキを調理できないことにしばしば気付きました。

回答:


66

ここに誤解があると思います。ソフトウェア設計では、設計は製品に非常に近いものです。土木建築では、設計は実際の製品から切り離されます。設計を保持する設計図があり、最終製品に具体化され、それらは膨大な時間と労力によって分離されます。

TDDは設計をテストしています。しかし、すべての車のデザインと建物のデザインもテストされています。建設技術は最初に計算され、次に小規模でテストされ、次に大規模でテストされてから実際の建物に配置されます。たとえば、Hビームと負荷を発明したとき、実際に最初のブリッジを構築する前に、これが試行され、再試行されたことを確認してください。

車の設計も、プロトタイプを設計することによってテストされます。そして、はい、確かに、正しくないものを期待に応えるまで調整することによってテストされます。ただし、このプロセスの一部は遅くなります。なぜなら、あなたが言ったように、製品をいじることができないからです。しかし、車のすべての再設計は、以前のものから学んだ経験に基づいており、すべての建物には、スペース、光、断熱、強度などの重要性に関する約3千年の基礎があります。そして新しいもののための再設計。

また、部品がテストされます。おそらくソフトウェアとまったく同じスタイルではありませんが、通常、機械部品(ホイール、イグナイター、ケーブル)を測定し、サイズが正しいこと、異常が見られないことなどを知るためにストレスをかけます。測定し、レンガをタップして壊れたものを見つけます。実際に何らかの構成でテストしたり、大規模なグループの限定表現を描画して実際にテストしたりします。

これらはすべて、TDDを使用して配置できます。

実際、テストは保証ではありません。プログラムがクラッシュし、車が故障し、風が吹くと建物が面白いことを始めます。しかし...「安全性」はブール問題ではありません。すべてを含めることができない場合でも、50%だけをカバーするよりも、99%の不測の事態をカバーできる方が優れています。テストせずに鋼を見つけることはうまく定まらず、壊れやすく、メイン構造を立てたばかりのハンマーの最初の叩きで壊れますが、お金の無駄です。建物を傷つける可能性のある他の懸念があるとしても、簡単に予防できる欠陥が設計を破壊することを許さないほど愚かではありません。

TDDの実践に関しては、それはバランスの問題です。1つの方法で実行するコスト(たとえば、テストせずに後でピースを拾う)と、別の方法で実行するコスト。それは常にバランスです。しかし、他の設計プロセスにはテストとTDDが存在しないとは思わないでください。


7
製造業のどこでテストが行​​われるかについて話すための+1 素晴らしい点。
アダムリア

11
「部品はテスト済み」と言います。もちろん、テスト駆動設計ではありません。航空機の部品は、テスト駆動方式ではなく、建築的で大きな設計を前もって設計されています。TDDとの類似点はここにはありません。
CesarGon

3
それに加えて:TDDは、私の意見では、主に最後に大きな「すべてまたは何も」ではなく、パーツをチェックできるようにする方法に関するものです。しかし、TDDの「最初にテストを構築する」ことは、「達成したいことを考える前にテストを行うこと」を意図したものではありません。テストを考えることは設計の一部だからです。その正確な部分に何をさせたいかを指定するのが設計です。入力を始める前に、すでにいくつかの設計を行っています。(そのように、「テスト駆動設計」という用語は、実際にはフィードバックループである一方通行のパスを誤って示唆していると思います)。
インカ

2
+1:ソフトウェアは純粋に設計です。問題のブリッジの類推は完全に間違っています。TDDは完全に外部ユニットテストに適用されます。テスト駆動設計は、設計のすべてのレイヤーに適用されます。
-S.Lott

3
@CesarGon:いいえ、TDDはテストによって開発を推進しています。これは、デザインの推進とは異なります。設計により、システムの使用方法が決まり、したがって、その動作を再現するためにどのテストを実装する必要があるかが決まります。ただし、これらのテストを実装すると、多くの場合、設計の改善に役立ちます。
-deworde

26

IMO、TDDのサクセスストーリーのほとんどは偽物であり、マーケティング目的のためだけです。成功はほとんどないかもしれませんが、小さなアプリケーションに限られます。私は、TDDの原則が使用されている大きなシルバーライトアプリケーションに取り組んでいます。アプリケーションには数百のテストがありますが、まだ安定していません。複雑なユーザーインタラクションのため、アプリケーションのいくつかの部分はテストできません。多くのモックと理解しにくいコードを使用した結果のテスト。

最初にTDDを試したとき、それはすべて良いようです。私はたくさんのテストを書いて、単体テストには難しい部分をモックアウトすることができました。かなりの量のコードがあり、インターフェースの変更が必要になると、ユーザーはめちゃくちゃになります。多くのテストを修正する必要があり、コードの実際の変更よりも多くのテストを書き換えます。

Peter Norvigは、Coders At WorkブックでTDDについての彼の見解を説明しています。

Seibel:テストを使用して設計を推進するというアイデアはどうですか?

Norvig:私はテストを設計の方法としてではなく、エラーを修正する方法としてより見ています。「最初にやるべきことは、最後に正しい答えが得られるというテストを書くことです」と言う極端なアプローチです。次に、それを実行して失敗したことを確認し、「私は何をしますか」と言います。次は必要ですか?」—それは私にとって何かを設計する正しい方法とは思えません。解決策が事前に定められているほど単純な場合にのみ意味があるように思えます。最初にそれについて考える必要があると思います。あなたは言わなければならない、「ピースは何ですか?そして、それらの一部が何であるかを知るまで、どうやってピースのテストを書くことができますか?」そして、それができたら、それらの各ピースのテストを行い、それらが互いにどのように相互作用するかをよく理解することは良い規律です境界ケースなど。それらにはすべてテストが必要です。しかし、「このテストは失敗しました」と言って、設計全体を推進するとは思わない。


7
さて、あなたは人々やコンサルタントをTDDためにこれらの事実を伝えた場合、あなたが得る答えは次のようになり、well, you haven't done TDD right!
Navaneeth KN

10
そして、彼らは正しいでしょう。非常に大容量のシステムでBDD / TDDを実行しており、うまく機能しています。テストは、予想される動作に違反したことを示すためにあります。これを後で変更してテストを「壊す」場合、実際には間違っています。システムの新しい動作を確定するために、最初にテストを変更してから、それを変更する必要があります。そして、もしあなたがそれを正しくしているなら、「このことは何をする必要があるか」から始めてテストを書き、テストを書くプロセスは「ITがその仕事をするために何が必要か」を考えるのを助けます。ああ、コンサルタントはまったく使われなかった
アンディ

4
多くのテストを行っても、適切な設計の作成が免除されるわけではありません。周囲にいくつのテストが構築されているかに関係なく、高度に結合された設計は常に壊れやすくなります。この設計にテストを組み込むと、全体がさらに悪化する可能性があります。
ニュートピア

3
間違ったことをしたり、高度に結合した設計であることは問題ではありません。事実は、インターフェースが変わるということです。つまり、そのインターフェイスを使用するすべてのテストを変更する必要があります。大きなシステムでは、テストを必要な変更と同期させておくと、実装が圧倒され始める可能性があります。インターフェースの変更の可能性がはるかに高いため、アジャイル開発を行っている場合、これはさらに大きな問題になります。方法論がうまくいかないとき、方法論の支持者があなたがそれを間違っていると主張するのは面白いことです。方法論がすべての問題領域に適しているわけではありません。
ダンク

2
私の経験では、TDDを行うことは小さなアプリケーションまたはモジュールで機能します。複雑な何かに取り組む必要がある場合、頭の中で全体像を明確にする前に詳細な(実行可能な)仕様を書くことを余儀なくされるため、TDDの速度が遅くなります。特定のクラスを必要としないことがわかった場合は、テストの束をすべて捨てます(まだデザインで遊んでいます)。そのような場合、まず合理的な全体設計を取得し、次に実装の詳細を具体化することをお勧めします(TDDを使用する可能性があります)。
ジョルジオ

25

テスト駆動設計は、次の理由で機能します。

これは、実行可能な形式の仕様です。

これは、テストケースから確認できることを意味します。

  1. その期待される結果は、テストケースに右あるようにコードが呼び出されている仕様をフル充填します。目視検査(テストケースに合格することを期待)は、すぐに「ああ、このテストでは、この状況でinvoiceCompanyを呼び出すと、その結果が得られることを確認します」と言うことができます。
  2. どのようにコードを呼び出す必要があります。テストを行うために必要な実際の手順は、外部の足場なしで直接指定されます(データベースはモックアウトされますなど)。

最初に外部からビューを作成します。

多くの場合、コードは最初に問題を解決する方法で作成され、次に作成したコードがどのように呼び出されるかを考えます。「フラグを追加する」などの方が簡単なことが多いため、これは頻繁に厄介なインターフェイスを提供します。これにより、コードは呼び出し元のインターフェイスに従って作成され、逆の方法ではないため、モジュール性が向上します。

これにより、通常、コードも簡潔になり、説明の少ないドキュメントが必要になります。

早く終わります

実行可能な形式の仕様を持っているので、完全なテストスイートに合格すると完了です。物事をより詳細なレベルで明確にすると、さらにテストを追加できますが、基本的な原則として、進捗状況と完了したことを非常に明確で目に見える形で示すことができます。

これは、作業が必要かどうかを判断できることを意味します(テストに合格するのに役立ちます)。

それらについて熟考している人にとっては、次のライブラリルーチンにTDDを使用することをお勧めします。実行可能な仕様をゆっくり設定し、コードがテストに合格するようにします。完了すると、ライブラリの呼び出し方法を確認する必要があるすべての人が実行可能な仕様を利用できます。

最近の研究

「ケーススタディの結果は、TDDプラクティスを使用しなかった同様のプロジェクトと比較して、4つの製品のリリース前の欠陥密度が40%から90%減少したことを示しています。 TDDを採用した後の初期開発時間。」〜4 つの産業チームの結果と経験


5
私はこれに、あなたが実際にあなたがいつ終わるかについていくらか合理的で明確なガイドラインを持っていると付け加えます。目の前のタスクを完了したことを客観的に検証する明確な手順がなければ、それを知ることは困難です。私自身の経験には、タスクが完了し、継続的で継続的なラインの移動が行われたかどうかを「ネゴシエート」するために何時間も何日も無駄にしました。これは、スケジューリングを含むプロジェクト管理のすべてのレベルに影響を与えますが、そのようなタスクをどのようにスケジュールできるのでしょうか?ターゲットをより明確にし、ターンアラウンドを高速化すると、スループットと通信が向上します。
エドワードストレンジ

これは受け入れられた答えでなければなりません。
ニーニング

19

ソフトウェアを作成するプロセスは、コードを記述するプロセスではありません。最初に「広範囲」計画なしにソフトウェアプロジェクトを開始することはできません。川の2つの岸を橋渡しするプロジェクトのように、最初にそのような計画が必要です。

TDDアプローチは(ほとんど)単体テストに関連しています-少なくともそれは人々がそれについて考える傾向があります-それはソフトウェアコードの最も低レベルのビットを作成しています。すべての機能と動作が既に定義されていて、実際に何を達成したいかがわかっている場合。

構造工学では、次のようになります。

「これらの2つの金属片を互いに接続しており、接続はxのオーダーでせん断力を維持する必要があります。これを行うのに最適な接続方法をテストしましょう」

ソフトウェアが全体として機能するかどうかをテストするために、ユーザビリティテスト、統合テスト、受け入れテストなど、他の種類のテストを設計します。これらも、コードの記述に関する実際の作業を開始する前に定義する必要があり、ユニットテストが緑になった後に実行されます。

Vモデルを参照してください:http : //en.wikipedia.org/wiki/V-Model_%28software_development%29

ブリッジに対してどのように機能するかを見てみましょう。

  1. 地方自治体は、橋梁建設会社に次のように述べています。「これら2つのポイントを接続するには橋が必要です。橋は1時間あたりnのトラフィックを許可し、2012年12月21日まで準備ができている必要があります」-これは受入テスト:会社は、テストに合格できない場合、全額(または任意の)お金を受け取りません。

  2. 会社の管理がプロジェクトのスケジュールを決定します。彼らは作業チームを設定し、各チームの目標を設定します。チームがこれらの目標を達成しない場合-ブリッジは時間通りに構築されません。ただし、ここにはある程度の柔軟性があります。チームの1つに問題がある場合、会社は要件を変更する、下請業者を変更する、より多くの人を雇うなどして、プロジェクト全体がポイント#1で設定された目標をまだ満たすようにすることでそれを相殺できます。

  3. 特定のブリッジコンポーネントの設計を担当するチーム内では、上記の例のようになります。ブリッジの構築に関する膨大な知識を持っているため、ソリューションが明らかな場合があります(ソフトウェア開発で十分にテストされたライブラリを使用するようなものです-宣伝どおりに機能すると仮定します)。いくつかのデザインを作成してテストし、最適なデザインを選択する必要がある場合があります。それでも、コンポーネントをテストする基準は事前にわかっています。


私があなたを正しく理解していれば、TDDは(a)単体テストにのみ使用され、(b)他のテストアプローチも伴う場合に限り、TDDはOKであると言っています。この場合、OPのポイント番号2をアドレス指定できます。ポイント番号1にどのように対処しますか?
CesarGon

@CesarGon:TDDは統合テストにも最適です。
sevenseacat

ポイント1は、自動車または橋の最終プロジェクトが受け入れられる前に、多くの繰り返しを経て、そのすべての詳細が「広範囲の計画」によって課された要件に対してレビューおよびテストされるという行為に要約されます。ほとんどの場合、紙で(またはコンピューターのメモリで)行われますが、この場合は安価であるためです。
-Mchl

@Karpie:受け入れテストにも!クライアントが作業を受け入れるために必要なものを事前に知っておく必要があります。
-Mchl

1
じゃあ 作業を開始する最初のほとんどのチームは、クライアントの基準を満たすことができるブリッジを設計するように言われている建築家のチームです。一方で、安価で、おそらく見栄えが良く、最初の強い突風で下りません。チームは、これらの基準を多少満たすいくつかの大まかな設計を提案し、1つを選択してより詳細に作業し、設計の準備ができるまで繰り返す(つまり、指定された基準を満たし、十分に詳細になるように繰り返す)プロジェクトの別の段階を開始できます)
-Mchl

18

私の考えでは、TDDが機能するのは、

  • 仕様や要件ドキュメントで通常カバーされていない精度レベルで実装を決定する前に、ユニットに何をさせるかを強制的に定義します
  • テストと本番の両方のシナリオで使用する必要があるため、コードを本質的に再利用可能にします
  • より小さなデザインでコードを書いて、より良い設計につながる傾向があるチャンクをテストすることをお勧めします

具体的には、あなたがあげるポイントについて

  • コードは、レンガやスチールよりも順応性が高いため、修正するのが安価です。動作が変更されていないことを確認するテストがある場合は、さらに安価です
  • TDDは設計を行わない言い訳ではありません。高レベルのアーキテクチャは一般的に推奨されますが、あまり詳細ではありません。Big Up Front Designは推奨されませんが、十分な設計を行うことをお勧めします
  • TDDはシステムが動作することを保証することはできませんが、さもなければ見逃されることになる多くの小さな間違いを防ぐことができます。また、一般的に、より良いファクタリングされたコードを推奨するため、多くの場合、理解しやすく、バグが発生しにくい

3
また、欠陥が発見された場合、別のテストを追加するときにそれらが繰り返されないことを確認できることを追加する必要があります。
アンディ

16

TL; DR

プログラミングはまだ設計作業であり、構築ではありません。事実の後にユニットテストを書くことは、コードがそれがすることをすることを確認するだけであり、何か有用なことをすることではありません。テストの失敗は、間違いを早期に発見できるため、真の価値があります。

コードは設計

PPPの第7章「ボブおじさん」はこの問題について直接話しています。この章の非常に早い段階で、彼はJack Reevesの優れた記事を参照しています。この記事では、コードは設計であると提案しています(リンクはトピックに関する3つの記事すべてを集めたページに移動します)。

この議論の興味深い点は、建設が非常に高価な活動である他のエンジニアリング分野とは異なり、ソフトウェアの建設が比較的無料であることです(IDEでコンパイルし、ソフトウェアを構築しました)。コードの作成を建設作業ではなく設計作業と見なす場合、赤緑リファクタリングサイクルは基本的に設計の練習です。テストを作成し、それらを満足させるコードを作成し、リファクタリングして新しいコードを既存のシステムに統合するにつれて、設計は進化します。

仕様としてのTDD

TDD用に作成する単体テストは、理解しているとおりに仕様を直接翻訳したものです。最小限の仕様を満たすコードを書くことにより(テストを緑にする)、あなたが書いたコードはすべて特定の目的のためにそこにあります。その目的が達成されたかどうかは、反復可能なテストによって検証されます。

機能へのテストの書き込み

単体テストでよくある間違いは、コードの後に​​テストを書くときに発生し、最終的にはコードがその機能を果たすかどうかをテストします。つまり、このようなテストが表示されます

public class PersonTest:Test
{
   [Test]
   TestNameProperty()
   {
      var person=new Person();
      person.Name="John Doe";
      Assert.AreEqual("John Doe", person.Name);
   }
}

このコードは役に立つかもしれませんが(誰かが単純なプロパティでわいせつなことをしていないことを確認してください)。仕様の検証には役立ちません。そして、あなたが言ったように、これらの種類のテストを書くことはこれまでのところあなただけを取ります。

緑は良いのですが、価値は赤 にありますTDDで予期せぬテストが失敗したとき、真の「あは」の瞬間がありました。私が構築しているフレームワークに対して行った一連のテストがありました。新しい機能を追加して、テストを作成しました。次に、テストに合格するコードを作成しました。コンパイル、テスト...新しいテストで緑色になりました。しかし、私が赤くなるとは思わなかった別のテストでも赤になりました。

失敗を見て、私は安placeのため息をつきました。なぜなら、そのテストを実施していなければ、かなり長い間そのバグを捕らえたのではないかと思うからです。そして、それは非常に厄介なバグでした。幸いなことに、私はテストを受け、バグを修正するために必要なことを正確に教えてくれました。テストがなければ、私はシステムを構築し続け(そのコードに依存する他のモジュールにバグが感染する)、バグが発見されるまでに、それを適切に修正することは大きなタスクでした。

TDDの真の利点は、無謀な放棄で変更を加えることができることです。それはプログラミングの安全策のようなものです。空中ブランコのアーティストがミスをして転倒したらどうなるか考えてみてください。ネットでは、それは恥ずかしい間違いです。なしでは、それは悲劇です。同様に、TDDを使用すると、骨の折れる間違いをプロジェクトの惨事に変えることを防ぐことができます。


4
バグをキャッチする赤のテストの価値は、特にTDDの属性ではなく、単体テストの属性です。
ロバートハーヴェイ

2
あなたはその点で正しいです。しかし、特定のバグが事後の単体テストでカバーされている可能性は低くなります。
マイケルブラウン

1
証拠、データ、または確固たる分析でその主張を支持できますか?
CesarGon

1
@CesarGon この研究は、小規模プロジェクトに取り組んでいるプログラマーの一方で、TDDを使用する開発者は、事後テストよりもテスト範囲が広いコードを生成し(92%-98%対80%-90%)、より多くをキャッチすることを示唆しています開発中の欠陥(TDDを使用して生成されたコードで見つかった欠陥が18%減少)。
ジュール14年

11

テスト駆動型開発、またはテスト駆動型設計(異なる)を提唱する人はいません。テストはアプリケーションを証明します。だから、それをただのストローマンと呼んで完了させましょう。

テストが時間と労力の浪費であると言うTDDに嫌悪感を抱いている人や感心していない人はいません。テストはアプリケーションを証明しませんが、エラーを見つけるのに非常に役立ちます。

これら2つのことから、どちらの側も、ソフトウェアで実際にテストを実行することに関して異なることをしていません。両方ともテストを行っています。両方とも、できるだけ多くのバグを見つけるためのテストに依存しており、両方ともテストを使用して、ソフトウェアプログラムが動作しており、その時点で発見できることを確認します。手掛かりの半分の人がテストなしでソフトウェアを販売することはありません。

したがって、TDDと非TDDの違いは、テストが行​​われているということではありません。違いは、テストを作成するタイミングです。TDDでは、ソフトウェアの前にテストが記述されます。not-TDDテストは、ソフトウェアの後、またはソフトウェアと一緒に作成されます。

後者に関して私が見た問題は、テストでは、目的の結果や仕様よりも記述されているソフトウェアをターゲットにする傾向があるということです。テストチームが開発チームから分離されている場合でも、テストチームはソフトウェアを見て、それで遊んで、それを対象とするテストを書く傾向があります。

プロジェクトの成功を研究する人々によって何度も気づかれていることの1つは、顧客が望むものをレイアウトする頻度、開発者が逃げて何かを書くこと、そして顧客が「完了」と言って戻ってくるときです。それは、顧客が求めたものではなく、完全に完全であることが判明しました。「しかし、すべてのテストに合格します...」

TDDの目標は、この「循環論法」を破り、ソフトウェアそのものではないソフトウェアをテストするテストの基礎を提供することです。テストは、「顧客」が望んでいる動作を対象とするように作成されています。ソフトウェアは、これらのテストに合格するように作成されます。

ただし、TDDはこの問題に対処するためのソリューションの一部です。あなたが行う唯一のステップではありません。あなたがする必要がある他のことは、より多くの顧客フィードバックとより頻繁にあることを確認することです。

しかし、私の経験では、TDDをうまく実装することは非常に困難です。多くの自動化されたテストでは、自動化ソフトウェアを正しく動作させるために何かをする必要があるため、製品が発売される前にテストを作成するのは困難です。また、単体テストに慣れていない開発者にそれを実行させることも困難です。何度も何度もチームの人々にテストを最初に書くように言ってきました。私は実際にそれをやったことがありません。最終的には、時間の制約と政治がすべての努力を破壊し、ユニットテストさえも行わなくなった。もちろん、これにより、必然的に、設計が偶然および厳しく結合されることになり、その結果、たとえ実行したとしても、実装するのに法外なコストがかかることになります。TDDを回避することが、TDDが最終的に開発者に提供するものです。


+1包括的な答えをありがとう、ノア。TDDとnot-TDDの主な違いは、テストを作成するときです。ただし、TDDの最初の「D」は「駆動」を表していると思います。つまり、TDDでは、開発全体がテストによって駆動されるということです。それは私が最も不可解であると思うものです。テスト対象を実際に構築する前に、テストを書くことに問題はありません。しかし、テストを駆動させますか?表面的な(つまり結果)が問題ない限り、緑色のライトとは何が違うのでしょうか。
CesarGon

さて、セザール、開発タスクがいつ終了するかを決定するためのより良い、客観的な基準として何を提案しますか?TDDのように、テストが開発者が対象とする仕様である場合、開発者はテストの合格時に作業を完了していますか?はい、どの仕様にも欠陥があるように、テストにも欠陥がある可能性があります。しかし、それは解決する開発者の仕事ではありません。テストに欠陥がある場合は修正され、開発は新しいターゲットをターゲットとし、すべてがグリーンになったら完了です。常にテストに合格するために機能します...余分な、文書化されていない綿毛はありません。
エドワードストレンジ

3
たぶん私は自分自身をはっきりと表明しなかった。テストは、完了したかどうかを判断する良い方法です。しかし、私は彼らがあなたが構築しなければならないものを決定する良い方法だとは思わない。そして、TDDでは、人々はテストを使用して、ビルドするものを決定していることがわかります。それもあなたの経験ですか?
CesarGon

いいえ。ビルドは自動化されています。それらは変更によってトリガーされます。前述したように、TDDはソリューションの一部にすぎません。
エドワードストレンジ

9

最初に設計する

TDDは設計をスキップする言い訳ではありません。すぐにコーディングを開始できたにもかかわらず、「アジャイル」な時流に多くのジャンプを見てきました。真のアジャイルにより、ウォーターフォールプロセスに影響を与えた(他の分野の)エンジニアリンググッドプラクティスよりもはるかに高速にコーディングを統計することができます。

しかし、早期にテストする

テストが設計を推進していると言うとき、それは単に、設計フェーズの非常に早い段階で、それが完了するずっと前にテストを使用できることを意味します。このテストを行うと、製品が完成するずっと前に灰色の領域に挑戦し、現実の世界に照らして設計に大きな影響を与えます。これを考慮して設計に戻って調整することを頻繁に強制します。

テストと設計...まったく同じ

私の意見では、TDDは、テストを最後に検証のために行うのではなく、単にデザインの不可欠な部分にするだけです。TDDの使用を開始するにつれて、システムを設計するときにシステムを破壊/破壊する方法の考え方がますます強くなります。個人的には、常に最初にテストを行うとは限りません。確かにインターフェイス上で明白な(ユニット)テストを行いますが、実際の利益は、このデザインが破れる新しい創造的な方法を考えるときに作成する統合テストと仕様テストから得られます。方法を考えるとすぐに、そのためのテストをコーディングし、何が起こるかを確認します。時々、結果に耐えることができます。この場合、メインビルドの一部ではない別のプロジェクトにテストを移動します(失敗し続けるため)。

それでは誰がショーをドライブしますか?

TDDでは、ここでの駆動とは、テストが設計に非常に強く影響するため、実際にテストを実行していると感じることができることを意味します。しかし、それはそれで止まります、そして、ここであなたの懸念を理解しています、それは少し怖いです...誰がショーを運転しますか?

あなたはテストではなく運転しています。テストはそこにあるので、あなたが進んでいくと、あなたが作成したものに対して十分な自信を得ることができ、それにより、それがしっかりした根拠に基づいていることをさらに知ることができます。

テストが固体である限り固体

正確に、したがって、TDDで駆動されます。テストがすべてを推進しているわけではありませんが、システムが設計方法や考え方に大きな影響を与えているため、思考プロセスの大部分をテストに委任し、見返りにしています彼らはあなたのデザインに深い影響を与えます。

ええ、でも、もし橋でそれをやると…

ソフトウェアエンジニアリングは、他のエンジニアリングプラクティスとはまったく異なります。実際、ソフトウェアエンジニアリングには、実際に文学との共通点が多くあります。完成した本を取り、それから4つの章をリッピングし、2つの新しい章を書いてそれらを置き換えることができます。優れたテストとソフトウェアを使用すると、システムの任意の部分をリッピングして別の部分に置き換えることができます。そのためのコストは、そもそもシステムを作成するよりも高くありません。実際、テストを行って設計に十分な影響を与えた場合、最初の段階で作成するよりもはるかに安くなる可能性があります。これは、この置換がテストの対象を破壊しないというある程度の自信があるからです。

そのすっごく良い方法は、なぜそれが常に動作しないのですか?

テストには、構築とはまったく異なる考え方が必要だからです。すべての人が戻ったり戻ったりできるわけではありません。実際、創造を破壊するように心を決められないという理由だけで、適切なテストを構築できない人もいます。これにより、テストの数が少なすぎるか、ターゲットメトリックに到達するのに十分なテストが得られます(コードカバレッジが頭に浮かびます)。彼らは幸せなパステストと例外テストを行いますが、コーナーケースと境界条件については忘れます。

他の人は、設計を部分的にまたはまったく行わないテストに依存するでしょう。それを行う各メンバーは、お互いに統合することです。デザインは何よりもまずコミュニケーションツールであり、私たちがここにいると言うために地面に置いたステーク、これがドアと窓がある場所だと言うスケッチです。これがなければ、あなたは、あなたがそのソフトウェアに何回テストを入れても、運命づけられます。統合とマージは常に苦痛を伴い、最高レベルの抽象化でのテストが不足します。

これらのチームのTDDは、進むべき道ではないかもしれません。


7

TDDを使用すると、テストが簡単または迅速でないコードを記述しない傾向があります。これは小さなことのように思えるかもしれませんが、リファクタリング、テスト、テストでのバグの再現、修正の検証がどれだけ簡単かということに影響するため、プロジェクトに大きな影響を与える可能性があります。

また、プロジェクトの新しい開発者は、テストでサポートされているコード化されたより優れたコードを使用していると、速度を上げるのが簡単になります。


2
私はこれが好きです-それは、テスト可能な(孤立して)という意味で生成するコードの種類として、(ユニットテストがあることは明らかに膨大な価値がありますが)利益を生み出すTDDではないという点を強調していますそれからあらゆる種類の良いこと(懸念の分離、IoC、依存性注入など)
マーフ

1
@MurphええTDDはあなたを正直に保つのに役立ちます:)
Alb

1
正直に言うと、「速度を上げるのが簡単だ」という議論に実際には納得していません-テストは役立つかもしれませんが、コード(全体として、必ずしも分離されている必要はありません)は、いくつかのものがまるで魔法のように見える。たとえば、使用しているIInjectedThingの実装がわからない。
マーフ

@Murph理論では、実装IInjectedThingも適切に設計されており、適切なテストでカバーされているため、インジェクトされたクラスを理解できるかどうかを実際に知る必要はありません。
アダムリア

@アンナ-はい、ある程度まで...何かが壊れている場所(私はいつもバグハンティングがプロジェクトの足跡を見つけるのに良い方法だと思っています)または何かを変更する必要がある場所を解決しようとしている場合/どこを知る必要があると付け加えました。その場所がうまくカプセル化されていても、それを見つける必要があります...そしてそれが何かを置き換えることを意味する場合(IWhatsitの新しい実装)、代替実装の使用方法を知る必要があります。繰り返しになりますが、構造が悪いこと-反対の証拠が多すぎること-を否定するつもりはありません。
マーフ

5

私はTDDをあまり練習していませんが、これについてはずっと考えてきました。コード品質と後続のTDDの間に(強い?)正の相関があるようです。

1)私の最初の考えは、これは(主に)TDDがコードに「より良い品質」を追加することによるものではなく(そのようなものとして)、TDDが最悪の部分や習慣を取り除くのに役立ち、間接的に品質を向上させることです。

私もそれがテストそのものではないことを提唱う-それはプロセスです書いてこれらのテストを。悪いコードのテストを書くのは難しいですし、逆の場合も同様です。また、プログラミング中にこれを後回しにしておくことで、多くの不正なコードを排除できます。

2)別の観点(これは哲学的になっています)は、マスターの精神的な習慣に従うことです。あなたは彼の「外部の習慣」に従うことによってマスターになることを学ぶことはありません(例えば、長いひげは良いです)、あなたは彼の内部的な考え方を学ばなければなりません、そしてこれは難しいです。そして、どういうわけか(初心者)プログラマーをTDDに従って、マスターの考え方に近い考え方を揃えます。


+1マグロブ、あなたはそれを釘付けにしたと思う。「TDDは、最悪の部分や習慣を取り除くのに役立ち、品質を間接的に向上させる」というあなたの説明が特に気に入っています。そして、長いひげの類推も非常に良いです。
CesarGon

不良コードのテストを作成するのではなく、テストを作成してからコードを作成してテストに合格します。

Maglob、物事のより実用的な側面の愛のために、あなたはそれを最高にカバーしました。@Thorbjørn、マグロブは、予想されたデザインがひどい場合、テストは具体化しようとしている吸うさのレベルに直接吸い上げなければならず、その腐った臭いはあなたのテストで臭いがするはずです実際のコードを書くことさえできます。
フィリップデュパノビッチ

3

「書き込みテスト+合格するまでリファクタリングする」アプローチは、信じられないほどアンチエンジニアリングに見えます。

リファクタリングとTDDの両方について誤解しているようです。

コードリファクタリングとは、ソフトウェアの非機能属性の一部を改善するために、外部機能動作を変更せずにコンピュータープログラムのソースコードを変更するプロセスです。

したがって、合格するまでコードをリファクタリングすることはできません。

そして、TDD、特にユニットテスト(他のテストはかなり妥当と思われるため、コアの改善と考えています)は、機能するまでコンポーネントを再設計することではありません。コンポーネントが設計どおりに機能するまで、コンポーネントを設計し、実装に取り​​組みます。

また、それは本当に把握することが重要で、そのユニットテストはおよそテストしている単位を。常にゼロから多くのことを書く傾向があるため、そのようなユニットをテストすることが重要です。土木技師は、使用しているユニットの仕様(さまざまな材料)をすでに知っており、動作することを期待できます。これらは多くの場合ソフトウェアエンジニアには当てはまらない2つのことです。テスト済みの高品質のコンポーネントを使用することを意味するため、ユニットを使用する前にテストすることは非常にプロエンジニアリングです。
土木技師がスタジアムを覆う屋根を作るために新しい繊維ティッシュを使用するというアイデアを持っていた場合、彼はそれをユニットとしてテストすることを期待します。その後、それらが満たされるまでテストと改良を行います。

それがTDDが機能する理由です。テストされたユニットのソフトウェアを構築する場合、それらを一緒に接続し、そうでない場合、テストのカバレッジが良好であると仮定して、グルーコードに問題があると予想できる可能性がはるかに優れています。

編集:
リファクタリングとは、機能に変更がないことを意味します。単体テストを記述する1つのポイントは、リファクタリングによってコードが破損しないことを確認することです。TDDは、リファクタリングに副作用がないことを保証するためのものです。
先ほど言ったように、粒度は正確には定義されていないため、システムではなくユニットをテストするため、粒度は観点の対象ではありません。

TDDは優れたアーキテクチャを促進します。すべてのユニットの仕様を定義および実装する必要があり、実装前にそれらを設計する必要がありますが、これはあなたが考えていることとはまったく反対です。TDDはユニットの作成を指示します。ユニットは個別にテストできるため、完全に分離されます。
TDDは、スパゲッティコードでソフトウェアテストを投げ、パスタがパスするまで攪拌するという意味ではありません。

土木工学とは対照的に、ソフトウェア工学では通常、プロジェクトは常に進化しています。土木工学では、位置Aに橋を建設する必要があります。橋はxトンを運ぶことができ、1時間にn台の車両に十分な幅があります。
ソフトウェアエンジニアリングでは、顧客は基本的に任意の時点(おそらく完成後)で、ダブルデッキブリッジを望み、最寄りの高速道路に接続することを望みます。最近、帆船を使い始めました。
ソフトウェアエンジニアは、設計を変更する必要があります。彼らのデザインに欠陥があるからではなく、それが手口だからです。ソフトウェアが適切に設計されていれば、低レベルのコンポーネントをすべて書き直すことなく、高レベルで再設計できます。

TDDは、個別にテストされ、高度に分離されたコンポーネントを使用してソフトウェアを構築することです。適切に実行されると、要件の変更に対応するのに役立ちます。

TDDは開発プロセスに要件を追加しますが、品質保証の他の方法を禁止しません。確かに、TDDはフォーマル検証と同じセキュリティを提供しませんが、フォーマル検証は非常にコストがかかり、システムレベルで使用することは不可能です。それでも、必要に応じて、両方を組み合わせることができます。

TDDには、システムレベルで実行される単体テスト以外のテストも含まれます。これらは説明しやすいが、実行するのが難しく、測定するのが難しいと思う。また、彼らは非常に妥当です。私は彼らの必要性を絶対に見ていますが、私はそれらをアイデアとして本当に評価していません。

最終的に、実際に問題を解決するツールはありません。ツールは問題の解決を容易にするだけです。あなたは尋ねることができます:ノミはどのように素晴らしい建築で私を助けますか?まっすぐな壁を作るつもりなら、まっすぐなレンガが助けになります。確かに、そのツールをバカに渡せば、彼は最終的に彼の足を叩くでしょうが、それはノミのせいではありません。初心者に誤ったセキュリティを与えるのはTDDの欠陥ではないからです良いテストを書かない人。
結論として、TDDはTDDを使用しないよりもはるかに優れていると言えます。


誤解しているとは思わない。投稿したコードリファクタリングの定義に同意しますが、コードの変更の粒度を確認する必要もあると思います。「コンピュータープログラムのソースコードを変更するプロセス」と言うとき、特定の全体の観点からは、動作は変わらないが、部品の動作は実際に変わることを認識する必要があります。それが変化の影響です。これに加えて、TDDがなぜ機能するのか(そしてそれを共有します)についてもお聞きしますが、元の投稿に従ってアーキテクチャはどのように対処されていますか?
-CesarGon

@CesarGon:投稿が更新されました。
back2dos

2

「ユーザーではなくテストが要件を設定する」という発言が好きではありません。TDDでは単体テストのみを検討していると思いますが、統合テストも対象としています。

ソフトウェアのベースを構成するライブラリのテストとは別に、ユーザーがソフトウェア/ウェブサイト/その他との相互作用をカバーするテストを作成します。これらはユーザーから直接送られてくるものであり、cucumber(http://cukes.info)のようなライブラリーでは、ユーザーが自然言語でテストを自分で書くことさえできます。

また、TDDはコードの柔軟性を促進します。何かのアーキテクチャを永遠に設計することに費やした場合、必要に応じてそれらの変更を後で行うことは非常に困難になります。いくつかのテストを書くことから始め、それらのテストに合格する小さなコードを書きます。テストを追加し、コードを追加します。コードを根本的に変更する必要がある場合でも、テストは有効です。

また、橋や車とは異なり、1つのソフトウェアはその存続期間中に大きな変更を受ける可能性があり、最初にテストを作成せずに複雑なリファクタリングを行うことは、単にトラブルを要求するだけです。


TDDについてあなたが主張する利点について聞いています。しかし、私が理解している限り、あなたは私の質問で明示的に求めているアーキテクチャとテスト品質の問題に対処していません。
CesarGon

@CesarGon:特定の質問は、TDDだけでなく、あらゆる種類のテストに当てはまると思います。それで、私はちょうど「働く」TDDの特定の機能に集中しました。
sevenseacat

1
統合テストは、スタンドアロンの単体テストよりも間違いなく意味があります。私が偶然見つけたほとんどのバグのケースは、すべてのボルトとホイッスルを所定の位置に置いて実際のシステム全体をテストすることによってのみ、単体テストで発見されることはなかったでしょう。

2

間違った角度から最初のポイントに近づいていると思います。

理論的な観点から、障害点をチェックすることで何かが機能することを証明しています。それが使用される方法です。何かが機能していることを証明できる方法は他にもたくさんありますが、TDDはビット単位のアプローチの単純さにより確立しています。

実際には、これは率直に言って次のように変換されます。次のことに進むことができます(すべての述部を満たすためにTDDを正常に適用した後)。この観点からTDDにアプローチする場合、「テストを書く+パスまでリファクタリングする」ことではなく、これを完了することです。私は今、最も重要なこととして次の機能に完全に焦点を当てています。

これが土木工学にどのように適用されるか考えてください。15万人の観客を収容できるスタジアムを建設しています。スタジアムの構造的健全性が健全であることを証明した後、まず安全性を満足させました。洗面所、フードスタンド、座席など、すぐに重要になる他の問題に焦点を当てることができます...観客の体験をより楽しいものにします。TDDにはさらに多くの要素があるため、これは単純化しすぎていますが、重要なのは、新機能とエキサイティングな機能の両方に焦点を合わせ、同時に整合性を維持する場合、最高の最悪のユーザーエクスペリエンスを実現できないことです。どちらの場合も途中で取得します。つまり、どうやって正確に知ることができます多くの洗面所があり、150000人のためにどこに配置すればよいですか?私は自分の生涯でスタジアムが崩壊することはめったにありませんでしたが、ハーフタイムの間は非常に多くの機会に並んで待たなければなりませんでした。それは、トイレの問題はほぼ間違いなくより複雑であり、エンジニアが安全に費やす時間が少なくなると、最終的にトイレの問題を解決できる可能性があることを示しています。

あなたの2番目のポイントは無関係です。なぜなら、アブソリュートは愚か者の努力であることにすでに同意しており、ハンクムーディはそれらが存在しないと言っているからです(しかし、そのための参照が見つからないようです)。


私の最初のポイントの良い説明とハンク・ムーディーへの言及のために+1。栄光。
CesarGon

2
感謝します。TDDは、技術的なアプローチ/プロセスではなく、心理的な現象として捉えています。しかし、それは問題に関する私の世界観です。
フィリップデュパノビッチ

トイレの数と配置場所を正確に知ることができますか?答えはイエスです。アーキテクトに尋ねると、この情報は事前に作成され、時には明確な統計データでバックアップされていることがわかります。
gbjbaanb

1

ソフトウェアエンジニアリングのTDDは、アプリケーションでのエラー処理と同様に、ログ記録と診断(エラー処理の一部ですが)と同様に、優れた実践です。

TDDは、ソフトウェア開発を試行錯誤のコーディングに減らすためのツールとして使用することはできません。それでも、ほとんどのプログラマーは、ランタイムログをじっと見たり、デバッガーで例外を監視したり、アプリのコーディング/コンパイル/実行で構成される開発フェーズ中に他の失敗/成功の兆候を終日使用します。

TDDは、これらのステップを形式化および自動化して、開発者としての生産性を向上させるための単なる方法です。

1)ソフトウェアエンジニアリングと橋梁建設を比較することはできません。橋梁建設の柔軟性は、ソフトウェアプログラムの設計に匹敵するものではありません。ブリッジの構築は、同じプログラムを損失の多いマシンに何度も書くようなものです。ソフトウェアのようにブリッジを複製して再利用することはできません。各ブリッジは一意であり、製造する必要があります。車や他のデザインにも同じことが言えます。

ソフトウェアエンジニアリングで最も難しいことは、障害を再現することです。ブリッジに障害が発生した場合、通常、障害の原因を特定するのは非常に簡単で、理論的には障害を再現するのは簡単です。コンピュータプログラムが失敗すると、システムが障害状態になったイベントの複雑なチェーンになり、エラーの場所を特定するのが非常に難しくなります。TDDとユニットテストにより、ソフトウェアコンポーネント、ライブラリ、アルゴリズムの堅牢性を簡単にテストできます。

2)システムにストレスをかけずに弱い単体テストと浅いテストケースを使用して、誤った自信を構築することは、単に悪い習慣です。システムのアーキテクチャの品質を無視し、テストを実行するだけでも、もちろん悪いことです。しかし、高層ビルや橋の建設現場で材料を節約し、設計図に従わないために不正をすることは同じくらい悪いことであり、それは常に起こります...


物理(つまりソフトウェアではない)システムで障害を再現するのは簡単であるというあなたの意味に同意しません。たとえば、航空交通事故の機械的故障の根本原因を特定するために必要な、非常に複雑で困難な作業を見てください。
CesarGon

うーん、今、クラッシュしている旅客機と故障している橋を比較しています。通常、橋は飛ぶことができず、ケースは閉じられています。しかし、飛行機とソフトウェアの比較は有効な場合があります。どちらの領域も非常に複雑であり、構造化されたテスト方法論が必要です。そのため、ブリッジに障害が発生すると、ブリッジが過負荷になっていることがわかります。飛行機がcrash落したとき、地上飛行の異常な状態が失敗したことをよくご存じですが、通常、ソフトウェアの障害と同じ徹底的な調査が必要です。
エルネッリ

橋は複製することができます-または、少なくとも、建築家から購入した橋の設計図は、大体、正確な状況に合わせて修正することができます。ポイントは、橋が必要な場合は建築家に行き、彼はあなたが持つことができるいくつかのタイプのリスト-サスペンション、ボックス、アーチなど、そしてそれを構築するための限られた材料のリストをあなたに与えるということです。
gbjbaanb

1

バグがより早く発見され、それらを修正するコストが少ないことを受け入れた場合、それだけでTDDの価値が高まります。


1
TDD設定でバグがより早く発見されるという証拠はありますか?また、アーキテクチャへの影響など、TDDの副作用についてはどうですか?
CesarGon

0

TDDは実際にはテストに関するものではありません。そして、それは確かに良いテストに取って代わるものではありません。それがあなたに与えるものは、よく考えられ、消費者が消費しやすく、後で維持しリファクタリングしやすい設計です。これらのことは、バグの減少と、より優れた、より適応性のあるソフトウェア設計につながります。TDDはまた、仮定を熟考して文書化するのに役立ち、多くの場合、それらの一部が間違っていることを発見します。これらはプロセスの非常に早い段階で見つかります。

また、副次的な利点として、リファクタリングによってソフトウェアの動作(入力および出力)が変更されないことを確認するために実行できるテストの大きなスイートがあります。


6
-1。多くの人がこれを言い続けていますが、私はそれを実現する魔法をまだ見ていません。
バートヴァンインゲンシェ

@Bart van Ingen Schenau、TDDをやったことがありますか?私はそれを約4年間やっていますが、「魔法」が起こるのは間違いありません。
マーシー

0

簡単に答えます。通常、TDDは、単体テストと同様に間違った方法で見られます。良いテクトークビデオを見た後、最近までユニットテストを理解していませんでした。基本的に、TDDは、次のことを機能させたいと述べているだけです。それらを実装する必要があります。次に、通常の方法で残りのソフトウェアを設計します。

ライブラリを設計する前に、ライブラリのユースケースを書くようなものです。ライブラリのユースケースを変更でき、TDDを使用しない場合があることを除きます(API設計にはTDDを使用しています)。また、さらにテストを追加し、テストが取得する可能性のあるワイルドな入力/使用について考えることをお勧めします。何かを変更した場合、何かを壊したことを知っておく必要があるライブラリやAPIを作成するときに役立ちます。ほとんどの毎日のソフトウェアでは、ユーザーがボタンを押すためのテストケースが必要なのはなぜですか、CSVリストまたは1行に1つのエントリがあるリストを受け入れる必要があるので、気にしません...それは本当に問題ではありませんそれを変更するには、TDDを使用するべきではありません。


0

構造工学が具体的な場合、ソフトウェアは有機的です。

ブリッジを構築すると、ブリッジのままになり、短期間に他の何かに進化する可能性は低くなります。改善は数か月から数年にわたって行われますが、ソフトウェアのように数時間や数日はかかりません。

単独でテストする場合、通常使用できるフレームワークには2つのタイプがあります。制約のあるフレームワークと制約なし。制約のないフレームワーク(.NET)では、アクセス修飾子に関係なく、すべてをテストして置き換えることができます。すなわち、プライベートおよび保護されたコンポーネントをスタブおよびモックできます。

私が見たプロジェクトのほとんどは、制約のあるフレームワーク(RhinoMocks、NSubstitute、Moq)を使用しています。これらのフレームワークを使用してテストする場合、実行時に依存関係を挿入および置換できるようにアプリケーションを設計する必要があります。これは、疎結合設計が必要であることを意味します。疎結合設計(適切に行われた場合)は、関心事のより良い分離を意味し、これは良いことです。

要約すると、この背後にある考え方は、デザインがテスト可能である場合、疎結合であり、懸念が十分に分離されていると考えています。

ちなみに、私は本当にテスト可能なアプリケーションを見てきましたが、オブジェクト指向の設計の観点からは不十分に書かれています。


0

TDDが機能する理由

そうではありません。

明確化:自動テストは、テストなしよりも優れています。しかし、私は個人的には、ほとんどの単体テストが無駄であると考えています(つまり、テスト中の実際のコードから明らかなことを言います)、一貫性があり、冗長ではなく、すべての境界ケースをカバーすることは簡単に証明できません(エラーが通常発生する場合) )。

そして最も重要なこと:優れたソフトウェア設計は、多くのアジャイル/ TDDエバンジェリストによって宣伝されているように、テストから魔法のように外れることはありません。それ以外の場合は、これを証明する査読済み科学研究へのリンク、または少なくともコード変更履歴によってTDDの利点を調査できる可能性のあるオープンソースプロジェクトへの参照を提供してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.