web-dev-qa-db-ja.com

TDDでは、コーディングを開始する前に実装するすべてのクラスを指定する必要があります

私のチームは、次のソフトウェアプロジェクトにTDDを適用することに関心があります。開発者がコーディングを始める前に、設計仕様でいくつの詳細を指定する必要があるかについて話し合います。

実装する前にすべてのテストケースを設計する必要があるため、コードを書く前に、すべてのクラスとそれらの関係を仕様で指定するよう提案する人もいます。

一部の人は、これが実際に機能することを疑っています。以前のプロジェクトでは、高レベルの設計しかなく、開発者が詳細クラスとメソッドを自分で設計できました。仕様の詳細レベルは、要件の複雑さと開発者の経験に依存します。仕様は、開発者が何をすべきか理解できるように十分詳細に記述しています。

私は個人的には議論の後半にいます。以前のプロジェクトでは、仕様にクラスとメソッドのすべてのビットを指定しようとしていました。以下は、私がそうすることで遭遇した問題のいくつかの例です。

  • 時間がかかりすぎます。すべてのクラスとメソッドを設計できるようにするには、SA開発者の帽子をかぶって、設計のすべてのビットを実際のコードにマッピングできることを確認します。その結果、設計は多くの場合、実装されたコードと大差ありません。同じことを2回行う必要があります。設計と実装。

  • 開発者には考える余地がありません。この方法でデザインを作成すると、開発者が実装するのは簡単なロジックだけになることがあります。学生にとっては、空白を埋める種類のエクササイズのようなものです。

  • デザインはしばしば時期尚早です。デザインは紙の上で行われます。コードが実際にどのように実行されているかはわかりません。コードを入手したときにしかわからない詳細がいくつかあります。たとえば、基盤となるフレームワークは、何らかの方法でクラスを設計するように強制する場合があり、設計を行っている間はこれがわかりません。また、適切であると判断した場合は、メソッドのロジックを別のクラスにリファクタリングするのが一般的です。実装中に新しいコンポーネントがポップアップするのは当然です。

インターネットで調べてみたところ、このトピックに関連するのは この記事 のみでした。この記事は、詳細クラスでTDDを実行する必要がないことを示唆しているため、私の信念をサポートしているようです。

しかし、参照は私たちが決定するのに十分ではありません。すべてのクラスとメソッドを設計することが正しい方法である可能性があり、それを達成するための手順がわからないだけです。

コードを記述する前に、仕様のすべてのクラスとメソッドを設計する必要があると思いますか?

2
asinkxcoswt

TDDは設計演習です。 「実装する前にすべてのテストケースを設計する必要がある」という意味ではありません。実際、まったく逆です。 TDDでは、次のサイクルを何度も繰り返します。

  • 書きます正確に1つテストに失敗しました。
  • その1つのテストに合格するために実装の十分な量を書き込みます。
  • リファクタリング

時間を無駄にしていないことを確認するために、高レベルの計画を少し行ってもかまいませんが、TDDの背後にある考え方は、ほとんどの作業が最初にテストされることですが、非常に小さな増分で、通常は数分です。必要なクラスの正確なセットを理解するようなことは、その演習から自然に抜け落ちます。

9
Karl Bielefeldt

あなたのチームはTDDの仕組みについて根本的な誤解を持っているようです。すべてのものと同様に、doctrineがあり、現実があります。最初に教義があります。

白紙の状態から始める:

  • 何かを変更する必要があることを証明するためのテストを書く
  • テストを実行して、失敗することを確認します
  • テストを満たすのに十分なだけ実装する
  • テストを実行し、合格したら監視します
  • 必要に応じてリファクタリング(および再テスト)してから、新しいテストからやり直します。

これらの活動はすべて、1人の開発者によって行われています。チームがある場合、作業が完了するまで、チームはそれぞれ同じステップを並行して実行します。

実際には、多くの開発者が最初にコードを記述してから、後でテストを実行しようとします。明確にTDDではありませんが、コードがテスト可能であり、リグレッションをキャッチする限り、これに関する法律の文書を遵守するかどうかは重要ではありません。機能するコードベースがあることがより重要です。

私のチームは、次のソフトウェアプロジェクトにTDDを適用することに関心があります。開発者がコーディングを始める前に、設計仕様でいくつの詳細を指定する必要があるかについて話し合います。

それから、私は Behavior Driven Development(BDD) を検討することをお勧めします。 BDDでは、テスト可能な仕様を記述します。これらの仕様は、ソフトウェアが全体として機能するように設計される方法を決定します。

