TDDで「実際の」コードを記述するのはいつですか?


147

トレーニングビデオで読んで見たすべての例には、単純化した例があります。しかし、グリーンになった後に「実際の」コードをどのように実行するかはわかりません。これは「リファクタリング」の部分ですか?

複雑なメソッドを持つかなり複雑なオブジェクトがあり、テストとそれをパスするための最低限のものを書いた場合(最初に失敗した後、赤)。いつ戻って実際のコードを書きますか?そして、再テストする前に実際のコードをどれだけ書くのでしょうか?最後の方がより直感的だと思います。

編集: 答えたすべての人に感謝します。あなたの答えはすべて私を非常に助けてくれました。私が質問したり、混乱させたりしたことについては、さまざまなアイデアがあるようです。

私のデザインには、最初に作りたいアーキテクチャ、ユーザーストーリーなどがあります。ここから、それらのユーザーストーリーを取得し、ユーザーストーリーをテストするためのテストを作成します。ユーザーは、「学校に入学して登録料を支払う人がいます」と言います。だから、私はそれを失敗させる方法を考えます。そうすることで、クラスX(多分Student)のテストクラスを設計しますが、これは失敗します。次に、クラス「Student」を作成します。たぶん「学校」は分かりません。

しかし、いずれにせよ、TD デザインは私に物語を考えさせることを強いています。テストを失敗させることができる場合、失敗する理由はわかりますが、これは合格することを前提としています。それは設計についてです。

私はこれを再帰について考えることに例えました。再帰は難しい概念ではありません。実際に頭の中でそれを追跡するのは難しいかもしれませんが、実際には、最も難しいのは、再帰が「壊れる」とき、いつ停止するかを知ることです(もちろん、私の意見です)。最初に再帰。これは不完全なアナロジーに過ぎず、各再帰反復が「パス」であると想定しています。繰り返しますが、単なる意見です。

実装では、学校は見にくいです。数値および銀行台帳は、簡単な算術を使用できるという意味で「簡単」です。a + bが表示され、0などが返されます。人々のシステムの場合、それを実装する方法をより厳しく考えなければなりません。私は失敗、合格、リファクタリングの概念を持っています(主に研究とこの質問のため)。

私の知らないことは、私の意見では経験の不足に基づいています。新しい学生のサインアップに失敗する方法はわかりません。誰かが姓を入力し、データベースに保存されるのを失敗させる方法がわかりません。私は簡単な数学のためにa +1を作る方法を知っていますが、人のようなエンティティでは、誰かがデータベースまたはその両方、またはどちらでもありません。

または、これは私がまだ混乱していることを示しているかもしれません。


193
TDDの後、人々は夜帰宅します。
ホブス

14
なぜあなたが書いたコードは本物ではないと思いますか?
五葉

2
@RubberDuck他の回答よりも多い。私はすぐにそれを参照すると確信しています。それはまだ一種の外国人ですが、私はそれをあきらめるつもりはありません。あなたの言ったことは理にかなっています。私のコンテキストまたは通常のビジネスアプリケーションで意味をなそうとしています。たぶん、在庫システムなどです。私はそれを考慮しなければなりません。あなたの時間に感謝しています。ありがとう。
ジョニー

1
答えはすでに頭にありますが、すべてのテストに合格し、新しいテスト/機能が必要ない限り、あなたが持っているコードは完成していると想定できます。
ESR

3
「複雑なメソッドを持つかなり複雑なオブジェクトを持っています」で問題になる可能性のある質問には仮定があります。TDDでは、テストを最初に記述するため、かなり単純なコードから始めます。これにより、モジュール式にする必要があるテストに適した構造をコーディングする必要があります。したがって、より単純なオブジェクトを組み合わせることにより、複雑な動作が作成されます。かなり複雑なオブジェクトまたはメソッドで終了する場合は、リファクタリング時です
-Borjab

回答:


243

