132

を使用する状況を本当に理解できませんか?

単純なアプリケーションを作成する場合でも、より大きなアプリケーションを作成する場合でも、System.outステートメントを使用してそれらをテストすると、非常に簡単に実行できます。

同じメソッドを呼び出し、それらが返すものを確認し、すべてに注釈を付けるオーバーヘッドがある場合、プロジェクトに不要なフォルダーであるJUnitを使用してテストクラスを作成するのはなぜですか?

クラスを作成し、テストクラスを作成せずにすぐにテストしてみませSystem.outんか?

PS。私はただ学んでいる大規模なプロジェクトに取り組んだことがありません。

では、目的は何ですか?

4

11 に答える 11

148

それはテストではなく、「出力を手動で見る」ことです (業界では LMAO として知られています)。より正式には、「異常な出力を手動で探す」(LMFAO) として知られています。(以下の注を参照)

コードを変更するたびに、それらの変更の影響を受けるすべてのコードに対してアプリと LMFAO を実行する必要があります。小規模なプロジェクトであっても、これは問題があり、エラーが発生しやすくなります。

コードを変更するたびに、50k、250k、1m LOC 以上、および LMFAO にスケールアップします。不快なだけでなく、不可能です。入力、出力、フラグ、条件の組み合わせを拡大したため、考えられるすべての分岐を実行することは困難です。

さらに悪いことに、LMFAO は、Web アプリのページにまたがるページにアクセスすること、レポートを実行すること、数十のファイルやマシンにまたがる何百万ものログ行を調べること、生成および配信された電子メールを読むこと、テキスト メッセージをチェックすること、ロボットのパスをチェックすること、ソーダ、100 の Web サービスからのデータの集約、金融取引の監査証跡のチェックなど...おわかりでしょう。「出力」とは、数行のテキストを意味するのではなく、「出力」とはシステムの動作を集約することを意味します。

最後に、単体テストと動作テストはシステムの動作を定義します。継続的インテグレーション サーバーでテストを実行し、正確性をチェックできます。もちろん、そうすることができSystem.outますが、CI サーバーはそれらの 1 つが間違っているかどうかを認識しません。

私たちがどれだけ優れていると思っていても、人間は単体テスト フレームワークや CI サーバーとしては優れていません。


注: LMAOテスト中ですが、非常に限定的な意味です。プロジェクト全体またはプロセスの一部として、意味のある方法で繰り返すことはできません。これは、REPL でインクリメンタルに開発することに似ていますが、それらのインクリメンタル テストを形式化することはありません。

于 2012-06-02T00:56:35.343 に答える
51

プログラムの動作の正確性を検証するためのテストを作成します。

出力ステートメントの内容を目で調べてプログラムの動作の正確性を検証することは、マニュアル、より具体的には視覚的なプロセスです。

あなたはそれを主張することができます

目視検査が機能し、これらのシナリオでコードが意図したとおりに動作することを確認し、それが正しいことが確認できたら、準備完了です。

まず最初に、コードが正しく動作するかどうかに関心を持っていただければ幸いです。それはいい。あなたは時代を先取りしています!残念ながら、これにはアプローチとしての問題があります。

目視検査の最初の問題は、コードの正確性を二度と確認できないどころか、悪い溶接事故になることです。

2つ目の問題は、使用される一対の目が、目の所有者の脳と密接に結合していることです。コードの作成者が目視検査プロセスで使用される目を所有している場合、正確性を検証するプロセスは、目視検査者の脳に内在化されたプログラムに関する知識に依存します。

元のコーダーの頭脳と提携していないという理由だけで、新しい一対の目が入ってコードの正しさを検証することは困難です. 2 番目の目の所有者は、問題のコードを完全に理解するために、コードの元の作成者と会話する必要があります。知識を共有する手段としての会話は、信頼できないことで有名です。元のコーダーが新しいペアアイに利用できない場合、議論の余地があるポイント. その場合、新しい目は元のコードを読まなければなりません。

