TDD Red-Green-Refactorおよびプライベートになるメソッドをテストするためのif / how


91

私が理解している限り、ほとんどの人は、プライベートメソッドを直接テストするのではなく、パブリックメソッドを呼び出してテストする必要があることに同意しているようです。私は彼らの要点を見ることができますが、「TDDの3つの法則」に従い、「赤-緑-リファクタリング」サイクルを使用しようとすると、いくつかの問題があります。例で説明するのが一番だと思います。

現在、ファイル(タブ区切りデータを含む)を読み取り、非数値データを含むすべての列をフィルターで除外できるプログラムが必要です。おそらくこれを行うためのシンプルなツールが既にいくつか用意されていると思いますが、TDDの練習をするのにすてきできれいなプロジェクトになりそうだと思ったため、最初から実装することにしました。

したがって、最初に、「赤い帽子をかぶる」、つまり、失敗するテストが必要です。私は、行内のすべての非数値フィールドを見つけるメソッドが必要だと考えました。だから、私は簡単なテストを書いて、もちろんすぐにコンパイルに失敗するので、関数自体の記述を開始し、2、3サイクル(赤/緑)前後に作業関数と完全なテストができました。

次に、ファイルを1行ずつ読み取り、最終的に削除する必要があるすべての列を収集するために各行で「findNonNumericFields」関数を呼び出す関数「gatherNonNumericColumns」を続行します。いくつかの赤と緑のサイクルがあり、作業機能と完全なテストが完了しました。

今、私はリファクタリングする必要があると考えています。私のメソッド「findNonNumericFields」は、「gatherNonNumericColumns」を実装するときに必要だと考えたために設計されたため、「findNonNumericFields」をプライベートにするのが合理的だと思われます。ただし、テストしていたメソッドにアクセスできなくなるため、最初のテストが中断されます。

だから、私はプライベートメソッドと、それをテストするテストスイートになります。多くの人がプライベートメソッドをテストすべきでないとアドバイスしているので、私はここで一角に自分を描いたように感じます。しかし、どこで正確に失敗しましたか?

より高いレベルで始めて、最終的には私のパブリックメソッド(つまり、findAndFilterOutAllNonNumericalColumns)となるものをテストするテストを作成することもできましたが、それはTDDの全ポイントに少なくとも反すると感じます(少なくともボブおじさんによれば) :テストと本番コードの作成を絶えず切り替える必要があります。また、任意の時点で、すべてのテストが最後の1分以内に機能しました。パブリックメソッドのテストを書くことから始めた場合、プライベートメソッドのすべての詳細が機能するようになるまでに数分(または数時間、あるいは非常に複雑な場合は数日)があり、テストがパブリックをテストするためメソッドが渡されます。

じゃあ何をすればいいの?TDD(急速な赤緑リファクタリングサイクル)は、単にプライベートメソッドと互換性がありませんか?または、私の設計に欠陥がありますか?



2
これらの2つの機能は、ユニットが異なるほど十分に異なります(この場合、プライベートメソッドはおそらく独自のクラスにある必要があります)。ユニット内部の動作。最後から2番目の段落については、矛盾は見られません。1つのテストケースに合格するために、複雑なプライベートメソッド全体を記述する必要があるのはなぜですか?パブリックメソッドを使用して徐々にそれを追い出すか、インラインで開始してから抽出してみませんか?
ベンアーロンソン

26
プログラミングの方法に関する実際のガイドラインが私を超えているのに、なぜ人々はプログラミングの本やブログからイディオムや決まり文句を取り入れているのでしょうか。
AK_

7
私はまさにこの理由でTDDが好きではありません。もしあなたが新しい地域にいるなら、あなたはアーキテクチャがどうあるべきか、そして特定のものがどのように機能するかを見つけようとしている間に多くの余分な仕事をするでしょう。一方、あなたが既に経験している地域にいる場合、インテリセンスはコンパイルできないコードを書く理由を理解していないため、最初にテストを書くことはあなたを悩ますことから利益を得るでしょう。私は、デザインについて考え、それを書き、それからユニットテストをするのがずっと好きです。
Jeroen Vannevel