複雑なメソッドを持つかなり複雑なオブジェクトがあり、テストとそれをパスするための最低限のものを書いた場合(最初に失敗した後、赤)。いつ戻って実際のコードを書きますか?そして、再テストする前に実際のコードをどれだけ書くのでしょうか?最後の方がより直感的だと思います。

「戻って」「実際のコード」を書くことはありません。それはすべて実際のコードです。あなたがすることは戻って、新しいテストに合格するためにコードを変更することを強制する別のテストを追加することです。

再テストする前にどのくらいのコードを書きますか?無し。あなたは書き込みゼロ失敗テストせずにコードを強制的にあなたがより多くのコードを書くこと。

パターンに注目してください。

それが役立つことを期待して、(別の)簡単な例を見ていきましょう。

Assert.Equal("1", FizzBuzz(1));

簡単です。

public String FizzBuzz(int n) {
    return 1.ToString();
}

あなたが本当のコードと呼ぶものではありませんか?変更を強制するテストを追加しましょう。

Assert.Equal("2", FizzBuzz(2));

のような愚かなことをすることもできif n == 1ますが、正気の解決策にスキップします。

public String FizzBuzz(int n) {
    return n.ToString();
}

クール。これは、FizzBu​​zz以外のすべての番号で機能します。量産コードの変更を強制する次の入力は何ですか?

Assert.Equal("Fizz", FizzBuzz(3));

public String FizzBuzz(int n) {
    if (n == 3)
        return "Fizz";
    return n.ToString();
}

そしてまた。まだ合格しないテストを作成します。

Assert.Equal("Fizz", FizzBuzz(6));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    return n.ToString();
}

そして、3の倍数すべてをカバーしました(5の倍数ではありません。注意して戻ってきます)。

「バズ」のテストはまだ書いていないので、書きましょう。

Assert.Equal("Buzz", FizzBuzz(5));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n == 5)
        return "Buzz"
    return n.ToString();
}

繰り返しますが、別のケースを処理する必要があることを知っています。

Assert.Equal("Buzz", FizzBuzz(10));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n % 5 == 0)
        return "Buzz"
    return n.ToString();
}

そして、3の倍数ではない5のすべての倍数を処理できるようになりました。

この時点まで、リファクタリング手順を無視していましたが、重複が見られます。今それをきれいにしましょう。

private bool isDivisibleBy(int divisor, int input) {
    return (input % divisor == 0);
}

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
}

クール。これで重複を削除し、適切な名前の関数を作成しました。コードを変更せざるを得ない次のテストは何ですか?さて、3と5の両方で数値が割り切れる場合を回避してきました。今から書きましょう。

Assert.Equal("FizzBuzz", FizzBuzz(15));

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n) && isDivisibleBy(5, n))
        return "FizzBuzz";
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
}

テストは合格しましたが、さらに重複しています。オプションがありますが、「ローカル変数の抽出」を数回適用して、リライトではなくリファクタリングします。

public String FizzBuzz(int n) {

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
}

また、妥当な入力はすべて網羅しましたが、不合理な入力はどうでしょうか?0または負の値を渡すとどうなりますか?それらのテストケースを作成します。

