203

アンチパターン: 実際のアンチパターンを単純な悪い習慣、悪い習慣、または悪い考えと正式に区別するには、少なくとも 2 つの重要な要素が存在する必要があります。

  • 最初は有益に見えるが、最終的には有益な結果よりも悪い結果をもたらす行動、プロセス、または構造の繰り返しパターン、および
  • 明確に文書化され、実際の実践で証明され、再現可能なリファクタリングされたソリューション。

「実際に」何度も目にした TDD アンチパターンに投票してください。
James Carr によるブログ投稿testdrivendevelopment yahoogroup に関する関連ディスカッション

「名前のない」ものを見つけたら..それらも投稿してください。アンチパターンごとに 1 つの投稿を行って、投票が何かにカウントされるようにしてください。

私の既得権益は、上位 n 個のサブセットを見つけて、近い将来のランチボックス ミーティングでそれらについて議論できるようにすることです。

4

31 に答える 31

70

Second Class Citizens - テスト コードは本番コードほどリファクタリングされておらず、多くの重複コードが含まれているため、テストの保守が困難です。

于 2008-12-02T14:37:26.600 に答える
67

フリーライド / Piggyback -- James Carr、Tim Ottinger
新しいテスト ケース メソッドを記述して、別の/異なる機能/機能をテストするのではなく、新しいアサーション (およびそれに対応するアクション、つまり AAA からの Act ステップ) を既存のテスト ケースに乗せます。 .

于 2008-12-02T13:15:03.990 に答える
64

ハッピーパス

テストは、境界と例外をテストせずに、ハッピー パス (つまり、期待される結果) にとどまります。

JUnit アンチパターン

于 2008-12-02T13:43:08.270 に答える
59

ローカルヒーロー

実行するために記述された開発環境に固有のものに依存するテスト ケース。その結果、開発ボックスではテストに合格しますが、誰かが別の場所で実行しようとすると失敗します。

隠された依存関係

ローカル ヒーローと密接に関連しており、テストを実行する前に既存のデータをどこかに入力する必要がある単体テストです。そのデータが入力されていない場合、テストは失敗し、開発者に何が必要なのか、またはその理由はほとんど示されません。開発者は、使用しているデータがどこから来るはずなのかを見つけるために、何エーカーものコードを掘り下げる必要があります。


悲しいことに、これらの dll を担当する 3 人の開発者との詳細な協議なしにマシンに現存することは言うまでもなく、任意の本番システムで常に同期が取れていない曖昧で多様な .ini ファイルに依存する古代の .dll で、これがあまりにも多く見られます。はぁ。

于 2008-12-02T11:40:20.670 に答える
58

チェーンギャング

特定の順序で実行する必要があるいくつかのテスト。つまり、1 つのテストがシステムのグローバルな状態 (グローバル変数、データベース内のデータ) を変更し、次のテストはそれに依存します。

これは、データベースのテストでよく見られます。でロールバックを実行する代わりにteardown()、テストは変更をデータベースにコミットします。もう 1 つの一般的な原因は、グローバル状態への変更が、テストが失敗した場合にクリーンアップする try/finally ブロックにラップされていないことです。

于 2008-12-02T12:30:01.553 に答える
56

モッカリー
時には、モッキングが便利で便利な場合もあります。しかし、開発者は自分自身を失い、テストされていないものを模倣しようとすることがあります。この場合、単体テストには非常に多くのモック、スタブ、および/またはフェイクが含まれているため、テスト対象のシステムはまったくテストされておらず、代わりにモックから返されたデータがテストされています。

出典: James Carr の投稿。

于 2008-12-02T11:25:13.150 に答える
40

サイレントキャッチャー- ケリー?
例外がスローされた場合に合格するテスト..実際に発生した例外が開発者が意図したものとは異なるものであっても。
関連項目:シークレット キャッチャー

[Test]
[ExpectedException(typeof(Exception))]
public void ItShouldThrowDivideByZeroException()
{
   // some code that throws another exception yet passes the test
}
于 2008-12-02T14:17:34.457 に答える
34

