JavaRush /Java Blog /Random-JA /JavaRush 用の JUnit または自宅でのテストについて少し。
Sdu
レベル 17

JavaRush 用の JUnit または自宅でのテストについて少し。

Random-JA グループに公開済み
タスクを確認するためにコンソールにテストデータを何十回も入力することにうんざりしていませんか? 猫へようこそ。猫を使って何ができるか説明します。 この教材の最終的な目標は、ソース コードを変更せずに、さまざまなパラメーターを使用して解決されるタスクの起動と結果の確認を自動化することです。タイトルからすでにお分かりかと思いますが、このかなり単純な問題の主なアシスタントは JUnitです。 単体テスト単体テストについてまだ聞いたことがない場合は、少し休憩してこれらの概念に慣れることをお勧めします。幸いなことに、インターネットには十分な情報があります。いいえ、したくないですか?まあ、何が起こっているのかを理解する上で、これは大きな問題にはならないと思います。結局のところ、テストとテスト一般が何であるか知っていますか? タスクを起動するたびにこれを実行し、初期データを入力し、結果の結果を期待した結果と比較します。
こんにちは、世界のJUnit!
JUnitとは何ですか? プロジェクトの公式ウェブサイトでは、次の説明を読むことができます。
JUnit は、反復可能なテストを作成するためのシンプルなフレームワークです。これは、単体テスト フレームワークの xUnit アーキテクチャのインスタンスです。
私たちにとって、これは、プログラムと対話するメソッドを備えた特別に設計されたクラスを記述し、結果と参照結果を比較し、一致しない場合は通知する機能を意味します。原理を理解するために、簡単な例を考えてみましょう。補助クラスがあり、そのメソッドの 1 つが int型の 2 つの変数を受け取り、その合計を返すとします。 JavaRush 用の JUnit または自宅でのテストについて少し。 - 1 これがテストしようとする機能です。幸いなことに、私たちのお気に入りの IDEA には、テストをすばやく作成するために必要なものがすべて揃っています。必要なのは、クラス宣言行にカーソルを置き、「Alt + Enter」を押して、コンテキスト メニューで「テストの作成」を選択することだけです JavaRush 用の JUnit または自宅でのテストについて少し。 - 2 。テストを作成する必要があります。IDEA は、テスト ライブラリ (この資料では JUnit4 を使用します。ライブラリ クラスをプロジェクトに接続するには、[修正] ボタンをクリックする必要があります)、テストするメソッド、および追加の選択を提案します。オプション。 JavaRush 用の JUnit または自宅でのテストについて少し。 - 3 IDE はテスト クラス テンプレートを作成します。 ClassName = TestClassName + "Test" MethodName = "test" + TestMethodName JavaRush 用の JUnit または自宅でのテストについて少し。 - 4 メソッド本体を入力するだけです。 JUnit が提供するいわゆる「アサーション」メソッドがこれに役立ちます。単純化すると、その作業は次のようになります: 期待される結果と、テスト対象のメソッドの呼び出し結果が .assert* メソッドに渡されます。便宜上、最初のパラメーターとして説明メッセージを追加できます。テスト中にパラメータが一致しない場合は、そのことが通知されます。通常のクラスと同じようにテスト クラスを起動して実行できます。私は Ctrl+Shift+F10 キーの組み合わせを使用することを好みます。 JavaRush 用の JUnit または自宅でのテストについて少し。 - 5
タスクを指定しましょう
理論的には、すべてがシンプルで美しいですが、提案された例のコンテキストでは、それは実際には必要ではなく、コンピューターが 2 つの数値を加算することを信頼できます。私たちは、JavaRush の学生が解決した実際の問題がどうなるかにもっと興味があります。たとえば、人気の level05.lesson12.bonus03 を取ることをお勧めします。
/* アルゴリズムの問​​題 次のようなプログラムを作成します。 1. コンソールから数値 N > 0 を入力します。 2. 次に、コンソールから N 数値を入力します。 3. 入力された N 数値の最大値を表示します。*/
正の数、負の数、および混合セットに対する 3 つのテストを作成する必要があります。
さらに森の奥へ・・・
ここでいくつかの驚きが私たちを待っています。 public class UtilApp { public static void main(String[] args) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); //напишите здесь ваш code int n; int maximum; /* Конечно же я не буду размещать решение задачи ;) Код приведенный тут переработан для наглядности, и не в коем случае не означает что он должен присутствовать в "правильном решении" */ System.out.println(maximum); } }
  • プログラムロジックは main() メソッドに配置されます
  • ソース データはメソッドには渡されませんが、キーボードから入力されます。
  • main() メソッドは結果を返しませんが、結果をコンソールに出力します。
