私の最初のプロのプロジェクトのリズムに乗っている初心者の開発者として、私はできるだけ早く良い習慣を身につけようとしています。ただし、ビルドの最後に、一度に1つずつではなく、テストしたり、延期したり、一連のテストを実行したりするのを忘れることがよくあります。
私の質問は、大規模なプロジェクトで作業するときにどのようなリズムを取り入れたいか、そしてテストがそれに適合する場所です。
私の最初のプロのプロジェクトのリズムに乗っている初心者の開発者として、私はできるだけ早く良い習慣を身につけようとしています。ただし、ビルドの最後に、一度に1つずつではなく、テストしたり、延期したり、一連のテストを実行したりするのを忘れることがよくあります。
私の質問は、大規模なプロジェクトで作業するときにどのようなリズムを取り入れたいか、そしてテストがそれに適合する場所です。
さて、あなたがTDDの人たちをフォローしたいのなら、コーディングを始める前に;)
私はあなたと非常に同じ立場にいます。私はもっとテストに取り掛かりたいのですが、私は現在、私を怖がらせる「コードを正しく出す」のではなく、「コードを取り出す」ことに取り組んでいる立場にあります。そのため、私はゆっくりとテストプロセスを開発サイクルに統合しようとしています。
現在、私はコードを記述しながらテストし、コードを記述しながら破壊しようとしています。TDDの考え方に入るのは難しいと思います。時間がかかりますが、それが私がやりたい方法です。
私はおそらくこれを拡張する必要があると思いました、これは私の基本的な「作業プロセス」です...
私はそれが役立つことを願っています..私がそれが私の懸念であると言ったように、これを改善する方法についてのコメントを開いてください..
コードをチェックインする前に。
覚えておくべき良い鍵は
「早期にテストし、頻繁にテストし、完了したと思ったらもう一度テストしてください」
最初に、そして頻繁に。システムの新しい機能を作成する場合は、最初にインターフェイスを定義してから、それらのインターフェイスの単体テストを記述します。インターフェイスの API とそれが提供する機能を考慮して、作成するテストを決定するには、ペンと紙を取り出して、潜在的なエラー状態や、それが正しい仕事をしていることを証明する方法についてしばらく考えてください。これが難しすぎる場合は、API が十分ではない可能性があります。テストに関しては、複数の特定のオブジェクトをテストする「統合」テストを作成することを避け、それらを「単体」テストとして保持できるかどうかを確認してください。
次に、インターフェイスのデフォルトの実装を作成し(何もせず、ゴミの値を返しますが、例外をスローしません)、テストにプラグインして、テストが失敗することを確認します(これは、テストが機能することをテストします! :) )。次に、機能を書き込んで、テストを再実行します。このメカニズムは完璧ではありませんが、多くの単純なコーディングの間違いをカバーし、アプリケーション全体にプラグインすることなく新しい機能を実行する機会を提供します。
これに続いて、メイン アプリケーションで既存の機能を組み合わせてテストする必要があります。これはテストがより困難な場所であり、可能であれば、優れた QA テスターに部分的にアウトソーシングする必要があります。彼らは物事を壊すコツを持っているからです。これらのスキルもあれば役立ちますが。テストを正しく行うことは、正直に言うと習得しなければならないコツです。私自身の経験は、私自身の単純な展開と、ユーザーが怒って使用したときに報告されたその後のバグに由来しています。
最初にこれが起こったとき、ユーザーが意図的に私のソフトウェアを壊そうとしていることに腹を立て、すべての「バグ」を「トレーニングの問題」としてマークしたいと思いました。しかし、よく考えてみると、私たち (開発者としての) 役割は、アプリケーションをできる限りシンプルで信頼性の高いものにして、愚か者でも使用できるようにすることであることに気付きました。馬鹿に力を与えるのが私たちの役割であり、それが私たちがドルを支払われる理由です. バカ扱い。
このように効果的にテストするには、すべてを壊そうとする考え方を身につける必要があります。ボタンをバッシングし、一般的に奇妙で素晴らしい方法でアプリケーションを破壊しようとするユーザーのマントルを想定してください。欠陥が見つからない場合は、本番環境で発見され、会社の面目を失うことになると想定してください。これらすべての問題について全責任を負い、自分が責任を負う (または部分的に責任を負う) バグが本番環境で発見された場合は、自分自身を呪ってください。
上記のほとんどを実行すると、はるかに堅牢なコードを作成できるようになりますが、これは芸術的な形であり、熟達するには多くの経験が必要です。
いつテストする?コードが正しく機能することが重要な場合!
ここにはたくさんの素晴らしい答えがあります!
私は理にかなっている最低レベルでテストしようとします:
単一の計算または条件付きが困難または複雑な場合は、記述中にテストコードを追加し、各部分が機能することを確認します。完了したらテストコードをコメントアウトしますが、アルゴリズムをどのようにテストしたかを文書化するためにそのままにしておきます。
各機能をテストします。
上記と同じ戦略で各モジュールをテストします。
コード本体全体をテストして、コンポーネントが適切に相互作用することを確認します。下位レベルのテストに熱心に取り組んできた場合、これは本質的に「信頼性テスト」であり、組み立て中に何も壊れていないことを確認します。
私のコードのほとんどは組み込みデバイス用であるため、堅牢性、さまざまなスレッド、タスク、コンポーネント間の相互作用、およびリソース(メモリ、CPU、ファイルシステムスペースなど)の予期しない使用に特に注意を払っています。
一般に、エラーが発生するのが早いほど、エラーの特定、特定、修正が容易になり、尻尾を追いかけるのではなく、作成に費やす時間が長くなります。*
**私は知っています、無償のバッファポインタリファレンスの場合は-1です!*
テストする新しい機能の作成が終了するまで待つと、機能が破損する可能性があると思ったエッジケースの多くを忘れてしまうことがわかりました。自分で学ぶことをしている場合はこれで問題ありませんが、プロの環境では、私のフローは赤、緑、リファクタリングの古典的な形式であることがわかります。
赤:失敗するようにテストを書いてください。そうすれば、テストが正しい変数に対してアサートしていることがわかります。
緑:可能な限り最も簡単な方法で新しいテストに合格します。それがハードコーディングを意味する場合、それは問題ありません。これは、何かをすぐに機能させたいだけの人に最適です。
リファクタリング:テストに合格したので、自信を持って戻ってコードを変更できます。あなたの新しい変更はあなたのテストを破りましたか?素晴らしい、あなたの変更はあなたが気づかなかった意味を持っていました、今あなたのテストはあなたに伝えています。
このリズムにより、機能を動作させるためにチェックする必要があると思ったすべてのものの履歴コンパイラが基本的にあるため、時間の経過とともに開発がスピードアップしました。これは、順番に、私がここに到達しない他の多くの利点につながります...
自分で何かをハッキングするときは、最後にテストします。悪い習慣ですが、これらは通常、私が数回使用する小さなものであり、それだけです。
大規模なプロジェクトでは、クラスを作成する前にテストを作成し、そのクラスに変更を加えるたびにテストを実行します。
私は常にテストしています。関数内のループも終了した後、プログラムを実行し、ループの先頭にあるブレークポイントに到達して、それを実行します。これはすべて、プロセスが私が望んでいることを正確に実行していることを確認するためだけのものです。
次に、関数が終了したら、関数全体をテストします。関数が呼び出される直前にブレークポイントを設定し、デバッガーをチェックして、それが完全に機能することを確認することをお勧めします。
「頻繁にテストする」と言うと思います。
私は最近、通常のワークフローに単体テストを追加しましたが、単体テストを作成します。
私はほとんどのビルドでテストを実行し、常にコードを実行する前に実行します。
ここではTDDを実行しません(一部の人はそれを提唱していますが)が、私たちのルールは、変更を加えてユニットテストをチェックインすることになっているということです。常に発生するとは限りませんが、戻って特定のチェンジセットを確認し、テストが作成されたかどうかを確認するのは簡単です。
ユニットテストから始めます。具体的には、TDD、テスト駆動開発をチェックしてください。TDDの背後にある概念は、最初に単体テストを記述し、次にコードを記述することです。テストが失敗した場合は、戻ってコードを作り直します。合格した場合は、次の問題に進みます。
私はTDDに対してハイブリッドアプローチを採用しています。私は何に対してもテストを書くのが好きではないので、私は通常、最初にコードの一部を書き、次に単体テストを入れます。これは反復プロセスであり、実際には決して行われることはありません。コードを変更し、テストを実行します。障害が発生した場合は、修正して繰り返します。
もう1つの種類のテストは統合テストです。これはプロセスの後半で行われ、通常はQAテストチームによって実行されます。いずれにせよ、統合テストは、全体としてピースをテストする必要性に対処します。これは、テストに関係する実用的な製品です。これは、b / cを処理するのがより困難であり、通常、自動テストツール(たとえば、ロボットなど)を使用する必要があります。
また、継続的ビルドを行うためのCruiseControl.NETなどの製品もご覧ください。CC.NETは、ビルドごとに単体テストを実行し、障害が発生した場合はすぐに通知するので便利です。