過剰なセットアップ-- James Carr
テストを開始するだけでも大がかりなセットアップが必要なテスト。場合によっては、1 つのテストの環境を準備するために数百行のコードが使用され、いくつかのオブジェクトが含まれます。これにより、すべてのセットアップの「ノイズ」が原因で、何がテストされるかを実際に確認することが難しくなる可能性があります。(出典: James Carr の投稿)

于 2008-12-02T11:57:44.597 に答える
34

インスペクター
100% のコード カバレッジを達成するためにカプセル化に違反するユニット テストですが、オブジェクト内で何が起こっているかを非常によく知っているため、リファクタリングを試みると既存のテストが壊れ、変更をユニットに反映する必要があります。テスト。


「メンバー変数を公開せずにテストするにはどうすればよいですか...単体テストのためだけですか?」

于 2008-12-02T11:26:25.457 に答える
32

アナルプローブ

Java のsetAccessible(true)を使用してプライベート フィールドを読み取るか、保護されたフィールド/メソッドにアクセスするためにクラスを拡張するか、アクセスするために特定のパッケージにテストを配置する必要があるなど、そのタスクを実行するために非常識な、違法な、またはその他の不健康な方法を使用する必要があるテストグローバル フィールド/メソッドをパッケージ化します。

このパターンが見られる場合は、テスト対象のクラスでデータ隠蔽が多すぎます。

これと The Inspector の違いは、テスト対象のクラスは、テストする必要があるものさえ隠そうとすることです。したがって、目標は 100% のテスト カバレッジを達成することではなく、何でもテストできるようにすることです。プライベート フィールドのみを持つクラス、run()引数を持たずゲッターをまったく持たないメソッドを考えてみてください。ルールを破らずにこれをテストする方法はありません。


Michael Borgwardt によるコメント:これは実際にはテストのアンチパターンではなく、テスト対象のコードの欠陥に対処するための実用主義です。もちろん、これらの欠陥を修正する方が良いのですが、サードパーティのライブラリの場合はそれができない場合があります。

Aaron Digulla: 同意します。おそらく、このエントリは、アンチパターンではなく、「JUnit HOWTO」ウィキに適しているかもしれません。コメント?

于 2008-12-02T12:35:11.400 に答える
26

名前のないテスト-- ニック・ペロー

バグ トラッカーで特定のバグを再現するために追加され、作成者が独自の名前を保証しないと考えているテスト。既存の不足しているテストを強化する代わりに、testForBUG123 という名前の新しいテストが作成されます。

2 年後、そのテストが失敗した場合、最初にバグ トラッカーで BUG-123 を見つけて、テストの意図を理解する必要があるかもしれません。

于 2008-12-03T10:35:20.300 に答える
25

スローポーク

実行速度が非常に遅い単体テスト。開発者がテストを開始すると、トイレに行ったり、タバコを吸ったり、最悪の場合、1 日の終わりに家に帰る前にテストを開始したりする時間があります。(出典: James Carr の投稿)

別名、必要な頻度で実行されないテスト

于 2008-12-02T11:30:23.483 に答える
20

バタフライ

現在の日付を含む構造など、常に変化するデータを含むものをテストする必要があり、結果を固定値に固定する方法はありません。醜い部分は、この値をまったく気にしないことです。値を追加することなく、テストをより複雑にするだけです。

その翼のコウモリは、世界の反対側にハリケーンを引き起こす可能性があります. -- エドワード・ローレンツ『バタフライ・エフェクト』

于 2008-12-02T12:46:21.533 に答える
19

ちらつきテスト(出典:Romilly Cocking)

特定の時間ではなく、たまに失敗するテストであり、通常はテスト内の競合状態が原因です。通常、JMSなどの非同期のものをテストするときに発生します。

おそらく、「 WaitandSee」アンチパターンと「TheSleeper 」アンチパターンのスーパーセットです。

ビルドが失敗しました。まあ、ビルドを再実行するだけです。-匿名の開発者

