web-dev-qa-db-ja.com

テストにJUnitを使用する理由

私の質問は初心者のものかもしれませんが、 junit ?を使用する状況を本当に理解することはできません。

単純なアプリケーションを作成する場合でも、より大きなアプリケーションを作成する場合でも、System.outステートメントを使用してテストします。

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

クラスを作成して、System.outで一度にテストし、テストクラスを作成しないのはなぜですか?

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

それでは、目的は何ですか?

130
Artem Moskalev

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

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

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

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

最後に、ユニットと動作のテストdefineシステムの動作。テストは、継続的統合サーバーによって実行され、正確性を確認できます。もちろんSystem.outsもできますが、CIサーバーはそれらの1つが間違っているかどうかを知りません。もしそうなら、それらは単体テストであり、フレームワークを使用することもできます。

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


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

133
Dave Newton

プログラムの動作が正しいことを検証するテストを作成します。

eyesを使用して出力ステートメントの内容を検査することにより、プログラムの動作が正しいことを確認することは、manual、より具体的には、visualプロセス。

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

目視検査は機能します、これらのシナリオでコードが意図したとおりに動作することを確認し、正しいことが確認できたら行ってください。

最初に、コードが正常に動作するかどうかに興味があることは素晴らしいことです。それはいいことだ。あなたは曲線の先を行っています!悲しいことに、アプローチとしてこれには問題があります。

目視検査の最初の問題は、コードの正確性を再度確認できないことから離れて、悪い溶接事故であることです。

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

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

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

単体テストでは、コードをコンポーネント部分に分割します。次に、各コンポーネントについて、プログラムの動作の動作を示すストールを設定します。各ユニットテストは、プログラムのその部分が特定のシナリオでどのように動作するかについてのストーリーを伝えます。各ユニットテストは、クライアントコードの観点から何が起こるべきかを記述する契約の条項のようなものです。

これは、新しい目のペアが、問題のコードに関するtwoストランドlive and正確なドキュメントを持っていることを意味します。

まず、コード自体、実装、コードの実行方法があります。次に、元のコーダーがこのコードがどのように動作するかのストーリーを伝える一連の正式なステートメントで記述されているというすべての知識を持っています。

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

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

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

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

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

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

テスト駆動開発 には注意点があります。それは、テスト可能にするためにコードを記述する必要があるということです。これには、インターフェイスへのコーディングと、依存関係注入などの手法を使用したコラボレーションオブジェクトのインスタンス化が含まれます。 Kent Beck の仕事をチェックしてください。彼はTDDを非常によく説明しています。 インターフェイスへのコーディング を調べ、 design-patterns を調べます

50
Rob Kielty

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

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

人間がこれらの異なる入力をすべてテストするには数週間かかるのに対して、マシンでは数分かかる場合があります。

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

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

13
jmort253

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

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メソッドに従って、そうでない場合は==参照比較を使用)。注:配列の場合、チェックされるのは参照であり、notの内容では、assertArrayEquals([message,] expected, actual)を使用します。
  5. assertEquals([message,] expected, actual, delta)-2つのfloat値またはdouble値が、delta値によって制御される互いに特定の距離にあるかどうかをテストします。
  6. assertNull([message,] object)-オブジェクトがnullであることを確認します

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

スイート

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

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 { } 
9
Arvind

他にできないSystem.outをいくつか追加しました。

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

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

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

    JUnitでできます。

  • CIとの統合

    JUnitは、AntおよびMavenで実行できます。

  • テストケースを簡単に整理して結合

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

  • 結果の確認が簡単

    JUnitは多くのAssertメソッドを提供しています(assertEqualsassertSame...)

  • モックとスタブにより、テストモジュールに集中できます。

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

JUnitの主な利点は、印刷物を手動で確認するのではなく、自動化されることです。作成する各テストはシステムに残ります。これは、予期しない副作用を伴う変更を行うと、各変更後にすべてを手動でテストすることを忘れずに、テストがそれをキャッチして失敗することを意味します。

6
n00begon

JUnitは、Javaプログラミング言語の単体テストフレームワークです。テスト駆動開発では重要であり、xUnitと総称される単体テストフレームワークのファミリーの1つです。

JUnitは、「最初にテストしてからコーディングする」という考え方を推進しています。これは、最初にテストしてから実装できるコードのテストデータの設定に重点を置いています。このアプローチは、「少しテスト、少しコード、少しテスト、少しコード...」のようなもので、プログラマの生産性とプログラムコードの安定性を高め、プログラマのストレスとデバッグに費やす時間を削減します。

