web-dev-qa-db-ja.com

なぜTDDは大学でもっと人気がないのですか?

最近、ここの人がPythonリストの要素のすべての順列を計算する方法についての基本的な質問をしました。学生からのほとんどの質問については、実際のソースコードは私の答えですが、問題への取り組み方を説明しましたが、本質的にはテスト駆動開発の基本的なプレゼンテーションに終わりました。

問題自体について考えたとき、私が大学でプログラミングを勉強していたときに解決しなければならない同様の問題をすべて思い出しました。テスト駆動開発についても、同等の方法についても教えられませんでしたが、リストから要素を並べ替えるアルゴリズムや、ハノイの塔のパズルなどを解くアルゴリズムを常に求められました。SoftwareEngineering.SEに参加したすべての生徒もそうではありません。 TDD(Test Driven Development)が与えられた問題をどのように解決するのに役立つかを知ること。もしそうなら、彼らは非常に異なって質問を定式化したでしょう。

実際、TDDがなければ、これらの問題はすべて非常に困難です。私自身はプロの開発者だと思いますが、TDDを使用せずにリスト順序付けアルゴリズムを作成するのにある程度の時間を費やします。質問された場合、リストなしで要素のすべての順列を計算するように要求された場合、ほとんど無知です。 TDDを使用します。一方、TDDを使用すると、生徒への回答を書くときに順列問題をほんの数分で解決しました。

TDDがまったく教えられていない、または少なくとも大学で非常に遅れている理由は何ですか?言い換えれば、学生にリストソートアルゴリズムや同様のものを書くように求める前にTDDアプローチbeforeを説明することは問題がありますか?


2つの質問の発言に従ってください。

あなたの質問では、TDDを「問題解決デバイス」として提示しているように見えます[...]過去に、TDDは「ソリューション発見メカニズム」として提示されましたが、ボブマーティン(TDDの主要な擁護者)でさえも認めています技術にかなりの量の事前知識をもたらす必要があります。

そして特に:

TDDによって、明確に定義された仕様を使用したトリッキーなアルゴリズムの問​​題が容易になると思うのはなぜでしょうか。

私の意見では、問題の解決に関してはTDDの魔法とは何かについてもう少し説明する必要があると思います。

高校や大学では、問題を解決するための特別なテクニックはありませんでしたが、これはプログラミングと数学の両方に当てはまりました。振り返ってみると、そのようなテクニックの1つは、現在/最後のレッスン/講義を復習し、練習との関係を模索することだと思います。レッスンが積分に関するものである場合、教師が解くことを求めた問題が積分を使用することを要求する可能性があります。講義が再帰についてであった場合、生徒に与えられたパズルは再帰を使用して解決できる可能性があります。また、数学の問題を解決するための形式化されたアプローチが確実にあり、それらのアプローチはプログラミングにも適用できます。しかし、私は何も学びませんでした。

これは、実際には、私のアプローチは単に問題をぶつけることであり、どのようにそれを解決すべきかを推測しようとすることでした。当時、リストから要素の順列を生成するという課題があった場合、空のリストを入力として使用するのではなく、[4, 9, 2]などの例を使用して、その理由を理解しようとしました。 6つの可能な順列があり、コードを使用してそれらをどのように生成できますか。そこから、問題を解決するための可能な方法を見つけるために多くの考えが必要です。これは、本質的には 元の質問 の作成者が行ったことであり、最終的にはrandomを使用します。同様に、私が学生だったとき、私の年齢の他の学生は[]で始まることはありませんでした:すべてが2つまたは3つの要素ですぐにケースに突入し、30分留まって、コードで終わる場合がありますコンパイルも実行もされません。

私にとって、TDDアプローチは直感に反するように見えます。つまり、それは非常にうまく機能しますが、TDDに関するいくつかの記事を読む前に、(1)最も単純なケースから始めるべきである、(2)コードを記述する前にテストを記述し、そして(3 )決してラッシュせず、コードでいくつかのシナリオを実行しようとします。初心者プログラマの考え方を見ると、直感に反するのは自分だけではないという印象を受けました。関数型言語をよく理解しているプログラマにとっては、より直感的だと思います。たとえば、Haskellでは、最初に空のリストの場合、次に1つの要素を持つリストの場合、次に複数の要素のリストの場合を検討することで順列問題を処理するのは自然だと思います。ただし、再帰的なアルゴリズムが可能であるがHaskellほど自然ではない言語では、そのようなアプローチは、当然ながらTDDを実践しない限り、それほど自然ではありません。

