paint-brush
私がTDDが不可欠だと思わない理由by@shai.almog
1,162
1,162

私がTDDが不可欠だと思わない理由

Shai Almog5m2022/11/22
Read on Terminal Reader

テスト駆動開発は、統合テストよりもユニットに重点を置いています。その結果、製品に組み込まれたバグを特徴とする低品質になる可能性があります。
featured image - 私がTDDが不可欠だと思わない理由
Shai Almog HackerNoon profile picture


私は最近、ロンドンの Java コミュニティでデバッグについて講演しました。 Q&A の部分で、テスト駆動開発に対する私のアプローチについて尋ねられました。以前、私はその慣行をよりポジティブな見方で見ていました。たくさんのテストを書く。どうしてそれが悪いのでしょうか?

しかし、時間が経つにつれて、私はそれを別の観点から見ています。


私はそれを、非常に特殊なユースケースを持つ非常に限定されたツールだと考えています。それは私が構築するプロジェクトのタイプに適合せず、促進するはずの流動的なプロセスをしばしば妨げます。しかし、ちょっと話を戻しましょう。 TDD のタイプと問題を分離する この投稿がとても気に入りました。しかし、少し単純化して、すべての PR が十分に報道されるべきであることを明確にしましょう。これは TDD ではありません。それはちょうど良いプログラミングです。


TDDはそれ以上です。その中で、制約を定義してから問題を解決する必要があります。そのアプローチは、問題を解決してから制約が正しいことを確認するよりも優れていますか?これが、TDD と優れたテスト カバレッジを作成することの基本的な前提です。

いいもの

TDD は興味深いアプローチです。緩く型付けされた言語を扱う場合に特に便利です。そのような状況では、TDD は厳密なコンパイラとリンターの役割を果たしているので素晴らしいです。

それが理にかなっている場合は他にもあります。入力と出力が非常に明確に定義されたシステムを構築している場合。コースや資料を作成するときに、これらのケースに多く遭遇しました。実世界のデータを操作する場合、データを処理して定義済みの形式で出力するミドルウェアがある場合に、これが発生することがあります。


アイデアは、中間に隠れた変数を使用して方程式を構築することです。次に、コーディングは方程式を埋めることになります。といった場合にとても便利です。コーディングは穴埋めになります。

悪い人

「テスト駆動開発は複式簿記です。同じ規律。同じ理屈。同じ結果です。」 – ボブ・マーティンおじさん


テストは複式簿記に少し似ていると思います。はい。テストが必要です。問題は、テストに基づいてコードをビルドする必要があるか、またはその逆かということです。ここで、答えはそれほど単純ではありません。


テストを備えた既存のシステムがある場合、TDD は世界的に理にかなっています。しかし、まだ構築されていないシステムをテストしています。理にかなっている場合もありますが、思ったほど頻繁ではありません。


TDDの大きな主張は「そのデザイン」です。テストは実質的にシステム設計であり、その設計を実装します。これの問題は、デザインをデバッグできないことです。以前、日本の大手企業のプロジェクトに携わりました。この会社には、最大かつ最も詳細な別館の設計図書セットがありました。これらの設計仕様に基づいて、同社は何千ものテストを作成しました。私たちのシステムは膨大な量のテストに合格するはずでした。ほとんどが自動化されていないことに注意してください。


テストにはバグがありました。多くの競合する実装がありましたが、テストでバグを発見したものはありませんでした。なんで?それらはすべて、同じリファレンス実装のソース コードを使用していました。私たちは、それをスキップしてクリーンルームの実装を行った最初のチームでした.これらのバグはコードに永続化され、一部は以前のすべてのリリースに影響を与える重大なパフォーマンス バグでした。

しかし、本当の問題は進行が遅かったことです。会社はすぐに前に進むことができませんでした。 TDD の支持者は、TDD プロジェクトの方がリファクタリングが容易であるとすぐにコメントするでしょう。なぜなら、テストによってリグレッションが発生しないことが保証されるからです。ただし、これは事後にテストが実行されるプロジェクトに適用されます。

もっと悪いです

TDD は、高速な単体テストに重点を置いています。低速の統合テストや、TDD システムで一晩実行できる長時間のテストを実行するのは現実的ではありません。主要システムへの拡張と統合をどのように検証しますか?


理想的な世界では、すべてがレゴのようにカチッとはまります。私はそのような世界に住んでいません。統合テストはひどく失敗します。これらは、追跡が最も困難なバグを伴う最悪の失敗です。ユニットテストで失敗した方がいいので、ユニットテストを行っています。簡単に修正できます。しかし、完全なカバレッジがあっても、相互接続を適切にテストしていません。統合テストが必要で、彼らは最もひどいバグを見つけます。


その結果、TDD は、本質的な統合テストよりも、「あると便利な」単体テストを過度に強調します。はい、両方を持っている必要があります。しかし、統合テストが必要です。それらは、TDD プロセスにきれいに適合しません。

右駆動テスト

ケースバイケースで選択した方法でテストを記述します。事前にテストするのが自然な場合がある場合は、それを使用します。しかし、ほとんどの場合、最初にコードを書く方が自然に思えます。カバレッジの数値を確認することは、テストを作成するときに非常に役立ちます。これは、私が事後に行うことです。


前に述べたように、私は統合テストのカバレッジのみをチェックします。私はそこでも良いカバレッジが欲しいので、ユニットテストとそこでのカバレッジの監視が好きです。しかし、品質に関しては、統合テストだけが重要です。 PR には単体テストが必要です。実装前に単体テストを書いたかどうかは気にしません。その結果を判断する必要があります。

悪い自動化

テスラがモデル 3 の工場を建設していたとき、生産地獄に陥りました。問題の原因は、すべてを自動化しようとしたことにありました。パレートの法則は自動化に完全に適用されます。自動化に対して非常に抵抗力があり、プロセス全体を非常に悪化させるものもあります。


これが実際に失敗するポイントの 1 つは、UI テストです。 Selenium などのソリューションは、Web フロント エンドのテストにおいて大きな進歩を遂げました。それでも、複雑さは途方もないものであり、テストは非常に脆弱です。保守が困難なテストになってしまいます。さらに悪いことに、テストを書き直したくないため、UI のリファクタリングが難しくなっています。


おそらく、テスト済みの機能の 80% を超えることができますが、自動化による利益が減少するポイントがあります。これらの環境では、TDD に問題があります。機能は簡単ですが、テストを構築するのは難しくなります。

ついに

私は TDD に反対ではありませんが、お勧めしませんし、実際には使用しません。テストから始めるのが理にかなっている場合はそうするかもしれませんが、それは実際には TDD ではありません。その結果に基づいてコードを判断します。 TDD は優れた結果をもたらす可能性がありますが、多くの場合、単体テストを強調しすぎます。統合テストは、長期的には品質にとってより重要です。


自動化は素晴らしいです。止まるまで。自動テストがほとんど意味をなさない点があります。それを受け入れて、生産的な方向に努力を集中することで、多くの時間と労力を節約できます。


これは、型安全で厳密な言語を好む Java 開発者としての私の偏見によるものです。 JavaScript や Python などの言語は、柔軟性が高いため、大量のテストからメリットを得ることができます。したがって、これらの環境ではTDDがより理にかなっています。


要約すると、テストは良好です。ただし、TDD はより良いテストを行いません。それがあなたにとってうまくいくなら、それは興味深いアプローチです。場合によっては巨大です。しかし、TDD が不可欠である、あるいは TDD によって結果のコードが大幅に改善されるという考えは、意味がありません。




こちらにも掲載。