web-dev-qa-db-ja.com

ユニットテストを書く前にコードを書くことの欠点は何ですか?

私は最初に単体テストを作成してからコードの作成を開始するという推奨を常に見てきました。しかし、実際のコードを記述した後は、はるかに明確になるので、コードを記述してからユニットテストを記述した方がはるかに快適です。コードを記述してからテストを作成する場合、テスト可能なデザインの作成に集中しても、コードを少し変更してテスト可能にする必要がある場合があります。一方、テストを記述してからコードを記述した場合、コードが形を整えると、テストはかなり頻繁に変更されます。

テストの作成を開始してからコーディングに進むための多くの推奨事項を確認したので、逆の方法でコードを作成してユニットテストを行うと、どのような短所がありますか?

33
k25

赤が答えです。赤は、TDDの赤、緑、リファクタリングのサイクルから得られるものであり、テストの最後には得られません。まず、失敗するテストを記述します。それが失敗するのを見てください。それはあなたの赤です、そしてそれは重要です。それは言う:私にはこの要件があり、私はknow私のコードはそれを満たしていません。したがって、ステップ2(緑色)に進むと、コードがその要件を満たしていることも、同じくらい確実にわかります。要件を満たすようにコードベースを変更したことを知っています。

コードに基づいて開発された要件(テスト)は、コードに基づいて、そのような確実性、その信頼性を奪います。

37
Carl Manaster

コードを記述してからテストを記述した場合、コードが仕様に適合することを確認するためのテストを記述するのではなく、コードを渡すためにテストを記述するという罠に陥るのは非常に簡単です。

とは言っても、それが唯一の方法ではなく、ソフトウェアを開発する「最良の」方法はありません。テストケースの開発に多くの先行作業を費やした場合、提案されたアーキテクチャに欠陥があるかどうかはかなり後になるまでわかりません。一方、コードを最初に開発した場合は、より早くそれらに遭遇し、より少ない作業で再設計できます。努力。

18
Anon.

実際、人々はTDDに夢中になるのはテストについてですが、頭字語の他の2文字については忘れています。ここで読むことができるもの: TなしのTDD または TDDはテストに関するものではありません

事は私がTDDでしっかりと編み込まれている他の多くのものを学んだことです。最初にテストするかどうかは関係ありません:ソフトウェア設計について考えていること

単体テストを「正しい方法」で書くこともできるようにするために、つまり、それらが分離され、迅速かつ自動化されているため、うまくいけば、コードをテストしやすくなるようにコードを配置する方法について、いくつかの再考が必要です。

個人的に私は SOLIDの原則 を学んだが、そのようなことが書かれていたことを知らなかった。これは、単体テストを作成すると、クラスを書き直さなければならず、テストが過度に複雑にならないためです。それは次のようなものにつながりました:

  • 意味をなさないか、プライベートメソッドに常駐していた機能を個別のクラスに移動して、個別にテストできるようにする必要がありました。 (単一責任原則)。
  • 大きな継承構造を回避し、代わりに構成で実装を拡張する必要がありました(Open-Closed原理で顕著です)。
  • 継承については賢くする必要があり、共有できる共通のコードを見つけてスタブメソッドを使用するときは常に抽象クラスを使用しました(Liskov Substitution Principle)。
  • クラスを分離してテストできるように、インターフェイスと抽象クラスを作成する必要がありました。誤ってモックオブジェクトを作成することになります。 (インターフェース分離原理)
  • たくさんのインターフェースと抽象クラスを書いたので、変数とパラメーターを宣言して、共通の型(依存関係の逆転の原則)を使用するようにしました。

常にテストファーストを行うわけではありませんが、テストを少し簡単にするために、私はたまたまあなたが従い始めた優れたOOの原則と実践に従います。今私はそれ自身のためにコードを書いているわけではありません。私は簡単にテストできるように、またはさらに重要なことにコードを書きました。 メンテナンスが簡単

13
Spoike