123

私は地元のコミュニティカレッジで非常勤のプログラミング教師をしています。

この大学で教えられる最初のコースは、Javaプログラミングとアルゴリズムです。これは、基本的なループと条件で始まり、継承、ポリモーフィズム、およびコレクションの紹介で終わるコースです。 。すべての1学期で、これまでコード行を記述したことがない学生にとって、ほとんどの学生にとって完全にエキゾチックなアクティビティです。

カリキュラム審査委員会に一度招待されました。理事会は、大学のCSカリキュラムに関する多くの問題を特定しました。

  1. 教えられているプログラミング言語が多すぎます。
  2. ソフトウェア開発ライフサイクルに関するコースはありません。
  3. データベースコースはありません。
  4. 州立大学や地元の大学に単位を移すための単位を取得することの難しさ。これらの学校が「コンピュータサイエンス」、「情報技術」、「ソフトウェアエンジニアリング」という用語の統一された定義に同意できないためです。

彼らへの私のアドバイスは?学生がフルスタックアプリケーションを作成できるカリキュラムに2学期のキャップストーンクラスを追加します。これは、要件の収集から展開までのソフトウェア開発ライフサイクル全体をカバーするコースです。これにより、彼らは地元の雇用主(見習いレベル)で雇用可能になります。

では、TDDはこれらすべてにどのように適合するのでしょうか。正直わからない。

あなたの質問では、TDDを「問題解決デバイス」として提示しているように見えます。 TDDは主に、コードの設計とテスト容易性を改善する方法と考えています。これまで、TDDは「ソリューションの発見メカニズム」として提示されてきましたが、ボブマーティン(TDDの主要な提唱者)でさえ、かなりの量の事前知識を技術にもたらす必要があると認めています。

つまり、コードの問題を最初に解決する方法を知る必要があります。 TDDは、ソフトウェア設計の仕様に関連して、正しい一般的な方向にあなたを微調整します。それはそれを下位レベルのコースではなく、上位レベルのコースにします。

135
Robert Harvey

まず、コンピュータサイエンスソフトウェアエンジニアリング。 (そして、おそらくソフトウェアエンジニアリングとプログラミングまたは「コーディング」との間のより少ない程度に)

私のCS教授の1人が言ったように:キーボードが必要な場合、CSを行っていません。

TDDは非常にソフトウェアエンジニアリング業務です。コンピュータサイエンスとはあまり関係がありません。したがって、CSの学生がTDDを学習しない理由を尋ねる場合、それはTDDがCSとあまり関係がないためです。

さて、ソフトウェアエンジニアリングとはまったく別の魚のやかんです。私はTDDがそこで教えられるべきであることに非常に同意します。私は1つのソフトウェアエンジニアリングクラス(1学期に週90分)を受講し、このクラスではウォーターフォール、Vモデル、RUP、CMM、CASEを学びました、RAD、スパイラル、反復、そしておそらく私が忘れていたいくつかの他のもの。確かに、特にそれを残りのコースと統合し、プログラミングが必要なすべてのコースのすべての宿題とクラスワークにTDDを適用する場合、TDDを絞るスペースがあったはずです。

しかし、公平に言うと、私の場合、アジャイル宣言はまだ書かれておらず、TDDはあいまいなニッチな手法でした。

あなたがプログラミングを教えるための私の個人的なお気に入りである How To Design Program を見てみると、彼らは非常に教えることがわかります関数の初期には使用例が付属し、ほんの少し後に、本は自動化された単体テストそして、それらの使用例はテストの形で書かれるべきであることを示唆しています。また、使用例と「目的ステートメント」と呼ばれるもの(JavaDocコメントの要約行と考えることができます)は、コードの前に記述する必要があることも教えています。