単体テストでカバーされていない他の人のコードを読むことは、単体テストに関連するコードを読むことよりも困難です。他人のコードを読むのは良くてもトリッキーな作業ですが、最悪の場合、これはソフトウェア エンジニアリングで最も厄介な作業です。雇用主が求人を宣伝するとき、プロジェクトがグリーンフィールド (またはまったく新しい) であることを強調するのには理由があります。コードをゼロから作成することは、既存のコードを変更するよりも簡単であるため、宣伝されている仕事が潜在的な従業員にとってより魅力的に見えるようになります。

単体テストでは、コードを構成要素に分割します。次に、コンポーネントごとに、プログラムがどのように動作するかを示すストールを設定します。各単体テストは、プログラムのその部分が特定のシナリオでどのように動作するかのストーリーを伝えます。各単体テストは、クライアント コードの観点から何が起こるべきかを記述するコントラクトの句のようなものです。

これは、新しい目で、問題のコードに関するライブで正確なドキュメントの2 つのストランドがあることを意味します。

最初に、コード自体、実装、コードがどのように作成されたかを確認します。2 番目に、元のコーダーが、このコードがどのように振る舞うべきかというストーリーを伝える一連の正式なステートメントで記述したすべての知識を持っています。

単体テストは、元の作成者がクラスを実装したときに持っていた知識を取り込み、正式に記述します。それらは、クライアントによって使用されたときにそのクラスがどのように動作するかについての説明を提供します。

役に立たない、問題のコードのすべてをカバーしていない、古くなったり古くなったりする単体テストを作成する可能性があるため、これを行うことの有用性を疑問視するのは正しいことです。単体テストが、実行時にコードの出力ステートメントを視覚的に検査する、知識があり良心的な作成者のプロセスを模倣するだけでなく、改善するようにするにはどうすればよいでしょうか? 最初に単体テストを作成してから、そのテストに合格するコードを作成します。完了したら、コンピューターにテストを実行させます。コンピューターは高速で、繰り返しのタスクを実行するのに優れており、仕事に最適です。

テストするコードに手を加えるたびにレビューし、ビルドごとにテストを実行することで、テストの品質を確保します。テストが失敗した場合は、すぐに修正してください。

プロジェクトのビルドを行うたびにテストが実行されるように、テストの実行プロセスを自動化します。また、テストによってカバーおよび実行されたコードの割合を詳細に示すコード カバレッジ レポートの生成も自動化します。高いパーセンテージを目指しています。一部の企業は、コードの動作の変更を記述する十分な単体テストを作成していない場合、コードの変更がソース コード管理にチェックインされないようにします。通常、2 人目の担当者が、変更の作成者と協力してコードの変更を確認します。レビュー担当者は変更を確認し、変更が理解しやすく、テストで十分にカバーされていることを確認します。レビュープロセスは手動です ただし、テスト (単体テストと統合テスト、場合によってはユーザー受け入れテスト) がこの手動レビュー プロセスに合格すると、自動ビルド プロセスの一部になります。これらは、変更がチェックインされるたびに実行されます。サーバーは、ビルド プロセスの一部としてこのタスクを実行します。

自動的に実行されるテストは、コードの動作の整合性を維持し、コード ベースへの将来の変更によってコードが壊れるのを防ぐのに役立ちます。

最後に、テストを提供することで、コードを積極的にリファクタリングできますこれは、変更によって既存のテストが壊れないことがわかっているため、大きなコードの改善を安全に行うことができるためです。

テスト駆動開発には注意点があります。それは、コードをテスト可能にすることを念頭に置いてコードを作成する必要があるということです。これには、インターフェイスへのコーディングと、依存性注入などの手法を使用して連携オブジェクトをインスタンス化することが含まれます。TDD を非常によく説明しているKent Beckの作品をチェックしてください。インターフェイスへのコーディングを参照し、を研究する

于 2012-06-02T13:51:59.937 に答える
13

System.out のようなものを使用してテストする場合、可能なユースケースの小さなサブセットのみをテストしています。ほぼ無限の異なる入力を受け入れる可能性のあるシステムを扱っている場合、これはあまり完全ではありません。