于 2008-12-04T09:37:39.137 に答える
19

成り行きを見守る

いくつかのセットアップ コードを実行し、テスト対象のコードが期待どおりに機能したかどうかを「確認」する前に、特定の時間「待機」する必要があるテスト。Thread.sleep() または同等のメソッドを使用する testMethod は、"Wait and See" テストであることは間違いありません。

通常、これは、電子メール、http 要求、ディスクへのファイルの書き込みなど、システム外部のイベントを生成するコードをテストする場合に表示されることがあります。

このようなテストは、低速のボックスまたは過負荷の CI サーバーで実行すると失敗するため、ローカル ヒーローである可能性もあります。

Wait and See アンチパターンをThe Sleeperと混同しないでください。

于 2008-12-04T01:12:47.923 に答える
17

不適切に共有されたフィクスチャ-- Tim Ottinger
テスト フィクスチャのいくつかのテスト ケースは、セットアップ/ティアダウンを使用しないか、または必要としません。新しいテスト フィクスチャを作成する開発者の慣性が原因の 1 つです... 1 つのテスト ケースを山に追加するだけで簡単です

于 2008-12-02T13:12:14.960 に答える
16

巨人

テスト対象のオブジェクトを有効にテストしているが、数千行にまたがり、多数のテスト ケースを含むことができる単体テスト。これは、テスト中のシステムが神のオブジェクトであることを示している可能性があります(James Carr の投稿)。

これの確かな兆候は、数行以上のコードにまたがるテストです。多くの場合、テストは非常に複雑であるため、独自のバグや不安定な動作が含まれ始めます。

于 2008-12-02T11:27:25.703 に答える
15
于 2008-12-04T07:39:32.947 に答える
14

スリーパー、別名ベスビオ山-ニックペロー

将来の特定の日時に失敗する運命にあるテスト。これは多くの場合、DateオブジェクトまたはCalendarオブジェクトを使用するコードをテストする際の境界チェックが正しくないことが原因です。深夜など、特定の時間帯に実行すると、テストが失敗する場合があります。

「TheSleeper」を「 WaitAndSee」アンチパターンと混同しないでください。

そのコードは2000年よりずっと前に置き換えられます-1960年の多くの開発者

于 2008-12-04T01:01:30.240 に答える
11

今日はこれでちょっとした:

Wet Floor :
テストはどこかに永続化されるデータを作成しますが、テストが終了してもクリーンアップしません。これにより、テスト (同じテスト、または場合によっては他のテスト) が後続のテスト実行で失敗します。

私たちの場合、テストでは、最初にテストを実行したユーザーからのアクセス許可で、「一時」ディレクトリにファイルが横たわっていました。別のユーザーが同じマシンでテストしようとしたとき: ブーム。James Carr のサイトのコメントで、Joakim Ohlrogge はこれを「Sloppy Worker」と呼んでおり、「Generous Leftovers」のインスピレーションの一部でした。私は自分の名前の方が好きです(侮辱的ではなく、親しみやすい)。

于 2010-01-27T23:01:51.093 に答える
11

枯れ木

スタブが作成されたが、実際にはテストが書かれていないテスト。

私は実際に私たちの製品コードでこれを見てきました:

class TD_SomeClass {
  public void testAdd() {
    assertEquals(1+1, 2);
  }
}

私はそれについて何を考えるべきかさえ知りません。

于 2009-10-06T16:10:10.153 に答える
11

The Cuckoo -- Frank Carver
他のいくつかのテスト ケースに置かれ、テスト ケース内の他のテストと同じ (潜在的に長い) セットアップ プロセスを楽しむユニット テストですが、セットアップから一部またはすべてのアーティファクトを破棄します。独自のものを作成します。
の高度な症状:フィクスチャが不適切に共有されている

于 2008-12-02T13:23:06.937 に答える
10

