現在のプロジェクト(ゲーム、C++)では、開発中にテスト駆動開発を100%使用することにしました。
コードの品質に関しては、これは素晴らしいことです。私のコードは、これほどうまく設計されていたり、バグがなかったりすることはありません。 1年前にプロジェクトの開始時に記述したコードを見るときに、うんざりすることはありません。また、物事を構造化する方法について、テストが容易になるだけでなく、実装と使用がより簡単になることについて、はるかによく理解できました。 。
しかし...プロジェクトを開始してから1年になります。確かに、私は自分の暇なときにしか作業できませんが、TDDは以前に比べてかなり遅くなっています。開発の速度が遅いほど時間が経つにつれて改善することを読んだので、テストは以前よりずっと簡単に考えられるようになりましたが、今は1年経っていて、カタツムリのペースで作業しています。
作業が必要な次のステップを考えるたびに、私は毎回立ち止まって、実際のコードを記述できるように、そのテストをどのように書くかを考えなければなりません。何時間も行き詰まって、作成するコードを正確に把握しているが、完全にテストでカバーするために細かく分解する方法がわからない。それ以外の場合は、私はすぐに1ダースのテストを考え、1時間かけてテストを作成し、そうでなければ数分で作成できた実際のコードのごく一部をカバーします。
または、50番目のテストを終了して、ゲーム内の特定のエンティティと、その作成と使用のすべての側面をカバーした後、私はto-doリストを見て、コード化される次のエンティティを確認し、執筆の思考に恐怖を感じます実装するための別の50の同様のテスト。
去年の進捗を見て、「いまいましいプロジェクトを終わらせる」ためにTDDをやめることを検討しているところまで来ています。ただし、付属のコード品質をあきらめることは、私が期待していることではありません。テストの作成をやめると、コードをモジュール化してテスト可能なものにする習慣から抜け出します。
私はおそらくこれでとても遅いために何か間違ったことをしていますか?メリットを完全に失うことなく生産性を向上させる代替策はありますか? TAD?テストカバレッジが少ない?他の人々はどのようにしてすべての生産性とモチベーションを殺すことなくTDDを生き残るのですか?
まず、あなたの経験を共有してくれたことに感謝し、懸念を表明することから始めましょう。これは珍しいことではありません。
そして、それは私に最終的なクエリをもたらします:どのように私はより良くなるのですか?私(またはAn)の答えは読む、反映する、実践するです。
例えば最近、私はタブを付け続けています
100%のテストカバレッジは必要ありません。実用的です。
TDDはまだ私をかなり遅くしています
それは実際には誤りです。
TDDがなければ、ほとんどが機能するコードの作成に数週間を費やし、翌年に多くの(すべてではない)バグを「テスト」して修正します。
TDDを使用すると、実際に機能するコードを1年かけて作成できます。次に、数週間の最終的な統合テストを行います。
経過時間はおそらく同じになるでしょう。 TDDソフトウェアの品質は大幅に向上します。
または、50番目のテストを終了して、ゲーム内の特定のエンティティと、その作成と使用のすべての側面をカバーした後、私はto-doリストを見て、コード化される次のエンティティを確認し、執筆の思考に恐怖を感じます実装するための別の50の同様のテスト。
これは、TDDの「リファクタリング」ステップをどれだけフォローしているのか不思議に思います。
すべてのテストに合格したら、今度はコードをリファクタリングして重複を削除します。人々は通常、これを覚えていますが、重複を取り除き、物事を単純化するために、これがテストをリファクタリングするときでもあることを忘れることがあります。
コードの再利用を可能にするために1つにマージする2つのエンティティがある場合は、それらのテストもマージすることを検討してください。実際にテストする必要があるのは、コード内でインクリメンタルな差異だけです。テストのメンテナンスを定期的に行わないと、テストがすぐに扱いにくくなる可能性があります。
役立つかもしれないTDDに関するいくつかの哲学的ポイント:
編集:単体テストの哲学のトピックに関して、これを読むのは興味深いかもしれません: The Way of Testivus
さらに、必ずしも実用的ではないにしても、より実用的なポイントは次のとおりです。
非常に興味深い質問です。
注意すべき重要な点は、C++はテストがそれほど容易ではなく、一般にゲームもTDDの非常に悪い候補です。 OpenGL/DirectXが三角形をドライバーXで赤に、ドライバーYで黄色を描くかどうかを簡単にテストすることはできません。シェーダーの変換後にバンプマップの法線ベクトルが反転しない場合。また、精度の異なるドライバーバージョンでクリッピングの問題をテストすることもできません。不正な呼び出しによる未定義の描画動作も、手元にある正確なコードレビューとSDKでのみテストできます。音も悪い候補です。ゲームでも非常に重要なマルチスレッドは、単体テストではほとんど役に立ちません。だから厳しいです。
基本的にゲームは多くのGUI、サウンド、スレッドです。 GUIは、WM_を送信できる標準コンポーネントがあっても、単体テストは困難です。
したがって、テストできるのは、モデルロードクラス、テクスチャロードクラス、マトリックスライブラリなどです。これはコードが多くなく、最初のプロジェクトだけの場合は非常に頻繁に再利用できません。また、独自の形式にパックされているため、変更ツールなどをリリースしない限り、サードパーティの入力が大きく異なる可能性はほとんどありません。
繰り返しになりますが、私はTDDの第一人者でも伝道者でもないので、すべてを一粒の塩で味わってください。
おそらく、主要なコアコンポーネント(たとえば、マトリックスライブラリ、イメージライブラリ)のいくつかのテストを記述します。すべての関数の予期しない入力に一連のabort()
を追加します。そして最も重要なことは、簡単に壊れない耐性/回復力のあるコードに集中することです。
1つのエラーについては、C++、RAII、および優れたデザインの巧妙な使用は、それらを防ぐための長い道のりです。
基本的に、ゲームをリリースしたい場合は、基本をカバーするためにやらなければならないことがたくさんあります。 TDDが役立つかどうかはわかりません。
他の答えにも同意しますが、非常に重要なポイントを追加します。リファクタリングのコストです!!
適切に記述された単体テストを使用すると、コードを安全に書き直すことができます。まず、適切に記述された単体テストは、コードの目的に関する優れたドキュメントを提供します。第二に、リファクタリングの不幸な副作用は既存のテストスイートに捕捉されます。したがって、古いコードの前提が新しいコードにも当てはまることが保証されます。
他の人々はどのようにしてすべての生産性とモチベーションを殺すことなくTDDを生き残るのですか?
これは私の経験とはまったく異なります。あなたは驚くほどインテリジェントで、バグのないコード(たとえば、1つのエラーでオフ)を書くか、コードにプログラムの動作を妨げるバグがあることに気付かず、実際には完了していません。
TDDは、あなた(そして私!)が間違いを犯したことを謙虚に知ることです。
私にとって、ユニットテストを書く時間は、最初からTDDを使用して行われるプロジェクトのデバッグ時間を短縮することで節約される以上のものです。
間違いをしない限り、TDDは私にとってそれほど重要ではありません。
ほんの少しの発言があります:
テストしようとしているようですすべて。特定のコード/メソッドのリスクが高い場合やEdgeの場合のみ、おそらくすべきではありません。 80/20のルールがここに当てはまると確信しています。コードの最後の20%またはカバーされていないケースのテストを書くのに80%費やしています。
優先する。アジャイルソフトウェア開発に参加し、1か月でリリースするために本当に必要なことのリストを作成します。その後、リリースします。これにより、機能の優先順位について考えることができます。ええ、あなたのキャラクターがバク転をすることができればそれはクールですが、それはビジネス価値を持っていますか?
TDDは優れていますが、100%のテストカバレッジを目指していない場合に限り、実際のビジネスバリュー(つまり、機能、ゲームに何かを追加するもの)を生み出せない場合はそうではありません。
はい、テストとコードの記述は、コードの記述よりも時間がかかる場合がありますが、コードと関連する単体テストの記述(TDDを使用)は、コードを記述してデバッグするよりもはるかに予測可能です。
TDDを使用すると、デバッグがほとんどなくなります。これにより、すべての開発プロセスがはるかに予測可能になり、最終的には間違いなく高速になります。
継続的なリファクタリング-包括的な単体テストスイートなしでは、深刻なリファクタリングを行うことは不可能です。ユニットテストベースのセーフティネットを構築する最も効率的な方法は、TDD中です。適切にリファクタリングされたコードは、コードを保守する設計者/チームの全体的な生産性を大幅に向上させます。
ゲームの範囲を狭めて、誰かがプレイしたりリリースしたりできるようにすることを検討してください。ゲームをリリースするのにあまりにも長く待たずにテスト標準を維持することは、モチベーションを維持するための中立的な立場になるかもしれません。ユーザーからのフィードバックは長期的にメリットをもたらす可能性があり、テストによって追加や変更に慣れることができます。