単体テストは、非常に大規模で多様なさまざまなデータ入力セットを使用して、アプリケーションでテストをすばやく実行できるように設計されています。さらに、最適な単体テストでは、有効と見なされるものの境界にあるデータ入力などの境界ケースも考慮されます。

人間がこれらのさまざまな入力をすべてテストするには数週間かかる場合がありますが、機械では数分かかる場合があります。

次のように考えてください。また、静的なものを「テスト」していません。あなたのアプリケーションは、常に変化している可能性が高いです。したがって、これらの単体テストは、コンパイルまたは展開サイクルのさまざまな時点で実行するように設計されています。おそらく最大の利点は次のとおりです。

コードで何かを壊した場合、デプロイ後ではなく、QA テスターがバグを発見したときでも、クライアントがキャンセルしたときでもなく、すぐにそれを知ることができます。問題のコードの部分を壊したことが最後のコンパイル以降に発生した可能性が最も高いことは明らかであるため、グリッチをすぐに修正する可能性も高くなります。したがって、問題を修正するために必要な調査作業の量が大幅に削減されます。

于 2012-06-02T00:57:12.703 に答える
9

単体テストは、コードが意図したとおりに機能することを保証します。また、バグを修正するために新しい機能を構築するために後でコードを変更する必要がある場合に備えて、コードが意図したとおりに機能することを確認するのにも非常に役立ちます。コードのテスト カバレッジが高いと、多くの手動テストを実行しなくても、機能の開発を続けることができます。

手動によるアプローチSystem.outは優れていますが、最善の方法ではありません。これは、実行する 1 回限りのテストです。現実の世界では、要件は変化し続けており、ほとんどの場合、既存の関数やクラスに多くの変更を加えています。だから… すでに書かれたコードを毎回テストするわけではありません。

JUnitには、次のようないくつかのより高度な機能もあります

アサート ステートメント

JUnit は、特定の条件をテストするメソッドを提供します。これらのメソッドは通常、アサートで始まり、エラー メッセージ、予想される結果、および実際の結果を指定できます。

これらの方法のいくつかは、

  1. fail([message])- テストを失敗させます。コードの特定の部分に到達していないことを確認するために使用される場合があります。または、テストコードが実装される前にテストに失敗する。
  2. assertTrue(true)/ assertTrue(false)- 常に true / false になります。テストがまだ実装されていない場合は、テスト結果を事前定義するために使用できます。
  3. assertTrue([message,] condition)- ブール値conditionが true であることを確認します。
  4. assertEquals([message,] expected, actual)- 2 つの値が等しいかどうかをテストします (実装されているequals場合はメソッドに従い、実装されていない場合は==参照比較を使用します)。注: 配列の場合、チェックされるのは参照であり、そのために使用される内容ではありませんassertArrayEquals([message,] expected, actual)
  5. assertEquals([message,] expected, actual, delta)- 2 つの float 値または double 値が、値によって制御されて、互いに一定の距離にあるかどうかをテストしdeltaます。
  6. assertNull([message,] object)- オブジェクトが null であることを確認します

等々。すべての例については、こちらの完全な Javadoc を参照してください。

スイーツ

テスト スイートを使用すると、ある意味で、複数のテスト クラスを 1 つのユニットに結合できるため、一度にすべてを実行できます。テスト クラスを組み合わせてMyClassTestというMySecondClassTest名前の 1 つのスイートにする簡単な例AllTests:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({ MyClassTest.class, MySecondClassTest.class })
public class AllTests { } 
于 2013-02-26T05:50:01.427 に答える
9

System.out が実行できない他のいくつかを追加しました。

  • 各テストケースを独立させる(重要)

    @BeforeJUnit はそれを行うことができます: 新しいテスト ケース インスタンスが作成され、呼び出されるたびに。

  • テスト コードをソースから分離する

    JUnitはそれを行うことができます。

  • CIとの統合

    JUnit は Ant と Maven でそれを行うことができます。

  • テスト ケースの配置と結合が容易

    JUnit は@Ignoreスイートを実行およびテストできます。

  • 簡単に結果を確認

    JUnit には多くの Assert メソッド ( assertEqualsassertSame...)が用意されています。

  • モックとスタブを使用すると、テスト モジュールに集中できます。

    JUnit でできること: モックとスタブを使用すると、正しいフィクスチャをセットアップし、テスト モジュール ロジックに集中できます。

