web-dev-qa-db-ja.com

Javaアプリケーション内からJUnitテストを実行するにはどうすればよいですか?

Javaアプリケーションの内部からJUnitテストを実行することは可能ですか?

使用できるテストフレームワーク(JUnit.jarなど)がありますか、それともテストファイルを見つけてメソッドを呼び出し、例外を自分で追跡することを強制しますか?

私が尋ねる理由は、アプリケーションが起動を開始するのに多くの作業(依存関係や構成など)を必要とし、外部テストツール(JUnit Antタスクなど)を使用するとセットアップに多くの作業が必要になるためです。

アプリケーションを起動してから、アプリケーション内でテストを実行する方が簡単です。

テストを実行し、結果を出力する簡単なテストフレームワークはありますかJavaアプリケーションか、独自のフレームワークを書くことを強制されますか?

52
corgrath

はい、できます。実稼働システムで診断/煙テストを実行するために、それを数回行いました。これは、JUnitを呼び出すコードの主要部分のスニペットです。

JUnitCore junit = new JUnitCore();
Result result = junit.run(testClasses);

JUnit.mainをアプリケーション内で使用しないでください。テストが終了するとSystem.exitが呼び出されるため、JVMプロセスが停止する場合があります。

JUnitの「通常の」コンソール出力(ドットと単純なレポート)をキャプチャすることができます。これは、TextListenerを登録することで簡単に実行できます(このクラスはこの単純なレポートを提供します)。

また、この種の方法を使用する場合のいくつかの問題にも注意してください。

  1. 非常に小さなものを含め、「テストフレームワーク」のテストは非常に単純ですが、混乱を招く可能性があります。たとえば、テストの1つが失敗したときに「テストフレームワーク」が失敗の結果を返すかどうかをテストする場合、常に失敗するサンプルJUnitテストを作成し、「テストフレームワーク」でそのテストを実行できます。この場合、失敗したテストケースは実際にはテストデータであり、「通常の」JUnitとして実行しないでください。そのようなテストの例については、JUnitの内部テストケースを参照できます。

  2. カスタムレポートを準備/表示したい場合は、JUnitから返される結果に合格したテストとテストメソッドに関する情報が(直接)含まれていないため、独自のRunListenerを登録する必要があります。テストの一部Description)。

84
kopper

JUnitに記載されているとおり [〜#〜] faq [〜#〜]

public static void main(String args[]) {
  org.junit.runner.JUnitCore.main("junitfaq.SimpleTest");
}

私が尋ねる理由は、アプリケーションが起動を開始するのに多くの作業(依存関係や構成など)を必要とし、外部テストツール(JUnit Antタスクなど)を使用するとセットアップに多くの作業が必要になるためです。

テストするコードからこれらの依存関係を削除する必要があります。依存関係と構成は、テストフレームワークを記述するときに回避しようとしているものです。テストごとに、アプリケーションのテスト可能な最小の部分をターゲットにする必要があります。

たとえば、テストしようとしているクラスでプロセスを実行するためにデータベース接続が必要な場合-クラスからデータベース処理オブジェクトを分離し、コンストラクタまたはセッターメソッドを介して渡し、テストでJMockなどのツールを使用します(またはスタブクラスを記述して)偽のデータベース処理オブジェクトを構築します。このようにして、テストが特定のデータベース構成に依存しないことを確認し、データベース処理レイヤー全体ではなく、関心のあるコードの小さな部分のみをテストします。

最初は多くの作業のように思えるかもしれませんが、この種のリファクタリングは、テストフレームワークが具体化すべきものです。依存関係を切り離すためのリファレンスとして、ソフトウェアテストに関する本を入手すると役立つ場合があります。実行中のアプリケーション内からbootstrap JUnitを試みるよりもはるかに多くの成果が得られます。

10
seanhodges

JUnit 5では、この目標に Launcher API を使用できます。

    final LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
            .selectors(
                    selectPackage("path_to_folder_with_tests")
            )
            .build();

    final Launcher launcher = LauncherFactory.create();

    final boolean pathContainsTests = launcher.discover(request).containsTests()
    if (!pathContainsTests) {
        System.out.println("This path is invalid or folder doesn't consist tests");
    }

    final SummaryGeneratingListener listener = new SummaryGeneratingListener();

    launcher.execute(request, listener);

    final TestExecutionSummary summary = listener.getSummary();

    final long containersFoundCount = summary.getContainersFoundCount();
    System.out.println("containers Found Count  " + containersFoundCount);

    final long containersSkippedCount = summary.getContainersSkippedCount();
    System.out.println("containers Skipped Count  " + containersSkippedCount);

    final long testsFoundCount = summary.getTestsFoundCount();
    System.out.println("tests Found Count  " + testsFoundCount);

    final long testsSkippedCount = summary.getTestsSkippedCount();
    System.out.println("tests Skipped Count  " + testsSkippedCount);
5
makson

JUnit APIによると、JUnitCoreにはJava内でテストを実行するためのいくつかのメソッドがあります。

それを指摘してくれたTomislav Nakic-Alfirevicに感謝します。

http://junit.sourceforge.net/javadoc/org/junit/runner/JUnitCore.html

2
corgrath
Result result = JUnitCore.runClasses(classes);

http://junit.sourceforge.net/javadoc/org/junit/runner/JUnitCore.html#runClasses(Java.lang.Class ...) を参照してください