public String FizzBuzz(int n) {

    if (n < 1)
        throw new InvalidArgException("n must be >= 1);

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
}

これはまだ「実際のコード」のように見え始めていますか?さらに重要なことは、どの時点で「非現実的なコード」でなくなり、「実際の」コードに移行したのでしょうか?それは熟考するものです...

そのため、各ステップでパスしないとわかっているテストを探すだけでこれを行うことができましたが、多くの練習を重ねてきました。私が仕事をしているとき、物事はこれほど単純ではなく、どのテストが変更を強制するかを常に知っているとは限りません。ときどきテストを書いて、それがすでに合格するのを見て驚くでしょう!始める前に「テストリスト」を作成する習慣を身に付けることを強くお勧めします。このテストリストには、考えられるすべての「興味深い」入力が含まれている必要があります。これらすべてを使用するわけではない可能性があり、ケースを追加する可能性がありますが、このリストはロードマップとして機能します。FizzBu​​zzのテストリストは次のようになります。

  • ゼロ
  • 1
  • 6(3の自明でない倍数)
  • 9(3乗)
  • 10(5の自明でない倍数)
  • 15(3と5の倍数)
  • 30(3&5の自明でない倍数)

3
コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
maple_shaft

47
この答えを完全に誤解していない限り、「n == 1の場合は馬鹿げたことをすることができますが、正解にスキップします。」-全体が愚かだった。前もって<spec>を実行する関数が必要なことがわかっている場合は、<spec>のテストを記述し、明らかに<spec>に失敗するバージョンを記述する部分をスキップします。<spec>にバグが見つかった場合は、まずテストを作成して、修正前にテストを実行し、修正後のテストパスを観察できることを確認します。しかし、これらすべての中間ステップを偽造する必要はありません。
GManNickG

16
この回答とTDD全般の主な欠陥を指摘するコメントは、チャットに移動しました。TDDの使用を検討している場合は、「チャット」をお読みください。残念ながら、「質の高い」コメントは、将来の学生が読むためのチャットの負荷の中に隠されています。
user3791372

2
@GManNickGポイントは、適切な量のテストを取得することだと思います。事前にテストを記述することで、どの特別なケースをテストする必要があるかを見逃しやすくなり、テストで十分にカバーされていない状況、またはテストで何度も無意味にカバーされている状況になります。これらの中間ステップなしでそれを行うことができれば、すばらしい!まだ誰もがそうできるわけではありませんが、それは練習が必要なものです。
hvd

1
そして、ここケント・ベックからリファクタリングの引用だ:「今、テストが実行されることを、我々は実現することができます(のように『本当の作る』)要約の実装()」。次に、彼は定数を変数に変更します。この引用は質問と非常によく一致すると感じました。
クリスウォーラート

46

「実際の」コードは、テストに合格するために記述するコードです。本当に。とても簡単です。

テストをグリーンにするために最低限のことを書くことについて人々が話すとき、それはあなたの実際のコードがYAGNIの原則に従うべきであることを意味します。

リファクタリング手順のアイデアは、要件を満たしたことがわかったら、書いたものをクリーンアップすることです。

作成するテストが実際に製品の要件を満たしている限り、合格するとコードは完成します。あなたのビジネス要件のすべてにテストがあり、それらのテストのすべてが環境に優しい場合、それ以上書くことはありますか?(さて、実生活では完全にテストをカバーする傾向はありませんが、理論は正しいです。)


45
単体テストは、比較的些細な要件であっても、実際に製品要件を網羅することはできません。せいぜい、彼らは入出力空間をサンプリングし、アイデアはあなたが完全に入出力空間に(正しく)一般化するということです。もちろん、あなたのコードは、switchすべてのテストに合格し、他の入力に対して失敗する各ユニットテストの場合には、単に大きくなる可能性があります。
デレクエルキンス

8
@DerekElkins TDDは、テストの失敗を義務付けています。単体テストに失敗していません。
-Taemyr

6
@DerekElkinsだからこそ、単体テストを書くだけでなく、偽物ではなく何かを作ろうとしているという一般的な仮定があるのです!
-jonrsharpe

36
@jonrsharpeその論理によって、私は些細な実装を決して書かないでしょう。たとえば、RubberDuckの回答(単体テストのみを使用)のFizzBu​​zzの例では、最初の実装は明らかに「偽物」です。質問に対する私の理解は、不完全であることがわかっているコードの作成と、要件を実装することを本当に信じているコード、つまり「実際のコード」とのこの二分法です。私の「大きなswitch」は、「テストをグリーンにするために最低限のことを書く」という論理的な極端なものとして意図されていました。私はOPの質問を次のように見ます:TDDでは、この大きなことを避ける原理はどこswitchですか?
デレクエルキンズ

2
@GenericJonそれは私の経験では少し楽観的すぎる:) 1つには、心のない反復作業を楽しむ人がいます。彼らは、「複雑な意思決定」よりも、巨大な切り替え声明のほうが幸せです。そして、仕事を失うには、テクニックについて彼らに声をかける人が必要です(そして、彼らは実際に会社の機会/お金を失っているという良い証拠を持っています!)、または非常に悪いことをします。そのような多くのプロジェクトの保守を引き継いだ後、顧客を満足させる(そして支払う)限り、非常に素朴なコードが何十年も続くのは簡単だと言えるでしょう。
ルアーン