彼らはTDDを明示的に教えていません(彼らは独自の方法論を持っています)が、これは少なくともある程度近いです。 HtDPは高校生が1年未満で教えられるように設計されているので、大学の1学期で教えるのは現実的ではないと思います。

しかし、正直に言うと、学生が実際にさまざまな入力で記述したコードを実際に実行できることを教えてもらえれば、それはすでに大きな勝利です。 (言い換えれば、手作業のテストの大まかな形です。)生徒がこのメンタルステップを踏めないことがどれほど頻繁にあるかに驚いています。

たとえば、Stack Overflowで複数の質問を見てきましたが、これらは基本的に「このコードを機能させるためにどのメソッドを実装する必要があるか」に相当します。これはメソッドのコードについてではなく(質問者はメソッドの実装方法を知っていた)、純粋にname。しかし、1つではない質問者は、単にコードを実行し、NoMethodError例外が常に発生します。

97
Jörg W Mittag

TDDは、「実際の」プログラミングでは素晴らしいプロセスです。なぜなら、問題は指定されていないデスクに到着することが多いからです。 「Xを実行する機能を追加する」、「Yを実行すると間違ったことが表示されるバグを修正する」など。TDDは、プログラミングを開始する前に仕様を作成するように強制します。

CS /プログラミングクラスでは、問題は通常、非常に詳細に特定されます。 「整数の配列を取り、同じ整数が減少しない順序で配列された配列を返す関数を作成します」。スペックは私たちに渡されます。

TDDによって、明確に定義された仕様を使用したトリッキーなアルゴリズムの問​​題が容易になると思うのはなぜでしょうか。具体的には、これについて説明してください。

TDDを使用せずに、リスト内の要素のすべての順列を計算するように依頼された場合、私はほとんど無知でしょう。一方、TDDを使用すると、生徒への回答を書くときに順列問題をほんの数分で解決しました。

P([]) -> [[]]P([1]) -> [[1]]P([1, 2]) -> [[1, 2], [2, 1]]などをアサートするテストケースを書いて、再帰がどのように機能するかを確認したので、あなたが言うと思う。しかし、それはTDDではありません。問題について考えているだけです。失敗する実際の単体テストを作成するプロセスなしで問題を考えることができます。

53
MattPutnam

自動化されたテストを書くのは、テストされるコードを書くよりも難しいからだと思います。基本的なメカニズムにまだ苦労している場合、別のレイヤーを追加することは困難です。また、他の回答が指摘しているように、TDDは実践者がそれを教訓的な装置としてより多く考えているにもかかわらず、ソフトウェアエンジニアリングプロセスとして認識されています。また、どのテストを最初に書くかを知ること自体がスキルです。

入門コースを担当している場合は、提供 TDDの順序でいくつかのテストを行い、その順序で1つずつテストに合格するように生徒に指示します。これは、プログラミングと経験豊富なメンターとのペアリングと非常に似ています。個人的には、アルゴリズムのようなクラスを教えるのがより簡単になると思います。これは、段階的に進むため、テクニックに費やされる時間を相殺します。 「2要素リストのすべての順列を見つける実証済みの作業コードがあります。3以上の要素で機能させるために、そのコードを可能な限り再利用するにはどうすればよいですか?」

33
Karl Bielefeldt

基本的な問題は、TDDプロセスでテストを作成することは、コンピュータサイエンスやソフトウェアエンジニアリングとは何の関係もないということです。 アプリケーションドメインの知識が必要です。

もちろん、これが実際のアプリケーションにおけるTDDの強みです。構築しているシステムが実際に何のために使用されるかについて考えることから逃れることはできません。しかし、典型的なCSおよびSEのアクティビティでは、学生に与えられるタスクは最小限のコンテキストであり、いくつかの学習目標をテストまたは説明するためにのみ存在します。

たとえば、学習目的がプログラミング言語で「ケース」構造の理解を示すことである場合、TDDは無関係です。「ケース」をまったく使用せずにすべてのTDDテストに合格するソフトウェアを作成できます。例が人工的なものである場合、「ケース」を使用しないことは実際には現実の問題のより良い解決策である可能性がありますが、意図された学習目標に関してはそうではありません。