于 2012-06-03T00:44:24.683 に答える
6

JUnit の主な利点は、プリントアウトを手動で確認する必要がなく、自動化されていることです。作成した各テストは、システムに残ります。これは、予期しない副作用を伴う変更を行った場合、変更のたびに手動ですべてをテストすることを覚えておく必要がなく、テストがそれをキャッチして失敗することを意味します。

于 2012-06-02T00:56:44.713 に答える
1

テスト フレームワークを使用せずにテスト ケースを作成することはできません。そうしないと、テスト ケースを正当化するためにテスト フレームワークを作成する必要があります。TestNG フレームワークを使用できることとは別に、JUnit フレームワークに関する情報を次に示します。

ジュニットとは?

Junit は、Java プログラミング言語とともに広く使用されているテスト フレームワークです。この自動化フレームワークは、単体テストと UI テストの両方に使用できます。さまざまなアノテーションを使用してコードの実行フローを定義するのに役立ちます。Junit は、テストケースの生産性とコードの安定性を高めるのに役立つ「最初にテストしてからコーディングする」という考え方に基づいて構築されています。

Junit テストの重要な機能 -

  1. これはオープン ソースのテスト フレームワークであり、ユーザーはテスト ケースを効果的に記述して実行できます。
  2. テスト メソッドを識別するためのさまざまな種類の注釈を提供します。
  3. テスト ケースの実行結果を検証するために、さまざまな種類のアサーションを提供します。
  4. また、テストを効果的に実行するためのテスト ランナーも提供します。
  5. これは非常に単純であるため、時間を節約できます。
  6. テスト ケースをテスト スイートの形式で編成する方法を提供します。
  7. シンプルかつエレガントな方法でテストケースの結果を提供します。
  8. jUnit を Eclipse、Android Studio、Maven & Ant、Gradle、Jenkins と統合できます
于 2016-09-14T05:21:21.910 に答える
0

JUNIT は、Java 開発者が通常受け入れるメソッドです。同様の期待される入力を関数に提供し、それに応じて記述されたコードが完全に記述されていると判断できる場合、またはテスト ケースが失敗した場合は、別のアプローチも実装する必要がある場合があります。JUNIT は開発を高速化し、機能の欠陥をゼロにします。

于 2014-09-16T11:21:11.033 に答える
0

JUNIT : 観察と調整

これが私のJUNITの見方です。

JUNIT は、
1) システムに新しいユニットが追加されたときのシステムの動作を観察するために使用できます。
2)システム内の「新しい」ユニットを歓迎するために、システム内で調整を行います。
何?丁度。

実生活。

親族があなたの大学の寮の部屋を訪れたとき、
1) あなたはもっと責任感のあるふりをします。
2) 靴は椅子の上ではなく靴箱に、衣類は椅子の上ではなく食器棚に収納するなど、すべてのものをあるべき場所に保管します。
3) 密輸品をすべて取り除きます。
4) 所有するすべてのデバイスで cleanUp を開始します。

プログラミング用語で

システム: あなたのコード
単位: 新しい機能。
JUNIT フレームワークは Java 言語に使用されるため、JUNIT = JAVA UNIT (かもしれません)。

すでに十分な防弾コードを持っているが、新しい要件が発生し、コードに新しい要件を追加する必要があるとします。この新しい要件により、一部の入力 (テストケース) でコードが壊れる可能性があります。

この変更を適応させる簡単な方法は、単体テスト (JUNIT) を使用することです。
そのためには、コードベースを構築するときに、コードに対して複数のテストケースを作成する必要があります。新しい要件が発生するたびに、すべてのテスト ケースを実行して、失敗するテスト ケースがないかどうかを確認します。「いいえ」の場合、あなたは BadA** アーティストであり、新しいコードをデプロイする準備ができています。
いずれかのテストケースが失敗した場合は、コードを変更して、緑色のステータスになるまでテストケースを再度実行します。

于 2017-08-05T11:05:07.013 に答える