14

簡単な答えは、「実際のコード」はテストに合格するコードだということです。実際のコード以外でテストに合格できる場合は、さらにテストを追加してください!

TDDについてのチュートリアルの多くは単純化されていることに同意します。それは彼らに対して機能します。たとえば、3 + 8を計算するメソッドの単純すぎるテストには、3 + 8を計算して結果を比較する以外に選択肢はありません。そのため、コードを全面的に複製しているように見えます。また、テストは無意味で、エラーが発生しやすい余分な作業です。

テストが得意な場合、アプリケーションの構成方法とコードの記述方法がわかります。賢明で有用なテストを思い付くのが難しい場合は、おそらくデザインを少し考え直すべきです。適切に設計されたシステムはテストが簡単です。つまり、賢明なテストは考えやすく、実装も簡単です。

最初にテストを作成し、それらが失敗するのを確認してから、それらをパスさせるコードを作成します。これは、すべてのコードに対応するテストがあることを保証する規律です。私がコーディングしているとき、私はその規則を軽率に守りません。多くの場合、事後にテストを書きます。ただし、最初にテストを行うと、正直になります。ある程度の経験があれば、最初にテストを書いていない場合でも、自分がコーナーにコーディングしていることに気付くでしょう。


6
個人的に、私が書くテストはそうassertEqual(plus(3,8), 11)ではないでしょうassertEqual(plus(3,8), my_test_implementation_of_addition(3,8))。より複雑なケースでは、テストで正しい結果を動的に計算して同等性をチェックする以外に、常に結果を正しく証明する手段を探します。
スティーブジェソップ

したがって、この例で本当に馬鹿げた方法で、plus(3,8)3を減算し、8を減算し、0に対して結果をチェックすることにより、正しい結果を返したことを証明できます。これはassertEqual(plus(3,8), 3+8)、少し馬鹿げていますが、テスト対象のコードが単なる整数よりも複雑なものを構築している場合は、結果を取得して各部分の正確性をチェックするのが適切なアプローチです。あるいは、次のようなものfor (i=0, j=10; i < 10; ++i, ++j) assertEqual(plus(i, 10), j)
スティーブジェソップ

...それは大きな恐怖を回避するためです。つまり、テストを記述するときに、ライブコードで行った "10を追加する方法"について同じ間違いを犯すということです。そのため、テストでplus()は、10を追加する可能性のあるテストでは、10を追加するコードを記述することは慎重に避けられます。もちろん、プログラマーが検証した初期ループ値に依拠しています。
スティーブジェソップ

4
事実の後にテストを書いている場合でも、テストが失敗するのを見るのは良い考えです。作業中の作業に不可欠と思われるコードの一部を見つけて、少し調整し(たとえば、+を-に置き換えます)、テストを実行して失敗するのを確認し、変更を元に戻し、合格するのを確認します。何回もこれを行ったので、テストは実際には失敗せず、役に立たないことよりも悪化しています。何もテストしていないだけでなく、何かがテストされているという誤った自信を与えています!
ウォーボ

6

TDDに関するいくつかの例が誤解を招く場合があります。他の人が以前指摘したように、テストに合格するために書くコードは実際のコードです。

しかし、実際のコードが魔法のように見えるとは思わないでください-それは間違っています。達成したいことをよりよく理解する必要があります。次に、最も簡単なケースとコーナーケースから開始して、それに応じてテストを選択する必要があります。