必ず学生に自分のテストケースを発明して実行するように勧めますが、正式なTDDプロセスを使用することは重要ではありません。

2番目の問題は、CEとSEを教える方法と関係があるかもしれませんが、それでも実際的な問題です:学生のテストのコレクションを評価する方法TDDを使用する場合?そのプロセスを自動化する明白な方法はありません。

「次の15または20の状況でテストする必要がある」というモデルソリューションを作成した場合でも、モデルの回答の各部分に(全体的または部分的に)対応する学生のテストを手動で特定する必要があります。そして、些細な場合を除いて、学生はモデルの答えとは異なる方法で論理的に構造化された優れた一連のテストを作成した可能性があります。

9
alephzero

平均的な学生は、実際に彼らが知って何をすることが期待されているかについて、悪い概観を持っています。 TDDを教えるには、次のことを理解する必要があります。

  1. 技術的な問題のトラブルシューティング方法。当初、彼らはコードが一度に書かれていると思っています。彼らが基本的なデバッグ戦略に気づいた後、彼らはよりインクリメンタルな書き込みに移ります。彼らが前もってこれを言ったとしても、彼らは物事が成し遂げられた方法であると彼らが思うので、彼らはまだこの方法でそれをします(これは、人々が描画、ピアノを弾く、数学をするなどの方法を知らない理由でもあります) )

  2. 自分の行動に反復可能なパターンを見つけることができるように、自分の行動を内省する方法。これができたら、自分の作業を自動化できます。しかし、一定のレベルに達するまで、ほとんどの人にとってこれはまったく異質です。

  3. 要件の書き方。

  4. 問題空間のコーナーケースを理解する。

  5. リスク管理のエンジニアリング哲学を理解する。 (ハ、でもエンジニアだとは知らない)

  6. コードのリファクタリングとメンテナンスについて理解する。

  7. 実際の会社でのプログラミングの仕組みを理解する。

実際、TDDをあまりにも早く紹介された同僚がいましたが、あまりメリットがありませんでした。しかし、この効果に向けてまだまだ一歩踏み出すことは可能です。人々が恩恵を受けるには、その背後にかなりの経験が必要です。

だからあなたはそれを教えることができますが、あなたが最初から何かを教えることはできません。特に、TDDに適さないコードがあるためです。

8
joojaa

TDDは、大学ではあまり一般的ではありません。なぜなら、(一般的に言えば)大学は、学生に与えられている知識を実際の状況に変換できることを保証する上で非常に貧弱な仕事をしているためです。

間違いなく、そもそもそれは大学の役割ではなく、CSの基本とコアコンセプトを教えることについてです。学生がアカデミアでのキャリアを追求することに興味がある場合、それは有益で、重要であり、不可欠ですが、学生が学位を取得して業界に登録し、チームに統合されて開発に続くときは不十分ですベストプラクティス、CI/CDなど.

明らかに、交差点があり、両方がお互いから利益を得ることができますが、結局のところ、大学は、より有能で、関連性があり、最新のソフトウェアエンジニアを卒業するために必要なことについて、まだ十分にスピードアップしていません。

6
Bruno Oliveira

質問に直接回答するには:

誰かが示唆したように、学期全体に十分な学習があります。別のコース?多分。 TDDがソフトウェア設計のトピックと組み合わされているのを見ることができました。 IMO TDDの最大の価値は、既存の動作をロックダウンして、後で新しい動作を追加し、それらの新しい動作に適するように設計を変更できるようにすることです。それでは、ソフトウェア設計のクラスですか?

TDDの背後にある思考プロセス(名前が不十分で、ケントベックに再考するかどうか尋ねたところ、「その列車は駅を発車した」と彼は言った)ができるだけ早く導入されたとしたら嬉しいです。私は1976年からコードを利用してきましたが、最初はTDDが非常に不自然に感じられたことを知っています。しかし、今ではかなり自然な感じがします。私の時間は、テストコードを書くことによって取り戻されるのではなく、後で取り戻されます。深刻な欠陥を年に1回修正するだけで十分です(完全にテスト駆動で記述されたUofM移植センターのOTIS2ソフトウェアは、2004年に最後の「ソフトウェア緊急事態」がありました。 )。