1
「ほとんどの人は、プライベートメソッドを直接テストすべきでないことに同意しているようです」-いいえ、そうすることが理にかなっている場合は、メソッドを直接テストします。privateそうするのが理にかなっているかのように隠す。
osa

回答:


44

単位

問題がどこから始まったのかを正確に特定できると思います。

私は、行内のすべての非数値フィールドを見つけるメソッドが必要だと考えました。

これはすぐに「それは別のテスト可能なユニットgatherNonNumericColumnsか、同じものの一部ですか?」と自問する必要があります。

答えが「はい、個別」の場合、アクションのコースは単純です。そのメソッドは適切なクラスでパブリックである必要があるため、ユニットとしてテストできます。あなたのメンタリティは、「ある方法を試してみる必要があり、別の方法を試してみる必要があるというようなものです。

あなたが言ったことから、あなたは答えが「いいえ、同じの一部」であると考えました。この時点で、計画は完全に記述し、テストしてfindNonNumericFields から記述する必要はなくなりますgatherNonNumericColumns。代わりに、単にを記述する必要がありますgatherNonNumericColumns。今のところ、findNonNumericFieldsちょうどあなたがあなたの次の赤のテストケースを選択し、あなたのリファクタリングをやっているとき、あなたは心を持っている先の可能性が一部である必要があります。今回は、「1つの方法を試してみる必要がありますが、完成した実装にはおそらく他の方法が含まれることに留意する必要があります」という考え方です


短いサイクルを保つ

上記を実行しても、最後から2番目の段落で説明する問題が発生することはありませ

パブリックメソッドのテストを書くことから始めた場合、プライベートメソッドのすべての詳細が機能するようになるまでに数分(または数時間、あるいは非常に複雑な場合は数日)があり、テストがパブリックをテストするためメソッドが渡されます。

この手法ではfindNonNumericFields、最初から全体を実装した場合にのみ緑色に変わる赤色のテストを記述する必要はありません。多くのfindNonNumericFields場合、テストするパブリックメソッドのインラインコードとして開始されます。これは、数サイクルにわたって構築され、リファクタリング中に最終的に抽出されます。


ロードマップ

この特定の例のおおよそのロードマップを示すために、使用した正確なテストケースはわかりませんが、gatherNonNumericColumnsパブリックメソッドとして記述していると言います。その場合、ほとんどの場合、テストケースは、findNonNumericFields1行のみのテーブルを使用して作成したテストケースと同じになります。その1行のシナリオが完全に実装され、メソッドを抽出するように強制するテストを作成したい場合は、反復を追加する必要がある2行のケースを作成します。


2
これが正解だと思います。OOP環境でTDDを採用することで、自分のボトムアップの本能を克服するのに苦労することがよくあります。はい、機能は小さいはずですが、それはリファクタリング後です。前に、彼らは巨大なモノリスになることができます。+1
ジョアンメンデス

2
@JoãoMendesさて、特に非常に短いRGRサイクルでは、リファクタリングする前に巨大なモノリスの状態に到達すべきかどうかはわかりません。しかし、そうです、テスト可能なユニット内で、ボトムアップで作業すると、OPが説明する問題につながる可能性があります。
ベンアーロンソン

1
OK、どこでうまくいかなかったのか理解できたと思います。皆さんに感謝します(これを回答としてマークしましたが、他の回答のほとんども同様に役立ちます)
ヘンリックバーグ

66

多くの人々は、単体テストはメソッドベースだと考えています。そうではありません。意味のある最小単位に基づいている必要があります。ほとんどの場合、これは、クラスがエンティティ全体としてテストする必要があることを意味します。個別のメソッドではありません。