たとえば、レクサーを作成する必要がある場合は、空の文字列から始め、次に空白の束、数字、空白で囲まれた数字、間違った数字などから始めます。これらの小さな変換は、正しいアルゴリズムですが、実際のコードを完成させるために、最も簡単なケースから非常に複雑なケースにジャンプすることはありません。

ボブマーティンはここでそれを完全に説明します


5

リファクタリングの部分は、疲れて家に帰りたいときに掃除します。

機能を追加する場合、リファクタリング部分は次のテストの前に変更するものです。コードをリファクタリングして、新しい機能のためのスペースを作ります。これは、その新しい機能が何であるかを知っているときに行います。想像しているだけではありません。

これは、クラスを作成する前(テストを追加した後)に名前GreetImplを変更して「Hi Mom」を出力する機能を追加するのと同じくらい簡単です。GreetWorldGreetMom


1

ただし、実際のコードはTDDフェーズのリファクタリングステージに表示されます。つまり、最終リリースの一部となるコード。

テストを変更するたびに実行する必要があります。

TDDライフサイクルのモットーは次のとおりです。REDGREEN REFACTOR

RED:テストを書く

:テストにできるだけ早く合格する機能的なコードを取得しようとする正直な試みを行います。コードの重複、名前がはっきりしない変数が最高位のハッキングなどです。

REFACTOR:コードをクリーンアップし、変数に適切な名前を付けます。コードを乾燥させます。


6
「グリーン」フェーズについてあなたが言っていることは知っていますが、テストに合格するための戻り値のハードワイヤリングが適切である可能性があることを意味します。私の経験では、「グリーン」は要件を満たすために実際に動作するコードを作成するための正直な試みであるはずです。リファクタリングは、開発をさらに進め、最初のパスの問題がより明確になり、DRYの機会が生まれた後、しばらくして行うのが最適です。
mcottle

2
@mcottle:get-onlyリポジトリーの実装がコードベースの値をハードコーディングできることに驚くかもしれません。:)
ブライアンベッチャー

6
入力するのとほぼ同じ速さで本番品質の優れたコードを作成できるのに、なぜ私はくだらないコードを書いてクリーンアップするのでしょうか?:)
カズ

1
@Kazこの方法では、テストされていない動作を追加するリスクがあるためです。ありとあらゆる動作をテストできるようにする唯一の方法は、それがいかにくだらないかにかかわらず、可能な限り単純な変更を行うことです。時には、以下のリファクタリングは...あなたは、事前に考えていなかった新しいアプローチをもたらします
ティモシーTruckle

1
@TimothyTruckle可能な限り単純な変更を見つけるのに50分かかりますが、2番目に単純な変更を見つけるのに5分しかかかりませんか?2番目に単純なものを使用しますか、それとも最も単純なものを探し続けますか?
カズ

1

TDDで「実際の」コードを記述するのはいつですか?

、あなたがどこ相である書き込みコードを。

リファクタリング相主な目的は、することです削除コードを。

では、赤相、あなたはテストに合格するために何かをできる限り迅速かつ任意のコストで。優れたコーディングプラクティスやデザインパターンについて聞いたことがあるものを完全に無視します。テストをグリーンにすることが重要です。

では リファクタリング相あなたがちょうど作っ混乱を一掃します。ここで、最初に行った変更が[ 変換の優先順位]リストの最上位の種類であり、コードの重複がある場合は、デザインパターンを適用することで削除できる可能性が高いかどうかを確認します。

最後に、識別子の名前を変更して読みやすさを向上させ、マジックナンバーやリテラル文字列を定数に抽出します。


それは赤リファクタリングではなく、赤緑リファクタリングです。–ロブキニヨン

これを指摘してくれてありがとう。

だから、ある緑のあなたが書い相実際のコードを

では、赤相次のように記述実行可能な仕様を ...


