3

私はTDDにかなり熟練していると感じており、社内の「TDDエキスパート」とさえ言われていますが、それでも適切な処理方法がわからないと感じる場合があるので、他の人の意見を聞きたいと思います。 。

私の問題は次のとおりです。一般に、TDDはクラスの中心的な責任を考え、依存するクラスに他のすべての責任を抽出するのに役立ちますが、しばらくすると、クラスの1つに複数の責任があることに気付く場合があります。リファクタリングして2つのクラスに分割する必要があります。この結論は、そのクラスのテストが複雑または反復的になり始めるためによく起こります。このクラスを必要なデザインに分割するために、リファクタリングを非常に簡単に行うことができます(そして、緑色のバーを維持しながら、小さなステップでそれを行います)。私の問題は、2つのクラスを一緒にテストするのと同じ複雑で反復的なテストになってしまうことですが、クラスごとに別々のテストを行いたいと思っています。それを行うために私が考えることができる唯一の(多かれ少なかれ安全な)方法、

  1. テストケースを複製する
  2. テストの一方のコピーを1番目のクラスの代わりにモックを使用するように変更し、テストのもう1つのコピーを2番目のクラスの代わりにモックを使用するように変更します。
  3. 次に、コピーの1つに同じテストがすでに存在することがわかった場合は、それを削除します。

私は時々次のことをすることが可能だと思います:

  1. 2つのクラスを最初から作成することから始めます(もちろんTDDを使用します)
  2. 古いテストを変更して、古いクラスの代わりに新しいクラスを使用する
  3. 古いクラスを削除する
  4. 古いテストを削除する

これらのテクニックはどちらもかなり面倒で時間がかかるように思われるので、「本当の専門家」はこの問題にどのように取り組むのでしょうか。

4

4 に答える 4

2

実際の例がなければ、あなたが何を意味しているのか正確にはわかりません。しかし、すべてのクラス (および場合によってはすべてのメソッド) を個別にテストしようとしているように思えます。

クラスを複数のクラスに分割したい/分割しなければならないところまで来ても、クラスの結果のコレクションを 1 つの単位として見て、全体としてテストする傾向があります。それらが機能的な全体の構築をやめ、独立したユニットになり始めたときにのみ、私はそれらを互いに独立してテストします.

于 2012-09-10T10:44:08.517 に答える
1

このクラスを必要なデザインに分割するリファクタリングをかなり簡単に行うことができます (緑色のバーを維持しながら、小さなステップでそれを行います)。私の問題は、クラスごとに個別のテストを行いたいのに、2 つのクラスを一緒にテストする同じ複雑で反復的なテストになってしまうことです。

私もここまで来ました。ここで、テスト以外のコードと同じ手法 (変数をフィールドに変換、フィールドを移動、メソッドを抽出、変数を移動など) を使用して、テストのリファクタリングを開始します。名前付けはもちろん非常に重要であり、多くの設計ガイダンスを提供します。

http://www.kdgregory.com/index.php?page=junit.refactoringhttp://www.natpryce.com/articles/000686.htmlhttp://www-public.it-sudparis.eu /~gibson/Teaching/CSC7302/ReadingMaterial/vanDeursenMdenBK01.pdf

最後の記事には、特にリファクタリング テストに共通する匂いとリファクタリングの例がいくつかあります。

于 2012-09-11T05:43:47.020 に答える
1

クラスの責任とは何かを自問することから始めます(あなたがそうであるように)。たとえば、クラスが天気データを集計して天気予報 生成するとします。

この時点で、3 つのリストを作成します。

  • データ集計メンバー (属性、動作)
  • レポート生成メンバー
  • 共通メンバー

最初の 2 つは簡単です。1 つのクラスに排他的に属するメンバーは、2 つの新しいクラスのいずれかに排他的に属します。元の二重責任クラスをファサードとして保持し、そのメンバーは新しいクラスへのパススルーであるため、リファクタリング中にテストと機能が壊れることはありません。状況によっては、最終的にファサードを削除し、テストと依存オブジェクトをリファクタリングして新しいクラスを使用する場合があります。

両方の責任に共通するメンバーについては、新しいクラス (および他のすべてのクラス) が使用するヘルパー クラス (通常は内部スコープ) に移動します。この機能は再利用できることが証明されており、再利用される可能性があります。共通メンバーがすべて 1 つのヘルパー クラスに含まれるとは限らないことに注意してください。補助機能は 1 つの新しいクラス、複数の (もちろん責任に応じて) クラスに追加される可能性があり、一部の機能は既存のヘルパー クラスに追加される可能性があります。

于 2012-09-11T06:52:34.203 に答える
0

私はしばらく前にこれについて疑問に思いましたが、満足のいく答えを見つけることができませんでした。このトピックについて私が見つけたいくつかの議論を次に示します。

http://tech.groups.yahoo.com/group/testdrivendevelopment/message/27199

http://tech.groups.yahoo.com/group/testdrivendevelopment/message/16227

個人的には、私は責任を依存関係に移動するための「ヘアトリガー」アプローチを採用しました。新しい依存関係が明確に必要になる前に「スピンオフ」している間、YAGNI のスマックを見つけましたが、依存関係を再吸収することがわかりました。別のクラスであることを保証するにはあまりにも貧血であることが判明したことは、すでにかなりの数のテストが書かれているクラスから別のクラスを分割することに伴うリグマロールよりもはるかに簡単です。

編集:

ああ、おそらく私は「本当の専門家」ではないことを指摘しておく必要があります;)

于 2012-09-10T10:23:19.817 に答える