新卒の方は、1か月間試用することをお勧めします。しかし、彼らがTDDにずっと早くさらされていれば、彼らにとってははるかに簡単になります。新しい言語を学習しているときにユニットテストフレームワークを使用すると便利です(実話:「このテストをRubyで渡すにはどうすればよいですか?うまくいくかもしれません...」新しいライブラリ(「ドキュメントはこれらが返される順序についてあいまいです...テストを作成します...」)。

アルゴリズムを実装するとき(アルゴリズムを発明するのではなく...それを実現します)、または少し複雑なビジネスルールを最初から構築するときに、TDDは価値があると思います。合格している各テストは、永遠に「ロックイン」されます。テストが十分に離散的であれば、変更する必要はありません(ただし、thatが上手くなるまでに1か月以上の時間がかかります)。

したがって、TDDを以前のプログラミングクラスに組み込むことは興味深いでしょう。 3つの改善点:

  1. ほとんどの開発者が自分の仕事の本質であると考えているデバッグとブレークフィックスにそれほど焦点を当てることはできません。それはそうではありません。それほど苦痛で時間のかかるものである必要はありません。
  2. 単体テストフレームワークは、#ifdef DEBUG/printf( "...")/ #endifの単純な置き換えです。そのため、当初から同様の(しかしより危険な)処理を行ってきました。
  3. 「最初にテストを記述しなければならない」と聞くと、誤解を招きます。私wantこれから書こうとしているコードに対する期待を書き留めます。次の動作に集中するか、デザインのクリーンアップに取り掛かる間、その実行を続けたいと思います。

役立つかもしれないもう1つのことは、教科書、または少なくとも、TDDプラクティスのさまざまな側面を伝えるために設計されたラボを備えた、簡潔で実用的なカリキュラムです。そのための提案があります(後で体験/免責事項を参照)。

批評家に答えるには:

私はここに新しいですが、いくつかの「回答」は質問に回答しないが、TDDの公正な批評であることに注意します。だから私はそれらの懸念のいくつかに対処することは大丈夫だと思いますか?

  1. 確かに、TDDを単体テスト後(UTA?)と比較して行われた研究では、TDDが最初は遅いことが示されています。ただし、UTAグループのテストカバレッジははるかに低く、欠陥も多かった。私はそれがこの研究だったと思います: 産業におけるテスト駆動開発実践の使用に関する縦断的研究

数か月以上製品に取り組んでいる開発者が新機能の作成に大部分の時間を費やしているとしたら、これは悪いことです。しかし、私が開発者として取り組んだ6つのTDDチームはそのように時間を費やしましたが、TDDの前にコードをスリングするのに費やした10年は、ほとんどがデバッガーで費やされたか、慎重にコピー/貼り付け/変更して、古いバージョンを壊さないようにしました/他人のコード。 TDDの利点はすべてが瞬時であるわけではありませんが、開発者の時間外勤務(およびストレス)の低下と収入の増加。結論:これらのTDDチームと一緒に仕事に行くのをいつも楽しみにしていた。 (お茶を飲んだら)

  1. TDDが新しいアルゴリズムを発明できないことも事実です。 TDDを使用して数独ソルバーを作成しようとし、自分の数独スキルが実装に干渉しないようにしようとしたのは、ロンジェフリーズだったと思います。彼は失敗した。驚かない。 TDDは、ビジネスルールの分解、簡素化、および実装を支援します。アルゴリズムが正しいことを確認するのに役立ちます(例:還元できない複雑な暗号化アルゴリズム)。安全に新しい機能を追加できるように、後でコードを再形成するのに役立ちます。これは、製品の動作にすでに行った投資を固定することで実現します。

「テスト」(別名仕様、別名シナリオ)を作成するときは、答えを知る必要があります。また、ソリューションを実装する方法についての概念(事前の知識)をすでに持っているソリューションから十分に小さなテストを作成したいとします。

多くの場合、驚かされるのは、コードの臭いに注意を払い、そのコードに関連するすべてのテストに合格したときに、必要に応じてリファクタリングすると、デザインがいかに明確かつ単純になるかです。

デザインパターンや言語のイディオム、SOLIDの原則、数独の遊び方、ヒープソートの書き方など)についての知識を捨てるよう提案する人は誰もいません。