それは赤リファクタリングではなく、赤緑リファクタリングです。「赤」とは、テストスイートを緑(すべてのテストに合格)から赤(1つのテストに失敗)に変更することです。「緑」とは、テストスイートを赤(1つのテストが失敗)から緑(すべてのテストに合格)にずらりと移動させる場所です。「リファクタリング」とは、すべてのテストに合格したままコードを取得してきれいにすることです。
ロブキニヨン

1

あなたはずっとリアルコードを書いています。

各ステップで、コードの将来の呼び出し元に対してコードが満たす条件を満たすコードを記述しています(これは、あなたであるかどうかにかかわらず...)。

すぐにリファクタリングするかもしれないので、あなたは有用な(実際の)コードを書いていないと思います。

コードリファクタリング は、外部の動作を変更せずに、既存のコンピューターコードを再構築するプロセスです(ファクタリングを変更します)。

つまり、コードを変更しても、コードが満たす条件は変更されないままです。そして、あなたの変更が何かを変更したかどうかを確認するためにあなたのコードがすでに存在することを確認するために実装したチェック(テスト)。ですから、あなたがずっと書いたコードはそこにあります。

あなたがそれが本当のコードではないと思うかもしれないもう一つの理由は、あなたが最終プログラムがすでにあなたによって予見されることができる例をしているということです。プログラミングしているドメインに関する知識があることを示しているため、これは非常に良いことです。
しかし、プログラマーは多くの場合、彼らにとって未知の新しいドメインにいます。彼らは最終結果が何であるかを知らず、TDDはプログラムを段階に書く技術であり、このシステムがどのように機能するかについての知識を文書化し、コードがそのように機能することを検証します。

TDDでThe Book(*)を読んだとき、私にとって目立った最も重要な機能は、TODOリストです。TDDは、開発者が一度に1つのことに集中できるようにする手法でもあることを示しました。だから、これはまたabooutあなたの質問への答えである多くの実際のコードを書く方法?一度に1つのことに集中するのに十分なコードだと思います。

(*)ケントベックによる「テスト駆動開発:例による」


2
「テスト駆動開発:例による」ケントベック
ロバートアンドジェジュク

1

テストを失敗させるコードを書いているわけではありません。

テストを記述して、成功の外観を定義します。成功するコードは、まだ成功していないため、最初はすべて失敗するはずです。

最初に失敗したテストを記述することの全体的なポイントは、2つのことを行うことです。

  1. すべてのケースをカバー-すべての名目上のケース、すべてのエッジケースなど
  2. テストを検証します。それらがパスするだけを見た場合、エラーが発生したときに確実にエラーを報告することをどのように確認できますか?

red-green-refactorの背後にあるポイントは、正しいテストを最初に書くことで、テストに合格するために書いたコードが正しいことを確信できることです。何かが壊れているので、すぐに戻って修正できます。