機能JUnitは、テストの記述と実行に使用されるオープンソースフレームワークです。

テストメソッドを識別するための注釈を提供します。

期待される結果をテストするためのアサーションを提供します。

テストを実行するためのテストランナーを提供します。

JUnitテストにより、コードをより速く記述でき、品質が向上します

JUnitはエレガントでシンプルです。それほど複雑ではなく、時間がかかりません。

JUnitテストは自動的に実行でき、独自の結果を確認してすぐにフィードバックを提供します。テスト結果のレポートを手動で確認する必要はありません。

JUnitテストは、テストケースやその他のテストスイートを含むテストスイートに編成できます。

Junitは、テストが正常に進行している場合は緑色で、テストが失敗すると赤色に変わるバーでテストの進行状況を示します。

4
AKKI

私は、JUnitが必要な理由について、わずかに異なる視点を持っています。

実際にすべてのテストケースを自分で作成できますが、面倒です。問題は次のとおりです。

  1. System.outの代わりにif(value1.equals(value2))を追加して、0または-1またはエラーメッセージを返すことができます。この場合、これらすべてのメソッドを実行し、結果をチェックし、失敗したテストケースと合格したテストケースを維持する「メイン」テストクラスが必要です。

  2. さらにテストを追加する場合は、この「メイン」テストクラスにもテストを追加する必要があります。既存のコードの変更。テストクラスからテストケースを自動検出する場合は、リフレクションを使用する必要があります。

  3. すべてのテストとテストを実行するメインクラスはEclipseによって検出されないため、これらのテストを実行するにはカスタムデバッグ/実行構成を記述する必要があります。ただし、これらのかなり緑色/赤色の出力は表示されません。

JUnitの動作は次のとおりです。

  1. 条件から有用なエラーメッセージを出力し、結果を「メイン」クラスに伝えるのに役立つassertXXX()メソッドがあります。

  2. 「メイン」クラスはランナーと呼ばれ、JUnitによって提供されるため、何も記述する必要はありません。そして、反射によってテストメソッドを自動的に検出します。 @Testアノテーションを使用して新しいテストを追加すると、それらは自動的に検出されます。

  3. JUnitにはEclipse統合とmaven/gradle統合もあるため、テストを簡単に実行でき、カスタム実行構成を記述する必要はありません。

私はJUnitの専門家ではないので、これは今のところ理解していることであり、今後さらに追加される予定です。

2
Sreekar

テストフレームワークを使用せずにテストケースを作成することはできません。テストフレームワークを作成して、テストケースに正義を与える必要があります。 TestNGフレームワークを使用できることとは別に、JUnitフレームワークに関する情報をいくつか紹介します。

Junitとは何ですか?

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

Junitテストの重要な機能-

  1. これは、ユーザーがテストケースを効率的に作成および実行できるようにするオープンソースのテストフレームワークです。
  2. テストメソッドを識別するためのさまざまな種類の注釈を提供します。
  3. テストケースの実行結果を検証するためのさまざまな種類のアサーションを提供します。
  4. また、テストランナーがテストを効果的に実行できるようにします。
  5. これは非常にシンプルであるため、時間を節約できます。
  6. テストスーツの形式でテストケースを整理する方法を提供します。
  7. テストケースの結果をシンプルでエレガントな方法で提供します。
  8. JUnitをEclipse、Android St​​udio、Maven&Ant、Gradle、およびJenkinsと統合できます。
1
anuja jain

JUNIT:観察および調整

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

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

実生活.

親relativeが大学のホステルの部屋を訪れると、
1)あなたはより責任があるふりをします。
2)椅子の上ではなく靴棚の中の靴、椅子の上ではなく食器棚の中の服など、必要なすべてのものを保管します。
3)密輸品をすべて取り除きます。
4)所有するすべてのデバイスでクリーンアップを開始します。

プログラミング用語で

システム:コード
UNIT:新しい機能。
JUNITフレームワークはJava言語に使用されるため、JUNIT = Java UNIT(可能性あり)。

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

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

0
Rohit Singh

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

0
mohit sarsar

単体テストは、ホワイトボックステスト方法を使用して実行されます。ホワイトボックステストは、アプリケーションの内部構造または動作をテストするソフトウェアをテストする方法です。

いつ実行されますか?単体テストはソフトウェアテストの最初のレベルであり、統合テストの前に実行されます。

https://onlyfullstack.blogspot.com/2019/02/junit-tutorial.html

https://onlyfullstack.blogspot.com/2019/02/what-is-junit-how-to-use-junit.html

0
Saurabh Oza