テストの不人気な側面

テストの不人気な側面



各開発者はテストの作成が正しいことを知っており、一部の開発者は自分の経験からこれを知っています。また、個人的な経験からこれを知っており、自分の本を売る方法を知っているプログラマーの本の別の人もいます。 私は本の書き方がわかりませんし、経験もほとんどありませんが、単体テストの使用に関するいくつかの側面を共有できます。 以下では、あまり一般的ではない真実ですが、より独創的な考えについて言及しようとします。 すべての考えがどの言語やフレームワークにも結び付けられているわけではないため、この記事は開発者の幅広い読者に役立つかもしれません。



最初はテストのフレームワークの調査とテストの作成に時間を費やさなければならないため、テストの作成で最も難しい部分は開始しますが、テストからの有用なフィードバックは後ほど提供されます。 また、テストに間違った時間を選択して失望することは非常に簡単です。たとえば、統合システムではなくユニットテストで既に実行中のシステムをカバーするという考えは、ほとんどの場合失敗です(例外は、システムの作成後にユニットテストが記述されている場合、しかし、同時に、エラーを修正する場合、テストのタスクは、エラーが発生した状況を再現し、エラーがなくなったことを確認することです)。 テストの作業を始めたばかりの開発者は、コードと同時にテストを作成する必要があることを覚えておく必要があります。 この共通の真実の後、元の場所がすぐそこにあります。



テスト-繁殖エントリポイント


テストについて考えるようになった開発者がいるとは信じられませんが、それ以前には彼は関与していませんでした。 おそらく、彼が書いたテストはプログラムへのエントリポイントで記述され(C、C#、Javaはメインプロシージャのバリエーションです)、クラッシュせずに機能するまで1回以上実行され、削除されます。 この開発者は、テストがプログラムへの同じエントリポイントであると考えるのが便利ですが、テストは多くあり、作成は簡単です。 したがって、実行中のテストは削除できません。 さらに、最後の瞬間まで、メインエントリポイントを完全に取り除き(つまり、コンソールプログラムを開発している場合は、それをdllに置き換えます)、この目的のためにテストのみを使用できます。 以下はアイデアであり、その結果はTDDです。



決して落ちないテストは無駄なテストです


これは簡単に証明できます。2人の双子のプログラマーを考えてみましょう。1人はテストを使用せずにすぐに動作するプログラムを作成し、もう1人は同じ方法でテスト範囲を作成しました。 その結果、2つの同一のプログラムがありますが、2番目のプログラムはより多くの時間を費やしたため、コストが高くなります。 テストが役に立たないという条件を導入する場合、良いテストは少なくとも一度プログラムに失敗するはずです。 興味深いことに、TDDの概念(テストはテスト対象のコードが記述される前に記述されます)はこのステートメントから派生します。コードがテストの後に記述された場合、これによりテストは失敗します。



テスト-静的に型付けされた言語でのREPL


読み取り、評価、印刷、ループ-これがREPLの略です。 おそらく、すべての動的言語で存在します。たとえば、Rubyではirbです。一般に、REPLはそこに入力されたコードをすぐに実行するコンソールです。 REPLは、たとえば、標準のSort()メソッドを昇順または降順ですばやくチェックする必要がある場合に役立ちます。 もう1つの使用法は、記述されたコードをメモリにロードし、迅速にテストすることです。 多くの場合、REPL実装には1つの優れた機能があります。入力されたコマンドの履歴は、実行結果とともにソースファイルに保存できます。 これにより、次のようにコードを記述できます。Googleサーバーへの接続を試みます-いまいましいエラー、そうであれば-素晴らしい; そこに他に何が必要で、結果を解析します-この正規表現は機能するはずですが、このデータセットでテストしますか? エラー?、そして実行するのが貪欲なバージョンではない場合-それは動作します-勝利後、コンテキストを保存し、それを編集し、プログラムの準備ができています。



残念ながら、静的に型付けされた言語はREPLとは友好的ではありませんが、単体テストに置き換えることができます。 ライブラリ関数の動作がわからない場合は、テストを作成します。 また、システムのかなりの部分がすでに記述されている場合、テストでコードの記述を開始し、新しいモジュールの準備ができたら、リファクタリングして、機能をテストから別のモジュールに分離し、テストの親がテストに変わることにも気付きましたこのモジュールをテストします。 したがって、テストはREPLと同じ役割を果たします。



テストによりコードの不活性度が高まる


これはテストの物議を醸す特性であり、設計が不十分な場合、テストはコードの変更に抵抗します。 物議をかもしているのは、悪い建築家は邪魔をするテストをscるのに対して、良い建築家は自分の間違いがどこにあるのかを教えてくれて賞賛するということです。



テスト-動的言語での入力


テストはRubyを積極的に宣伝した人によって開かれ、私は彼に反対し、コンパイラの助けを参考にして静的型付けで言語を保護しようとしました。 彼の答えは-コードがテストでカバーされている場合、なぜコンパイラチェックが必要なのかということでした。 この例は、テスト言語が動的言語のプログラマーの間でより発達しているという事実を説明できます。 これのもう1つの証拠は、「java tdd」と「ruby tdd」のリクエストではgoogleがほぼ同じページ数を提供しますが、「java」と「ruby」のリクエストでは違いが大きいことです。



テスト-定理、コード-証明、テスト-正式な証明検証


この声明は一部前の声明の結果であり、カリー-ハワード同型と関連していますが、私は数学プログラミングのこの分野を掘り下げていないので、この声明は厳密な理論よりも直感に基づいています。 このステートメントを例で説明しようとします。 プログラムを林業の消防サービスのエミュレーションとする:1日3回特定のルートをパトロールするパトロールがあり、火がパトロールの範囲内にある場合、偶然に発生する火災があり、それが検出されたと見なされます。 次の文は定理(プログラムの不変式)と見なすことができます。1日の終わりには、パトロールエリアの外側にあるものと最後のパトロールの開始後に発生したものだけが検出されない火災のままです。 しかし一方で、プログラムの動作を検証するのは記述されたテストです。 この例の後、テストのこの側面が明らかになると思います。



コードに対する集団的責任、ただしテストに対する個人的責任


チームとして働いているとき、私はしばしば怒りを覚えるか、次のようなことについて怒りを聞かなければなりませんでした。「あなたは私のコードに何を触ったのですか?!」 実際、このフレーズの意味は、コードが変更されたために誰かが気分を害するということではなく、コードを変更することで、コードの作成者が念頭に置いた不変式を暗黙的に変更したためです。 テストを使用すれば、この状況は簡単に回避できます。コード内にあるすべての不変式はテストコードに組み込まれます。 この場合、「一体何が私のテストに触れたのか!」という叫び声のみが聞こえます。これは、会社の憲章に他の人のテストを変更することを禁止することで取り除くことができます。 コードの変更を作成者と調整する必要がないため、このアプローチは柔軟性を高めます。 前の声明を念頭に置いて、このアプローチは何世紀にもわたって実践されてきたと言うことができます-例えば、ピタゴラスの定理など、多くの非名義的な証明がある名目上の定理があります。



All Articles