これで、明らかにクラスのメソッドを呼び出すことになりますが、テストをブラックボックスオブジェクトに適用するものと考える必要があります。そのため、クラスが提供する論理演算を確認できるはずです。これらはテストする必要があるものです。クラスが大きすぎて論理演算が複雑すぎる場合は、最初に修正する必要がある設計上の問題があります。

1000個のメソッドを持つクラスはテスト可能に見える場合がありますが、各メソッドを個別にテストするだけでは、クラスを実際にテストすることはできません。一部のクラスは、メソッドが呼び出される前に特定の状態にある必要がある場合があります。たとえば、データを送信する前に接続を設定する必要があるネットワーククラスなどです。データ送信メソッドは、クラス全体から独立して考えることはできません。

したがって、プライベートメソッドはテストとは無関係であることがわかります。クラスのパブリックインターフェイスを呼び出してプライベートメソッドを実行できない場合、それらのプライベートメソッドは役に立たず、とにかく使用されません。

多くの人がプライベートメソッドをテスト可能なユニットにしようとするのは、テストを簡単に実行できるように見えるからです。しかし、これはテストの粒度を取りすぎます。マーティン・ファウラーは言う

私はユニットがクラスであるという概念から始めますが、多くの場合、密接に関連するクラスの束を取り、それらを単一のユニットとして扱います

オブジェクト指向システムでは、オブジェクトがユニットになるように設計されているため、非常に理にかなっています。個々のメソッドをテストする場合は、Cなどの手続き型システム、または代わりに静的関数のみで構成されるクラスを作成する必要があります。


14
私には、この答えはOPの質問のTDDアプローチを完全に無視しているように見えます。それはちょうど「プライベートメソッドをテストしていない」マントラの繰り返しであるが、それはTDD方法を説明していません- である実際の方法に基づくが、 -非法に基づくユニットテストのアプローチで動作するかもしれません。
Doc Brown

6
@DocBrownいや、それは彼に完全に答えて、あなたのユニットを「過度に肥大化させないでください」と言い、あなた自身の人生を難しくします。TDDはメソッドベースではなく、ユニットが意味をなすものであればどこでもユニットベースです。Cライブラリがある場合、はい、各ユニットは関数になります。クラスがある場合、ユニットはオブジェクトです。ファウラーが言うように、ユニットはいくつかの密接に関連するクラスである場合があります。いくつかのダムツールがメソッドに基づいてスタブを生成するという理由だけで、多くの人がユニットテストをメソッドごとに考えていると思います。
gbjbaanb

3
@gbjbaanb:既に記述しようとしているクラスのパブリックインターフェイスを持たずに、純粋なTDDを最初に使用して、OPが「非数値フィールドを1行に収集する」ことを実装できるテストを提案してください。
Doc Brown

8
ここで@DocBrownに同意する必要があります。質問者の問題は、プライベートメソッドをテストせずに達成できるよりも詳細なテスト粒度を望んでいるということではありません。彼は厳密なTDDアプローチを試みようとしましたが、そのように計画することなく、彼は壁にぶつかり、そこで私は突然、プライベートメソッドであるべきものに対するテストの束を見つけました。この答えはそれを助けません。これは、いくつかの質問に対する良い答えです。これだけではありません。
ベンアーロンソン

7
@Matthew:彼の間違いは、最初に関数を書いたことです。理想的には、スパゲッティコードとしてパブリックメソッドを記述し、リファクタリングサイクルでプライベートメソッドにリファクタリングして、リファクタリングサイクルでプライベートとしてマークしないでください。
スリーブマン

51

あなたのデータ収集方法は、テストに値するに十分に複雑であるという事実、むしろ解決策にはいくつかのループポイントの部分よりも自分自身の方法であるためにあなたの第一の目標から十分に独立した:これらのメソッドは行いませんプライベートが、いくつかのメンバー、他のクラス収集/フィルタリング/集計機能を提供します。