他のすべての答えは良いですが、触れられなかった点が1つあります。最初にテストを作成すると、テストが確実に作成されます。作業コードを記述したら、テストをスキップしてUIで確認するのは魅力的です。コードを作成する前に常に失敗するテストを行うという規律がある場合は、このトラップを回避できます。

10
RationalGeek

最初にテストを作成すると、そのデザインが「石にキャストされる」前に、デザインについて考える機会が再び得られます。

たとえば、特定のパラメータセットを受け取るメソッドが必要だと思うかもしれません。また、最初にコードを記述した場合は、そのように記述して、テストを指定されたパラメーターに適合させます。しかし、最初にテストを作成すると、「ちょっと待って、メインラインコードでこのパラメーターを使用したくないので、APIを変更する必要があるかもしれません」と考えるかもしれません。

4
Anon

テストの作成を開始してからコーディングに進むための推奨事項がたくさんあるので、

これには本当に正当な理由があります。

「正しいと思うことをする」と言うと、人々は愚かでクレイジーなことをします。

「テストを最初に書く」と言うと、人々は少なくとも正しいことをしようとするかもしれません。

コードを書いてからユニットテストを逆に行うと、どのような短所がありますか?

通常、お粗末なテストと、テストできるように手直しする必要のあるデザイン。

ただし、これは「通常」に過ぎません。一部の人々は、設計とテストを並行して進化させます。一部の人々は、テスト可能なコードを配置し、やり直しなしでテストを記述します。

「テストファースト」のルールは、まったく手がかりのない人に教えるためのものです。

同様に、道路を横断する前に常に「両方」を見るように指示されます。ただし、実際にはそうではありません。そして、それは問題ではありません。私は右ハンドルの国に住んでおり、横断を開始するときは左を見るだけです。

私が左ハンドルの国を訪問するとき、左を見るだけで私を殺すことができました。

ルールは理由のために非常に強く述べられています。

あなたがすることはあなた自身の問題です。

2
S.Lott

最初にテストを書くことのポイントは、あなたが考えることです

  • コードをテストする方法
  • テスト可能にするためにコードが提示する必要のあるインターフェース

単純なことをしている場合は、最初に何を書いてもかまいません(ただし、テストを最初に行う習慣を身に付けるのは良いことです)。テストは単純で、インターフェースは明白です。

しかし、TDDは単体テストだけでなく受け入れテストにもスケールアップし、インターフェースは重要なものになります。

2
Steven A. Lowe

最初にテストを記述しないと、テスト駆動開発(TDD)を実行できません。メリットは数多くあり、何度も練習するまでは信じがたいことが多くあります。以下は、従来の開発よりもTDDを実行することで得られた利点です。

  1. テストのセーフティネット-知らないうちに何かを壊すことを恐れずに大きな変更を加えることができます
  2. オーガニックデザイン-私が最終​​的に作成するデザインは、通常、最初から行ったデザインとは異なり、常に優れています
  3. 生産性-小さな目標に向けて作業し(この1つのテストに合格)、それを達成する(すべてのテストに合格)ことは私にとって非常にうまく機能し、やる気を維持します。ペアで追加すると、私の生産性は新しい最高に達します。

書籍:Beck、K.例によるテスト駆動開発

良い例: http://jamesshore.com/Blog/Lets-Play/

1
Mike Polen

テストを書くとき、それが失敗条件を検出することをどのようにして知っていますか?答えは「テストをテストする」です。その方法は、最初にテストを記述し、失敗することを確認し、テスト中のユニットが正常にコーディングされたときにのみ成功することを確認することです(他の回答の1つで述べた赤/緑/リファクターサイクル)。

最初にコードを記述してからテストを行うと、テストが正直な失敗を示すかどうかという疑問が残ります。

テストは仕様を表していることに注意してください。コードが「形を整える」ようにテストを修正する必要がある場合は、仕様が変更されていることを示しています。それは良いことかもしれませんし、そうでないかもしれません。問題の理解が最初は正しくなかった可能性があります。一方、それは、ユニットがその仕事を「どのように」行っているかをテストしていることを意味する可能性がありますwhatそれは達成されているはずです。

0
Zenilogix