シークレットキャッチャー-フランクカーバー
アサーションがないため、一見テストを行っていないように見えるテスト。しかし、「悪魔は詳細に宿っている」..テストは、スローされる例外に実際に依存しており、テストフレームワークが例外をキャプチャして、失敗としてユーザーに報告することを期待しています。

[Test]
public void ShouldNotThrow()
{
   DoSomethingThatShouldNotThrowAnException();
}
于 2008-12-02T14:07:53.243 に答える
10

環境破壊者

さまざまな「要件」に対して、環境変数/ポートを使用および設定して、その環境に流出し始める「単体」テスト。これらのテストの2つを同時に実行すると、「使用できないポート」の例外などが発生します。

これらのテストは断続的に行われ、開発者は「もう一度実行するだけ」などと言ったままになります。

私が見た解決策の1つは、使用するポート番号をランダムに選択することです。これにより、競合の可能性は減りますが、明らかに問題は解決しません。したがって、可能であれば、共有できないリソースが実際に割り当てられないように、常にコードをモックします。

于 2008-12-04T00:58:22.617 に答える
10

フォーティー フィート ポール テスト

テストしようとしているクラスに近づきすぎることを恐れて、これらのテストは離れた場所で動作し、無数の抽象化レイヤーと、チェックしているロジックからの何千行ものコードによって分離されます。そのため、それらは非常に脆弱であり、関心のあるクラスへの往復の壮大な旅で発生するあらゆる種類の副作用の影響を受けやすい.

于 2008-12-04T00:32:59.877 に答える
10

チューリングテスト

あまりにも巧妙すぎるデータフロー分析を使用して、テスト対象のクラスから収集された非常に多くのアサートを含む、高価なツールによって自動的に生成されたテストケース。開発者は、自分のコードが十分にテストされているという誤った自信に陥り、高品質のテストを設計および維持する責任から解放されます。マシンがテストを作成できるのなら、なぜマシンは指を抜いてアプリ自体を作成できないのでしょうか!

こんにちはバカです。-- 世界で最もスマートなコンピューターを新しい見習いに (古い Amiga コミックから)。

于 2008-12-04T00:42:43.727 に答える
9

ドッペルゲンガー

何かをテストするには、テスト対象のコードの一部を同じ名前とパッケージの新しいクラスにコピーする必要があり、クラスパス マジックまたはカスタム クラスローダーを使用して最初に表示されるようにする必要があります (そのため、コピーが選択されます)。上)。

このパターンは、テストから制御できない不健全な量の隠れた依存関係を示しています。

私は彼の顔を見ました...私の顔!鏡のようでしたが、血が凍りつきました。

于 2008-12-02T12:39:36.383 に答える
7

すべてをテストする

これが今まで言及されていなかったとは信じられませんが、テストは単一責任の原則を破るべきではありません。

私はこれに何度も遭遇しました。このルールに違反するテストは、定義上、維持するのが悪夢です。

于 2012-09-30T04:15:55.817 に答える
7

マザー ヘン-- フランク カーバー
実際のテスト ケースが必要とする以上のことを行う一般的なセットアップ。たとえば、テストが何かの存在または不在のみをアサートするときに、明らかに重要で一意の値が入力されたあらゆる種類の複雑なデータ構造を作成します。
高度な症状:フィクスチャが不適切に共有されている

私はそれが何をするのかわかりません...念のため、とにかく追加しています。-- 匿名の開発者

于 2008-12-02T13:26:10.737 に答える
6

ラインヒッター

一見すると、テストはすべてをカバーし、コード カバレッジ ツールは 100% でそれを確認しますが、実際にはテストは出力分析なしでヒット コードのみを行います。

カバレッジ対到達可能コード

于 2012-04-25T20:34:02.443 に答える
0

結合双生児

人々が「単体テスト」と呼んでいるテストですが、依存関係から分離されていないため、実際には統合テストです (ファイル構成、データベース、サービス、つまり、人々が怠けて分離しなかったテストでテストされていない部分)スタブ化またはモック化されているはずの依存関係が原因で失敗します。

于 2015-01-26T09:26:40.340 に答える