次に、ある場所でヘルパークラスの愚かなデータ変更の側面(「数字と文字を区別する」など)のテストを作成し、別の場所で主な目標(「売上高を取得する」など)のテストを作成します。通常のビジネスロジックのテストで基本的なフィルタリングテストを繰り返す必要はありません。

かなり一般的に、あることを行うクラスに、その主な目的とは別に必要な別のことを行うための広範なコードが含まれている場合、そのコードは別のクラスに存在し、パブリックメソッドを介して呼び出される必要があります。誤ってそのコードを含むだけのクラスのプライベートコーナーに非表示にしないでください。これにより、テスト性と理解性が同時に向上します。


はい、あなたに賛成です。しかし、あなたの最初の声明には問題があります。それは、「十分に複雑な」部分と「十分に分離した」部分の両方です。「十分に複雑」に関して:私は高速の赤緑サイクルを行おうとしています。つまり、テストに切り替える前(またはその逆)にコーディングできるのは1分程度しかできないということです。それは私のテストが実際に非常にきめ細かくなることを意味します。私はそれがTDDの利点の1つであると考えましたが、多分それをやりすぎて、それが不利になるでしょう。
ヘンリックベルク

「十分に分離」について:私は(再びunclebobから)機能を小さくすべきであり、それよりも小さくすべきだということを学びました。したがって、基本的には3〜4行の関数を作成しようとします。そのため、どれほど小さくシンプルであっても、多かれ少なかれすべての機能が独自のメソッドに分離されます。
ヘンリックベルク

とにかく、データ変更の側面(たとえば、findNonNumericFields)は本当にプライベートである必要があると思います。そして、別のクラスに分離する場合は、とにかく公開する必要があるため、その点についてはあまりわかりません。
ヘンリックベルク

6
@HenrikBergは、そもそもオブジェクトがある理由を考えます-それらは関数をグループ化する便利な方法ではありませんが、複雑なシステムを扱いやすくする自己完結型のユニットです。したがって、クラスをテストすることを検討する必要があります。
gbjbaanb

@gbjbaanb私は彼らが両方とも同じであると主張します。
ラバーダック

29

個人的には、テストを書いたときに実装の考え方に深く関わったと感じています。あなたは想定し、あなたが特定のメソッドが必要になります。しかし、クラスが行うことになっていることを実行するために本当に必要ですか?誰かがやって来て、それらを内部的にリファクタリングすると、クラスは失敗しますか?クラスを使用している場合(そして、それが私の意見ではテスターの考え方であるはずです)、数値をチェックする明示的なメソッドがある場合、実際にはそれほど気にする必要はありません。

クラスのパブリックインターフェイスをテストする必要があります。プライベート実装は、理由によりプライベートです。不要で変更できるため、パブリックインターフェイスの一部ではありません。これは実装の詳細です。

パブリックインターフェイスに対してテストを作成すると、実際に遭遇した問題を取得することはできません。プライベートメソッドをカバーするパブリックインターフェイス用のテストケースを作成できます(素晴らしい)か、できません。その場合は、プライベートメソッドについて一生懸命に考えて、とにかく到達できない場合は、それらをまとめて破棄する時間になるかもしれません。


1
「実装の詳細」とは、「XORまたは一時変数を使用して変数間でintを交換した」などです。保護/プライベートメソッドには、他の何かと同様にコントラクトがあります。特定の制約の下で、入力を受け取り、それを処理し、出力を生成します。最終的には、契約のあるものはすべてテストする必要があります-必ずしもライブラリを使用する人ではなく、ライブラリを保守し、後で修正する人のために。それが「公共」ではないという理由だけで、それはの一部ではないという意味ではありませんAPI。
Knetic

11

クラスが内部で行うことを期待することに基づいてTDDを実行しません。

テストケースは、クラス/機能/プログラムが外界に対して何をしなければならないかに基づいている必要があります。あなたの例では、ユーザーはあなたのリーダークラスを呼び出しますfind all the non-numerical fields in a line?

答えが「いいえ」の場合、そもそも書くのは悪いテストです。「これを機能させるためにクラスメソッドを実装する必要がある」レベルではなく、クラス/インターフェイスレベルで機能のテストを記述します。これはテストです。

TDDの流れは次のとおりです。

  • 赤(クラス/オブジェクト/関数/などが外界に対して行っていること)
  • 緑(この外部世界関数が機能するように最小限のコードを記述します)
  • リファクタリング(この機能を実行するためのより良いコードは何ですか)

「将来、プライベートメソッドとしてXが必要になるので、最初にXを実装してテストしてみましょう。」これを実行していることに気付いた場合、「レッド」ステージを誤って実行しています。これはあなたの問題のようです。

プライベートメソッドになるメソッドのテストを頻繁に書いていることに気付いた場合、次のいずれかの操作を行っています。

  • インターフェース/パブリックレベルのユースケースを十分に理解していないため、それらのテストを記述できません。
  • デザインを劇的に変更し、いくつかのテストをリファクタリングします(その機能が新しいテストでテストされているかどうかによっては、良いことかもしれません)

9

一般的なテストでよくある誤解に直面しています。

テストに慣れていない人のほとんどは、次のように考え始めます。

  • 関数Fのテストを書く
  • Fを実装する
  • 関数Gのテストを書く
  • Fへの呼び出しを使用してGを実装する
  • 関数Hのテストを書く
  • Gへの呼び出しを使用してHを実装する

等々。

ここでの問題は、実際には関数Hの単体テストがないことです。Hをテストすることになっているテストは、実際にはH、G、Fを同時にテストしています。

これを解決するには、テスト可能なユニットは互いに依存せず、インターフェイスに依存する必要があることを理解する必要があります。あなたの場合、ユニットが単純な関数である場合、インターフェースは単に呼び出しシグネチャです。したがって、Fと同じシグネチャを持つ任意の関数で使用できるように、Gを実装する必要があります。

これを正確に行う方法は、プログラミング言語によって異なります。多くの言語では、関数(またはそれらへのポインター)を他の関数の引数として渡すことができます。これにより、各機能を個別にテストできます。


3
これ以上何度も賛成票を投じることができたらいいのにと思います。あなたがあなたのソリューションを正しく設計していないので、私はそれを要約します。
ジャスティンオームズ

Cのような言語ではこれは理にかなっていますが、ユニットが一般にクラス(パブリックメソッドとプライベートメソッド)であるOO言語の場合、すべてのプライベートメソッドを個別にテストするのではなく、クラスをテストする必要があります。はい、クラスを分離します。各クラスのメソッドを分離します、いいえ。
gbjbaanb

8

テスト駆動開発中に作成するテストは、クラスがパブリックAPIを正しく実装していることを確認すると同時に、パブリックAPIのテストと使用が簡単であることを確認することになっています。

必ずプライベートメソッドを使用してそのAPIを実装できますが、TDDを介してテストを作成する必要はありません。パブリックAPIが正常に機能するため、機能がテストされます。

ここで、プライベートメソッドがスタンドアロンテストに値するほど複雑であると仮定しますが、元のクラスのパブリックAPIの一部としては意味がありません。まあ、これはおそらく、実際には他のクラスのパブリックメソッドでなければならないことを意味します。元のクラスが独自の実装で利用するものです。

パブリックAPIをテストするだけで、将来的に実装の詳細を簡単に変更できます。役に立たないテストは、後で発見したばかりの洗練されたリファクタリングをサポートするために書き直す必要がある場合にのみ、あなたを困らせます。


4

正しい答えは、パブリックメソッドから始めることについてあなたが思いついた結論だと思います。そのメソッドを呼び出すテストを書くことから始めます。それは失敗するので、その名前で何もしないメソッドを作成します。次に、戻り値をチェックするテストを正しく行うことができます。

(私はあなたの関数が何をするかについて完全に明確ではありません。それは非数値を取り除いたファイルの内容を含む文字列を返しますか?)

メソッドが文字列を返す場合、その戻り値を確認します。したがって、あなたはそれを構築し続けます。

プライベートメソッドで発生するものはすべて、プロセス中のある時点でパブリックメソッドに存在し、リファクタリング手順の一部としてプライベートメソッドにのみ移動する必要があると思います。私が知っている限りでは、リファクタリングに失敗したテストは必要ありません。機能を追加するときに失敗するテストのみが必要です。リファクタリング後にテストを実行するだけで、すべてが合格することを確認できます。


3

ここの隅に自分を描いたような気がします。しかし、どこで正確に失敗しましたか?

古い格言があります。

計画に失敗すると、失敗する計画があります。

TDDをするとき、あなたはただ座ってテストを書くだけで、デザインは魔法のように起こると考えているようです。これは真実ではありません。高度な計画を立てる必要があります。最初にインターフェイス(パブリックAPI)を設計するとき、TDDから最良の結果が得られることがわかりました。個人的にinterfaceは、最初にクラスを定義する実際を作成します。

gaspテストを書く前に「コード」を書きました!うーん、ダメ。しなかった。私は従うべき契約デザインを書きました。グラフ用紙にUML図を書き留めることで、同様の結果が得られると思います。重要なのは、計画が必要だということです。TDDは、コードを少しでもハッキングするライセンスではありません。

「最初のテスト」は誤った呼び名であると本当に感じています。最初に設計して からテストします。

もちろん、コードからより多くのクラスを抽出することについて他の人が与えたアドバイスに従ってください。クラスの内部をテストする必要性を強く感じている場合は、それらの内部を簡単にテストできるユニットに抽出して挿入します。


2

テストもリファクタリングできることを忘れないでください!メソッドをプライベートにすると、パブリックAPIが減るので、その「失われた機能」に対応するいくつかのテストを捨てることは完全に受け入れられます(別名、複雑さが減ります)。

他の人は、プライベートメソッドが他のAPIテストの一部として呼び出されるか、到達できないため削除可能であると言っています。実際、実行パスについて考えると、よりきめ細かくなります

たとえば、除算を実行するパブリックメソッドがある場合、ゼロ除算の結果となるパスをテストすることができます。我々はこの方法をプライベートにする場合、我々は選択肢を得る:我々はゼロ除算のパスを考えることができ、いずれかまたは我々は、それが他の方法で呼ばれていますどのように考慮することによって、そのパスを排除することができます。

このようにして、いくつかのテスト(たとえば、ゼロ除算)を破棄し、残りのパブリックAPIに関して他のテストをリファクタリングすることができます。もちろん、理想的な世界では、既存のテストは残りのすべてのパスを処理しますが、現実は常に妥協です;)


1
他の答えは、プライベートメソッドが赤いサイクルで書かれてはいけないという点で正しいですが、人間は間違いを犯します。そして、あなたが間違いの道を十分に進んだとき、これは適切な解決策です。
スリーブマン

2

プライベートメソッドを別のクラスのパブリックメソッドにすることができる場合があります。

たとえば、スレッドセーフではないプライベートメソッドがあり、クラスを一時的な状態のままにする場合があります。これらのメソッドは、最初のクラスによってプライベートに保持されている別のクラスに移動できます。したがって、クラスがキューの場合、パブリックメソッドを持つInternalQueueクラスを作成し、QueueクラスはInternalQueueインスタンスをプライベートに保持できます。これにより、内部キューをテストできます。また、InternalQueueの個々の操作が何であるかを明確にします。

(これは、Listクラスが存在しないと想像した場合、およびList関数を使用するクラスのプライベートメソッドとしてList関数を実装しようとした場合に最も明白です。)


2
「プライベートメソッドを別のクラスのパブリックメソッドにすることができる場合があります。」私はそれを十分に強調することはできません。プライベートメソッドは、独自のアイデンティティを求めて叫んでいる別のクラスである場合があります。