最初の点に特に問題がない場合 (通常どおり main() メソッドを呼び出すことができます)、次の 2 点ではトピックをさらに深く掘り下げる必要があり、頭を悩ませます。この問題に対するいくつかの解決策を見つけました。
  1. 最大値を見つけるロジックを別のメソッドに移動します。
    • 長所:リファクタリングの観点からは正しいアプローチ
    • 短所:プログラムはコードや不要な構造で肥大化し、少なくとも配列または ArrayList が追加されます (好みや色によって異なります...)。最大値を見つけるメカニズムのみがテストされ、データの入力と出力はチェックされません。
  2. System.in/System.out のラッパーを作成します。
    • 長所:サードパーティのライブラリは使用しません。
    • 短所:この道は初心者向けではありません。テスト実装の相対的な複雑さ。テスト内のコードの量は、テスト対象のタスクよりも多くなる可能性があります。
  3. テスト用の追加ライブラリの使用。
    • 長所:テスト内のコードがきれいで、テストの作成が比較的簡単です。テスト対象クラスのソースコードは変更されません。
    • 短所:サードパーティのライブラリをプロジェクトに接続する必要があります。
正直に言うと、私は 3 番目のオプションが最も気に入ったので、それを実装してみます。
システムルール
簡単な検索でhttp://stefanbirkner.github.io/system-rules/ というページにたどり着き、これが私に必要なものであることがすぐにわかりました。
java.lang.System を使用するコードをテストするための JUnit ルールのコレクション。
それでは、 ライブラリをダウンロードしましょうシステム ルールが機能するために必要なCommons IOライブラリをダウンロードします。両方のライブラリをプロジェクトに接続し (ファイル -> プロジェクト構造 -> ライブラリ -> + -> Java)、スカルプトを開始します。 起動後、タスクはコンソールから N+1 個の数字を入力するように求めます。最初の数字がそれを示します。どれだけの数字が彼に続くだろうか。システム ルールでは、TextFromStandardInputStream クラスがこれらの目的に使用されます。最初に、このタイプのフィールドをテスト クラスに追加し、 @Rule アノテーションでマークする必要があります。次に、 @Rule public final TextFromStandardInputStream systemInMock = emptyStandardInputStream(); テスト メソッド内で直接、必要なデータを指定します。 systemInMock.provideText("4\n2\n6\n1\n3\n"); ご覧のとおり、数値はテキスト形式で送信され、ハイフン文字列「\n」で区切られています。これに基づいて、N は 4 に等しいことがわかり、数値 {2, 6, 1, 3} から最大値を探します。次に、テスト対象のクラスのインスタンスを作成し、main() メソッドを呼び出す必要があります。私たちのプログラムは systemInMock からデータを読み取り、処理して結果を出力します。必要なのは、それを読み取って標準と比較することだけです。これを行うために、システム ルールは StandardOutputStreamLog クラスを提供します。指定されたタイプのフィールドを追加します。 @Rule public final StandardOutputStreamLog log = new StandardOutputStreamLog(); .getLog() メソッドを使用して出力されたデータを読み取ることができますが、改行文字の存在を考慮する必要がありますが、最終的なオプションは次のようになります assertEquals("{2, 6, 1, 3}, max = 6", "6", log.getLog().trim()); // or assertEquals("{2, 6, 1, 3}, max = 6", "6\r\n", log.getLog()); 。データの階層化を避けるには、ログをクリアする必要があります。 log.clear(); 私のテスト クラスの全文: import org.junit.Rule; import org.junit.Test; import org.junit.contrib.java.lang.system.StandardOutputStreamLog; import org.junit.contrib.java.lang.system.TextFromStandardInputStream; import static org.junit.Assert.*; import static org.junit.contrib.java.lang.system.TextFromStandardInputStream.emptyStandardInputStream; public class UtilAppTest { @Rule public final TextFromStandardInputStream systemInMock = emptyStandardInputStream(); @Rule public final StandardOutputStreamLog log = new StandardOutputStreamLog(); @Test public void testAddition() throws Exception { systemInMock.provideText("4\n2\n6\n1\n3\n"); UtilApp utilApp = new UtilApp(); utilApp.main(new String[]{}); assertEquals("{2, 6, 1, 3}, max = 6", "6", log.getLog().trim()); systemInMock.provideText("5\n-100\n-6\n-15\n-183\n-1\n"); log.clear(); utilApp.main(new String[]{}); assertEquals("{-100, -6, -15, -183, -1}, max = -1", "-1", log.getLog().trim()); systemInMock.provideText("3\n2\n0\n-1\n"); log.clear(); utilApp.main(new String[]{}); assertEquals("{2, 0, -1}, max = 2", "2", log.getLog().trim()); } } 起動して楽しんでいます。 -=!!! 重要!!!=- この資料は情報提供のみを目的として提供されており、タスクのパッケージ内に無関係なクラスが存在する場合、サーバー上でのタスクのテストが成功することは保証されません。検証用のタスクをサーバーに送信する前に、不要なファイル、不要なクラス、コメントアウトされたコードなど、無関係なものをすべて削除してください。作成したテストが正常に完了しても、サーバー上のテストが正常に完了することは保証されません。単体テストの理論、JUnit アノテーション、アサートなど、理論的な内容については意図的に理解していませんでした。すべての内容は本文中に提供されているリンクにあります。おそらく、タスクをテストする独自の方法があるかもしれません。コメントで喜んで議論させていただきます。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION