2009-06-30 21 views
22

今日Proggitでは、投稿スレッド「Why Unit Testing Is A Waste of Time」でコメントスレッドを読んでいました。単体テストの際に「単位」はどのようにすべきですか?

私は実際にそれについて私が作ったcommentとしていますように多くの記事の前提に関係ないよ:

問題の茎は、そのビジネス・ソフトウェアのコードのほとんどの「単位」 のプロジェクトは簡単です。

ユニットのサイズを まで変更するのは簡単ですか?地獄の人 は、単なる 関数または方法としてコードの単位を定義しました!

まあ、私は で働いていた人たちの一部は、単一 関数として単位を定義したかったです。それは完全に愚かだった。 好きな "ユニット"の定義は: というコードの最も小さな部分が有効にテストできます。

いくつかのオブジェクトをモックして、些細なコードをテストして実際に価値のあるものを追加するのではなく、あまりにも多くの時間を費やしていますか?

ユニットテストの場合、「ユニット」はどのようにすべきですか?機能レベルのテストは細かすぎますか?

+0

この質問は、http://stackoverflow.com/questions/517977/what-do-you-test-with-your-unit-testsやhttp://stackoverflow.com/questionsとは異なりますが、おそらくそれに関連しています/ 962821/how-much-should-each-unit-test-test –

+0

@Thomas Owens、リンクありがとうございます。 – mmcdole

+0

問題ありません。私は誰もが必要とするすべての情報を持っている人のファンです。欠けている情報がなくなったら、それは嫌いです。 –

答えて

14

それはWikipediaを引用するのは簡単に見えるかもしれませんが、私はそれが、この場合には非常に簡潔かつ正確だと思う:

ユニットは、アプリケーションの最小テスト可能な部分です。

これは、ユニットが「有効にテストできるコードの最小の部分」であるというご質問の意見と一致しているようです。言い換えれば、可能であればユニットをできるだけ小さくして、それ自体が開発者/試験者にとっても意味をなさないようにしてください。

プロジェクトの一部を単独でテストし、それらがどのように組み合わされて相互作用するかをテストしたいことがよくあります。単体テストのさまざまな層(レベル)を持つことは、しばしば賢明なことです。コードが、個々の機能から自己完結型のタスク全体まで、すべてのレベルで機能するように働くことができます。私は個人的には、個人的な機能をテストすることが間違っている、あるいは役に立たないとは考えていません。

非常に正直なところ、「ユニットテスト」には「ユニット」という明確な定義はありません。これはまさに「ユニット」という曖昧な用語が使われている理由です!何をテストする必要があるか、どのレベルで経験するかは、経験の問題であり、かなりの頻度で単純な試行錯誤です。それは少し不満な答えのように聞こえるかもしれませんが、私はそれが正しい規則であると信じています。

+0

@ Noldorin:< - 最高の知恵: - 私がウィキペディアから取ったものは、少なくとも塩の単位であるものはほとんどありません。だから、もし「穀物」が働いたら、ピンチはどうですか...今大さじです。 - しかし、レシピの塩と同じように、ユニットが大きすぎると、テスト自体が威圧的になります。 – IAbstract

3

私はユニットが擬似コード内の他のステップと分けることができる意味のある作業の中で最も小さい部分だと言います。例えば

、あなたには、いくつかのデータを処理するための一連のステップを実行しようとしている場合、

  1. はヒストグラム
  2. を生成
  3. 意味
  4. 、最小値、最大値、中央値のためのデータセットをスキャンするように
  5. は、データ、データを再マッピング関数を
  6. 出力を
  7. リマップを生成

これらのステップのそれぞれは「ユニット」であり、シリーズ全体が「ユニット」でもあります(それぞれの間の結束が機能していることをテストするため)。これらのステップのいずれかは、4つの関数(プログラマが4つのループを実行している場合の最初のステップ)、または1つの関数、または何でもよいが、最終的には、既知の入力は既知の出力を与えるべきである。

3

あなたがマーフィーの法則を考慮すると、それほど些細なことはありません。

OO環境を想定して、さまざまなメソッドが内部状態を変更することが多く、さまざまなメソッド間の状態が一貫していることを確認したいので、単位テストを単位として使用します。

残念ながら、一貫性をチェックする唯一の方法は、クラスのさまざまなメソッドを呼び出して失敗するかどうかを確認することです。

4

私は常に機能レベルでテストしましたが、うまくいきました。私の大きなポイントは、単体テストが2つのコード間の契約をテストすることです。単体テストは単なる呼び出し元として機能し、テストされるコード(たとえ大きかったとしても、テストするのに30分かかる単一関数または巨大でネストされたライブラリ)が結果を予測可能に返すことを保証します。

ユニットの全ポイントは、互換性を保証して(インタレーションを壊さないように)、予測可能な結果を​​保証するためにテストします。どこにいても情報の交換があれば、アプリケーションを安定させるのに役立ちます。

更新:私は、顧客やユーザーが自分のアプリケーションでインタラクションを壊すエッジケースを報告するたびに、常に単体テストを追加しました。それを修正するだけでは不十分です。単体テストを追加して修正が保持されるようにして、回帰を防ぎ、安定した状態に保つのに役立ちます。

+0

コンテナをデバッグしている場合は、個別にput、fetch、reduceをテストする感覚は何ですか?重大なテストでは、すべてのテストを単一のテスト機能に組み込む必要があります。 – akappa

+0

私はあなたが尋ねていることを理解していませんが、いつものように、それは依存しています - いくつかのテストデータを使って "このコンテナは期待通りに動く"機能が分割されていることを確認したい場合は、複数のテストに分割してください。ユニットテスト(少なくとも私にとって)はテストポイントとして機能することにも言及する価値があります。もし私がアプリを誤動作させたいのであれば、大きなものの中でオブジェクトを壊さずにテストを少し修正することができますアプリケーションでは、テストごとにオブジェクトの単一のオブジェクトまたは機能をテストできます。 – SqlRyan

+1

@appaka:あなたの 'put'の実装が壊れていると、あなたの' put'テストだけが失敗するということです。一方、あなたが知っていることは、「put」、「fetch」、または「reduce」のいずれかの操作で破損しているか、あるいはそれらを組み合わせて使用​​している可能性があるということです。その情報から、 "put"が壊れてしまいました。余分な作業がたくさんあり、単体テストがずっと役に立たなくなります。 – Domenic

1

通常、ユニットを小さくするほど、ユニットテストがより有効かつ効果的になります。ユニットテストの全ポイントは、新しく導入されたバグをコードの小さな部分にローカライズできるようにすることです。

1

私にとって、「単位」とは、道路の8-12ヶ月で、私は覚えていないクラスの重要な行動です。

よく書かれた単体テスト(BDDだと思います)では、私のテストで私に説明し、普通の英語でコードを検証するので、私はする必要はありません。

0

ユニットのサイズを に変更するまではそれほど変わっていませんか?地獄の人 は、単なる 関数または方法としてコードの単位を定義しました!

メソッドとして定義された "ユニット"をテストすることが難しい場合、ユニットテストを作成するにはメソッドが大きすぎるか複雑すぎる可能性があります。

rwmnauで提案されている同様の方法論に従い、メソッドレベルでテストします。メソッドごとに1つのテストを作成するだけでなく、各メソッドの異なるコードパスに対して追加のテストを作成します。時には、すべてのコードパスが複雑になることを強調します。私の挑戦は、パフォーマンスとコードの複雑さの面でより優れた解決策がない限り、この種のメソッドを記述しないようにすることです。

また、コンポーネント間の契約をテストするためにモックを使用します。

4

「単位」は、定義の場合は1単位単位である必要があります。つまり、ユニットテストの「ユニット」を定義することは、むしろ主観的なものです。あなたのアーキテクチャーが正確であること、そしてアプリケーションがどのように機能単位を分解することを選択するかによってかなり強く依存する可能性があります。私が言っていることは、あなたが定義するものを除いて、明確に定義された「ユニット」がないということです。 「ユニット」は、単一の副作用を有する単一の方法であってもよいし、単一の一貫した機能セットを一緒に定義する関連する方法のセットであってもよい。

ここで合理性は重要です。あなたが持っている各クラスの各アクセサの単体テストを書くことは全く可能です。しかし、それは明らかに過労です。同様に、アプリケーション全体を1つの単位として定義することも可能ですが、それをテストする単一のテストが必要です。

一般に、テスト用の「ユニット」は、明確に定義された1つの明確に異なる機能のチャンクを記述します。アプリケーションを表示する各レベルでは、機能の明確な「原子」を見ることができます(設計が良好な場合)。これらは、低レベルのビューの場合は「データベースからレコードを取得する」、高レベルのビューでは「ユーザーを作成、編集、および削除する」のように単純なものにすることができます。彼らは相互排他的でもありません。ユニットテストとして簡単に両方を持つことができます。

ここでは、テストするユニットが理にかなっているということです。単体テストで機能の検証と検証を行いたい。ユニットテストがテストするのは、あなたが機能として定義するものです。機能の単位とは何ですか?それはあなたの個々の状況を定義することです。

1

「ユニットテスト」は誤用されていると思われます。今日、この用語は、小さなコードのテストを指すのに使用されるのではなく、自動化されたテストに使用されています。

私は自分のコードを書く前にテストを書く傾向があるので、いくつかの新しい行、新しいメソッド、または新しいクラスの作成を引き起こす場合は、最初に書き込むときはわかりません。

したがって、単語:mu

関連する問題