0

なぜあなたの言語は完全に公開と完全に非公開の2つのレベルのプライバシーしか持っていないのだろうか。

非公開メソッドをパッケージからアクセスできるように整理できますか?次に、テストを同じパッケージに入れて、パブリックインターフェイスの一部ではない内部動作のテストをお楽しみください。ビルドシステムは、リリースバイナリをビルドするときにテストを除外します。

もちろん、定義クラス以外にはアクセスできない、本当にプライベートなメソッドが必要な場合があります。そのような方法がすべて非常に小さいことを願っています。一般に、メソッドを小さくする(20行未満など)ことは非常に役立ちます。テスト、保守、コードの理解が容易になります。


3
テストを実行するためだけにメソッドアクセス修飾子を変更することは、尾が犬をくねらせる状況です。ユニットの内部をテストすることは、後でリファクタリングするのを難しくしているだけだと思います。それどころか、パブリックインターフェイスのテストは、ユニットの「契約」として機能するので素晴らしいです。
scriptin

メソッドのアクセスレベルを変更する必要はありません。私が言おうとしていることは、テストを含む特定のコードを簡単に、公開契約を結ぶことなく書くことができる中間アクセスレベルがあるということです。もちろん、パブリックインターフェイスをテストする必要がありますが、さらに、一部の内部動作を単独でテストすることが有益な場合もあります。
9000

0

私はときどき、プライベートメソッドをprotectedにバンプして、より詳細なテストを可能にしました(公開されたパブリックAPIよりも厳密です)。これは、ルールではなく(願わくは非常にまれ)例外である必要がありますが、特定の特定の場合に遭遇する可能性があります。また、パブリックAPIを構築する際に、それはまったく考慮したくないものです。これらのまれな状況で内部使用ソフトウェアで使用できる「チート」の多くです。


0

私はこれを経験し、あなたの痛みを感じました。

私の解決策は:

モノリスの構築などのテストの処理を停止します。

いくつかの機能を実行するために一連のテスト(5など)を作成した場合、特に他の一部になった場合これらのテストをすべて保持する必要はありません。

たとえば、私はしばしば持っています:

  • 低レベルのテスト1
  • それを満たすためのコード
  • 低レベルのテスト2
  • それを満たすためのコード
  • 低レベルのテスト3
  • それを満たすためのコード
  • 低レベルテスト4
  • それを満たすためのコード
  • 低レベルのテスト5
  • それを満たすためのコード

それで私は持っています

  • 低レベルのテスト1
  • 低レベルのテスト2
  • 低レベルのテスト3
  • 低レベルテスト4
  • 低レベルのテスト5

しかし、今ではそれを呼び出す、多くのテストがあるより高いレベルの関数を追加すると、これらの低レベルのテストを次のように減らすことができるかもしれません:

  • 低レベルのテスト1
  • 低レベルのテスト5

悪魔は詳細にあり、それを行う能力は状況に依存します。


-2

太陽は地球の周りを回っていますか、それとも太陽の周りを回っていますか?アインシュタインによると、答えはイエス、または両方のモデルが視点だけが異なるため、両方とも同じようにカプセル化とテスト駆動開発が競合しているだけだと考えています。私たちはガリレオと教皇のようにここに座って、お互いにin辱を投げかけます。ばか、プライベートメソッドもテストが必要だとは思いませんか。異端者、カプセル化を壊さないでください!同様に、パブリックインターフェイスのテストがカプセル化を破壊しないように、プライベートインターフェイスのテストをカプセル化するようなものを試すことができると、真実が思ったよりも大きいと認識した場合。

これを試してください:2つのメソッドを追加します。1つは入力なしでプライベートテストの数を返すメソッドと、テスト番号をパラメーターとして受け取り、合格/不合格を返すメソッドです。


1
選ばれたin辱は、ガリレオと教皇が使用したものであり、この質問に対する答えではありません。
-hildred
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.