TDDは、新しい機能を迅速に追加し、他を壊すことなくそれらの新しい機能に合うように設計を変更する自信を私たちに与えるセーフティネットを作成することです。

UTAは、誰かが穴を通り抜けて死んだ後、セーフティネットにパッチを当てています。 (興味深い副注:OTIS2プロジェクトは生命にかかわるシステムであるため、患者の死のリスクは冗談ではありませんでした。現在、20,000を超えるテストがすべて10分で実行されています- それはセーフティネットです!)

経験/免責事項:

私は1998年から2004年までほぼフルタイムでTDDを行い、最大6つの異なるチームで作業しました。すべてが少なくとも6か月の開発期間でした。その前に、私は13年間、逆の方法でソフトウェアを作成しており、printf()を使用したデバッガーや手動テストを嫌いになりました。

2001年にTDD、BDD、およびSA-CSDコースを含むソフトウェア開発の実践を教え始めました。確かに、それは良い生活ですが、TDDはチーム中心のソフトウェア開発を正気で楽しいものにする簡単な方法であることも知っています。そう...

私は大学や高校の教科書になることを望んでいます(もちろん、オンラインのレポ、ラボ、ビデオなどで): Essential Test-Driven Development

4
user30938

私はTDDが実際に問題を解決する方法として役立つとは考えていませんでした。

TDDは、問題を一方の端、つまりクライアントの端から見るように強制するだけです。これは、クライアントの質問に一致しないソリューションを思い付くのを防ぐのに役立ちます。これは一般的には良いことですが、制限されることもありますが、問題をより広い角度から見ることができなくなり、クライアントが考慮しなかった問題に対するより一般的で優れた解決策が存在する可能性があります。

それを見る別の方法は、それが究極のトップダウンアプローチであるということです。 TDDはトップダウン開発を表すことができます。ほとんどのコースレベルで開発を開始し、徐々に拡大します。

どちらにしても、それは抽象的な概念です。生徒にそれについて語り、定義を提供することができますが、それだけです。試験でそれについて多くの質問をすることはできません。したがって、SEまたはCSクラスでは、SEのコンテキストでは有用ですが、副次的なものにすぎません。

4
Martin Maat

私は1970年代に頭字語TDDが発明されるずっと前にコンピューティングサイエンスを教えられました。もちろん、そのテクニックを明示的に教えることはありませんでした。しかし、与えられたプログラミング演習の1つでは、一連のテストケースが提供され、ソリューションはテストに合格する必要があると言われました。だから私はそれを明確に教えられることなくアプローチの価値を学び、それ以来それを使ってきました。

4
Michael Kay

テストの作成はソフトウェア開発に不可欠なスキルですが、科学的証拠は、TDDが最終的な反復テスト(ITL)開発(OTOHよりも優れたソフトウェアを生成することを示しているわけではありません悪い)。

証拠として、Davide Fucci et al。をご覧ください。 「マルチサイトブラインド分析アプローチを使用したテスト駆動開発の影響に対する外部レプリケーション」( link )およびTurhanらのソフトウェア作成におけるメタ分析( link )。

したがって、TDDが実際に測定可能な利益を提供するという反対の証拠を見始めない限り、開発プロセスのある時点でテスト作成の良い習慣を単に注入することとは対照的に、特定の実践としてTDDを教えることはそれほど重要ではありません。

3
Anzel

しかし、尋ねられた場合、私はまだTDDなしでリスト順序付けアルゴリズムを書くのにしばらく時間を費やし、リスト内の要素のすべての置換を、まだTDDを使用せずに計算するよう求められた場合、ほとんど無知になります。一方、TDDでは、順列問題をほんの数分で解決しました