このアプローチはTDDではなく、2つの概念が相互に排他的でもありません。

一部の人は、これが実際に機能することを疑っています。以前のプロジェクトでは、高レベルの設計しかなく、開発者が詳細クラスとメソッドを自分で設計できました。仕様の詳細レベルは、要件の複雑さと開発者の経験に依存します。仕様は、開発者が何をすべきか理解できるように十分詳細に記述しています。

それにはいくつかの真実がありますが、実装にどのような方法で影響を与えるつもりなのかを知るために、事前に設計作業が必要です。たとえば、深く掘り下げる前に、全体的なアーキテクチャを決定する必要があります。つまり機能的なアプリケーションを構築しているか、DDDを使用しているか。また、マイクロサービスを構築する場合でも、モノリシックアプリケーションを構築する場合でも、.

4
Berin Loritsch

TDDでは、コーディングを開始する前に実装するすべてのクラスを指定する必要があります

いいえ。実際、TDDは具体的にはその代わりです。最初にすべてのクラスを指定することを Big Design Up Front と呼びます。

BigDesignUpFrontという用語は、コーディングとテストが行​​われる前に「大きな」詳細設計が作成されるソフトウェア開発の方法を表すために一般的に使用されます。いくつかのExtremeProgramming(XP)擁護者は、そのような「大きな」設計は必要ではなく、ほとんどの設計は開発プロセス全体で行われるべきだと述べています。 Xpには初期設計(SystemMetaphor)がありますが、比較的「小さい」設計と見なされます。

参照 http://wiki.c2.com/?DesignBeforeCoding

とはいえ、TDDの Look Ma、No Hands 時代は終わりました。

小規模な場合でも、設計の計画がなくてもシステムの開発を開始でき、一連のルールといくつかの反射を適用することにより、非常に優れた設計に到達できることがわかりました。振り返ってみると、「ほら、手じゃない!」って呼んでる。 TDDの時代。批評家は、これをうまくやっている人々が良いデザインの暗黙の知識の多くを利用していたことを正しく指摘するでしょう。ほとんどの場合、同意しました。私たちは、優れたデザインに関するこの知識を教えられるようになり、人々は優れたデザインを有機的に成長させるために開発サイクル全体で継続的な意思決定を行うことができると感じました。設計知識をテーブルに持ち込む必要があります。 -Michael Feathers、2010年。

まともな設計ヒューリスティックから始めれば、TDDははるかにうまく機能します。最初のテストを書き始める前に考えることをやめることは、完全にルールの範囲内です。

3
VoiceOfUnreason

実装する前にすべてのテストケースを設計する必要があるため、コードを書く前に、すべてのクラスとそれらの関係を仕様で指定するよう提案する人もいます。

そうする場合、それはTDDではありません(具体的には、設計は駆動ではなく、加えてリファクタリングからロックされています)。 TDDは動作する方法であり、主にテストに関するものではありません。

some初期設計を行う必要があります。特に、アプリケーションの外側の層がコアドメインとインターフェイスする領域で、どこに行くのかを理解している必要があります。外出先でもデザインを行います。ただし、大きな事前設計は避ける必要があります。通常、その時点では、実装のすべての詳細を設計するためのドメインについて十分に理解していないためです。

コアアプリケーションレイヤーの内部実装の詳細についてテストが認識しないように注意する必要があります。つまり、テストがアプリケーションと相互作用する表面領域を意識的に制御する必要があります。これにより、refactor-機能を変更せずに、テストを変更せずに、これらの内部層のコードを再構築できます。 。ここで、テストはセーフティネットとして機能します。それができない場合は、定義上、リファクタリングを行っていません。あなたは他のことをしています。

リファクタリングすると、コードを新しいクラスに再編成したり、クラスをマージしたり、パターンを適用したり、依存関係を再配置したりする機会があります。allの指定があると、前のクラスはそれと互換性がありません。

テストも維持する必要があります。しかし、それと、同時にリファクタリングを行う必要はありません。このようにして、テストとコードの並べ替えが相互にサポートされます。場合によっては、内部に入るテストを記述して、一種の足場として機能し、困難な問題に対処するのに役立つように構築しますが、それらのテストを変更して、テストが機能するようにする方法を見つける必要があります外層。または、それらを削除したくない場合もあります(そうです、そのような探索的テストを作成し、後で削除してもかまいません)。

1