私自身の経験(C#/。NET)では、まだ存在しないメソッドの呼び出しをコンパイルできないため、純粋なテスト優先は達成不可能な理想のビットです。したがって、「最初のテスト」とは、実際に最初にインターフェースをコーディングし、実装をスタブ化してから、スタブが適切に肉付けされるまでスタブ(最初は失敗します)に対するテストを記述することです。スタブから構築するだけで、「失敗したコード」を書くことはありません。


0

単体テストと統合テストを混同していると思います。受け入れテストもあると思いますが、それはプロセスによって異なります。

すべての小さな「ユニット」をテストしたら、それらすべてを組み立て、または「統合」してテストします。これは通常、プログラム全体またはライブラリです。

私が書いたコードでは、データを読み取ってライブラリにフィードするさまざまなテストプログラムでライブラリを統合テストし、結果を確認します。次に、スレッドでそれを行います。次に、途中でスレッドとfork()を使用します。次に、2秒後に実行して-9を強制終了し、起動して回復モードを確認します。ファジングします。私はあらゆる方法でそれを拷問します。

それはすべてテストでもありますが、結果をきれいに赤/緑で表示することはできません。成功するか、エラーコードを数千行掘り下げて理由を調べます。

そこで、「実際のコード」をテストします。

そして、私はこれについて考えただけですが、おそらくユニットテストの作成をいつ行うべきかわからないでしょう。テストが行​​うべきであると指定したすべてをテストが実行すると、ユニットテストの記述が完了します。すべてのエラー処理とエッジケースの間でそれを追跡できなくなる場合があるため、仕様をそのまま実行するハッピーパステストの素晴らしいテストグループを作成することができます。


(その=所有、それは=「それは」または「それは」。例えば、その使用方法とそれを参照してください。)
ピーターモーテンセン

-6

「TDDで「実際の」コードを書くのはいつですか?」という質問のタイトルへの回答では、答えは「ほとんどない」または「非常に遅い」です。

あなたは学生のように聞こえるので、学生に助言するかのように答えます。

多くのコーディング「理論」と「技術」を学習します。高価な学生コースで時間を過ごすのに最適ですが、半分の時間で本を読むことができなかったというあなたにはほとんど利益がありません。

コーダーの仕事は、コードを生成することだけです。本当にうまく機能するコード。そのため、コーダーは頭の中、紙の上、適切なアプリケーションなどでコードを計画し、コーディングの前に論理的および横方向に考えて、考えられる欠陥/穴を事前に回避することを計画します。

しかし、適切なコードを設計するには、アプリケーションを破壊する方法を知る必要があります。たとえば、Little Bobby Table(xkcd 327)について知らなかった場合、おそらくデータベースを操作する前に入力をサニタイズしないため、その概念に関するデータを保護することはできません。

TDDは、コードを導入する前にコーディングが指数関数的に難しくなり、かつて考えていたバグを忘れてしまう可能性があるため、アプリケーションをコーディングする前に何がうまくいかないかをテストすることで、コードのバグを最小限に抑えるように設計されたワークフローです。アプリケーションが完成したと思うと、テストとブームが実行され、テストでバグがキャッチされることが期待されます。

TDDは、一部の人が信じているように、テストを書いたり、最小限のコードで合格したり、別のテストを書いたり、最小限のコードで合格したりするなどではありません。代わりに、自信を持ってコーディングを支援する方法です。テストで動作するようにコードを連続的にリファクタリングするというこの理想はばかげていますが、新しい機能を追加し、まだコーディング方法を学んでいるときに気分が良くなるので、学生の間では素晴らしいコンセプトです...

このtrapに落ちないで、それが何であるかをコーディングするあなたの役割を見てください-コーダーの仕事はコードを生成することだけです。本当にうまく機能するコード。さて、あなたはプロのコーダーとして時間内にいることを忘れないでください、そしてあなたはあなたがあなたが100,000のアサーション、または0を書いたかどうか気にしません。彼らはただ機能するコードを望みます。ほんとうに、実は。


3
私は学生の近くにいるわけでもありませんが、良いテクニックを読み、プロになりたいと思います。その意味で、私は「学生」です。それが私だからです。私は自分がやっていることをやっている理由を正確に知りたい。問題の核心。それが得られない場合、私はそれを好まないし、質問を始めます。使用する場合は、理由を知る必要があります。TDDは、作成に必要なものを把握し、物事を検討するなど、いくつかの点で直感的には良いように見えますが、実装を理解することは困難でした。私は今よりよく把握していると思います。
ジョニー


4
これらがTDDのルールです。自由にコードを記述できますが、これらの3つのルールに従わない場合は、TDDを実行しません。
ショーンバートン

2
一人の「ルール」?TDDは、宗教ではなく、コーディングを支援するための提案です。非常に多くの人々がアイデアをこれほどまでに固守しているのを見るのは悲しいです。TDDの起源でさえ議論の余地があります。
user3791372

2
@ user3791372 TDDは非常に厳密で明確に定義されたプロセスです。多くの人がそれが単に「プログラミング中にテストを行う」ことを意味していると考えていても、そうではありません。ここで用語を混同しないようにしましょう。この質問は一般的なテストではなく、プロセスTDDに関するものです。
アレックス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.