これは私を真剣に混乱させています。
私にとってテスト駆動開発とは、テストを早期に検討し、時間をかけてテストを実装し、コードで最新の状態に保つことを意味します。
もちろん、何をテストするかを考えることは、解決する問題を詳しく説明する良い機会であり、場合によっては、落とし穴が何であるかをよく把握することができます。
しかし、TDDを行わず、最初にテストに集中しないことは、とにかく根本的な問題について考えることを禁じません。もう一歩進んでテストを今すぐ実装するかどうかに関係なく、常に何をするかを考え、状況を明確にする必要があります。

学生にリスト分類アルゴリズムや同様のものを書くように頼む前にTDDアプローチを説明することは問題でしょうか?

TDDをどの程度説明するかによって異なります。
何かについて聞くと役に立ちます。しかし、他の基本事項がまだ欠けているため、生徒はまだ解釈できない多くのことを聞きます。したがって、基本的な知識がなければ、未知の用語の役に立たない疎外の混乱になるという概念を深く理解するべきではありません。
これに加えて、おそらく多くのプログラマーは、問題のハウツーを探して実際に解決策を示す例を見つけたとしても、それがどのような感じかを知っていますが、まず最初に、あらゆる種類の無関係なものを整理する必要があります著者が付け加えた。

ですから、この質問に答えるために、私が学生だったら、物事を分離したいと思います。リストを並べ替える方法を説明することを発表した場合は、その方法を教えてください。ただし、テスト項目に記入するための道を離れないでください。テストの説明を開始したい場合は、ソートを実装するように告知しないでください。これは長い間行われないためです。
ここでも、並べ替えやテストの記述を始める前に、いくつかの考えが必要です。リストはソートの前後でどのように見えますか?例を挙げ、落とし穴、リストが空のときに失敗しないようにするために考慮すべきことなどについて考えます。これらすべてを考慮する必要がありますが、テストの行はまだ書かれていません。

一般的に、別々に保管する必要がある2つのことを混同していると思います。

  • 解決したい問題の性質について考える。
  • コードへの入力とどのような出力を与えるかについて考えます。

問題について考えることは、テストケースを書くことに集中することとは大きく異なります。

悪いやり方

かつて、TDDに夢中になっている人がTDDの例を見つけました。
残念ながら、著者は自分のチュートリアルが好きすぎたようで、実際のところがらくたであることに気づきませんでした。

著者onlyは、コードが処理する必要のある問題ではなく、テストケースに集中しました。すべての入力順列を見つけることはできないため、実際に行っていることの概要を把握し、問題全体を確認する必要があります。常に空の入力から始めて、その後さらに入力を追加し、常にコードを追加して新しい入力を正しく処理することはできません。
一般的に実際に何を扱っているかを理解している必要があります。しかし、著者はしませんでした。

それをリストの並べ替えに変換しようとすると、空のリストから始めて、そのまま返すことができる1つの要素、2つの要素を含むリストを交換する必要がある可能性があり、おそらく再帰に至ります。 3つの要素は2つの要素(既に解決済み)に加えて、1つの追加ステップでもう1つ要素を追加したものです...
ソートアルゴリズムにとって恐ろしいシナリオですが、テストケースのみに集中しているため、誰もそれを理解できません。

結論

コメントは私の意見についてもう少し書いてくれます。

「テスト駆動開発」という言葉は間違っていると思います。これは「テストでサポートされる開発」である必要があります。つまり、コーディングと希望だけでなく、テストについても考えており、何か問題が発生したときに早期に知っておくことは常に良いことです。

テストによって開発にDrivenという名前が付けられている場合、これはすべてがテストのみに依存することを意味し、いくつかのテストケースが満たされるとすぐに完了します。この要件は、全体として問題を確認しようとはしなかったが、すべてのテストケースが強​​制的に緑色に変わるまでハッキングされ、実際の操作で失敗する非常に不十分なコードでも満たされます。

2
puck

「なぜTDDは中核的な学習ツールとして教えられないのですか?」という質問に更新しました。他の回答は、TDDが101のコーディングに適さない理由を十分に説明していますが、主な回答は、TDDがコアで問題解決ツールではないということだけです。その目的に使用できますが、どのツールをいつどのように使用するかを最初に理解する必要があります。

TDDはテストプロセスであるため、当然のことながら、開発プロセスコースの一部として、またはソフトウェアテストコースの一部として教えられます。コーディング101コースの目標は、学生が問題を解決することではなく、さまざまなプログラミング概念の使い方を教えることです。一般的に、ほとんどのコーディング101および102プロジェクトは、問題の解決方法について非常に明確です。学生は、コピー/ペースト以外の方法でタスクを実行するために学んだことを理解する必要があります。

どの生徒もさまざまな方法で学びます。一部の学生はそれについて読む必要があり、他の人はそれを口頭で説明する必要があります。また、コードに精通しない限り、まったく理解できない学生もいます。学習プロセスを支援するためにTDDを教えることは実際にはほとんどの学生を助けません、そしてそれは助けますか?教師は、TDDを教える時間が追加学習速度に見合う価値があるかどうかを判断する必要があります。全体として、どのような学習方法を教えることも、実際のコース固有のトピックに費やすことができるクラスの時間の価値はありません。 (一般的に、学習と問題解決のスキルは、生徒だけが自分に最適なものを特定できるので、通常、生徒が自分で学ぶことができます)

TL:RD;人によって効果的なプロセスは異なります。大学はあなたが何をすべきかを規定していません。自分に最適な方法を実行できるように、ツールを提供してください。

1
Tezra

TDDは素晴らしい実装ツールであり、それが有益であることは正しいと思いますソフトウェアを書きたい人にとって

TDDがまったく教えられていない、または少なくとも大学で非常に遅れている理由は何ですか?言い換えると、学生にリストのソートアルゴリズムなどを書くように依頼する前にTDDのアプローチを説明することは問題でしょうか?

おそらく最大の理由は、これらのプログラムを教えている教授が専門分野ではないため、ソフトウェアの開発方法をほとんど知らないためです。他の回答が述べたように、コンピューターサイエンスとソフトウェアエンジニアリングは異なる分野です。コンピューターサイエンスの学生がソフトウェアエンジニアリングを学ぶという期待と、自動車の設計方法を学ぶ物理学の学生を比較します。 TDDは、実際に効果的に教えるにはかなりの練習が必要なスキルです。コンピュータサイエンスの教授は、キャリアの大半をコンピュータサイエンスに費やしているため、コンピュータサイエンスの教員はTDDを実際に教えることができると期待しています。それは単に生徒を混乱させるだけではなく、私の意見ではかなり非現実的です。

コンピュータサイエンスと専門的なソフトウェア開発は、それらを明確に分離した分野として扱う必要があります。あなたの目標がコンピューターサイエンスを学ぶことであれば、Reactでウェブサイトを作成する方法を学ぶために何千ドルも払うことで負担されるべきではありません。チョークボードの理論です。同様に、ソフトウェアエンジニアになることが目標である場合、4年間、数万ドルを費やして、本質的に数学の特定の分野だけを学習する理由がわかりません。排気マニホールドを設計する人がある程度の物理学を理解する必要があるのと同じように、フィールドで基本的な理解を得るために、しかし、排気マニホールドを設計する人は量子力学、特別な相対性理論の深い理解をあまり必要としません。そして電磁気学は彼らの仕事をする。

あなたが会計士になりたいなら、あなたは会計の学位を取得することができます、そしてあなたの教授はすべてある時点でCPAである可能性があります。機械工学者になりたい場合は、機械工学の学位を取得できます。また、すべての教授は、いずれかの時点で技術者にライセンスされている可能性があります。しかし、ソフトウェアエンジニアになりたい場合、ソフトウェアエンジニアリングの学位は実際にはコンピュータサイエンスの学位になり、選択科目の一部はすでに選択済みであり、教授の誰もプロのソフトウェア開発者であることがほとんどありません。会計学の学位は数学科の一部ではなく、機械工学の学位は物理学科の一部ではありませんが、ソフトウェア工学の学位はほとんど常にコンピューターサイエンス学科の一部です。アカデミア全体がこれら2つのフィールドを異なるスタッフが運営する異なる部門に完全に分けるまで、ソフトウェアエンジニアを志す学生に教えられないTDDのようなものの長いリストが常にあると思います。

1
Dogs