1

JUnit フレームワークを使用して、Java のプログラミング言語からインタープリターのテストを作成しています。この目的のために、テスト中の言語のコード スニペットを含む多数のテスト ケースを作成しました。これらのスニペットは通常小さいため、Java コードに埋め込むと便利です。ただし、Java は複数行の文字列リテラルをサポートしていないため、エスケープ シーケンスと長い文字列リテラルを分割する必要があるため、コード スニペットが少しわかりにくくなります。次に例を示します。

String output = run("let a := 21;\n" +
                    "let b := 21;\n" +
                    "print a + b;");
assertEquals(output, "42");

理想的には、次のようなものが欲しいです:

String output = run("""
    let a := 21;
    let b := 21;
    print a + b;
""");
assertEquals(output, "42");

考えられる解決策の 1 つは、コード スニペットを外部ファイルに移動し、対応するテスト ケースから各ファイルを参照することです。ただし、これによりメンテナンスの負担が大きくなります。

もう 1 つの解決策は、複数行の文字列リテラルをサポートする Scala や Jython などの別の JVM 言語を使用してテストを作成することです。これにより、プロジェクトに新しい依存関係が追加され、既存のテストを移植する必要があります。

メンテナンスをあまり追加せずに、テスト コード スニペットの明瞭さを維持する他の方法はありますか?

4

3 に答える 3

1

テストケースをファイルに移動することは、過去に私のために働いていました、それは通訳でもありました:

  1. 解釈されるスニペットと期待される結果を含むXMLファイルを作成しました。これはかなり単純なXML定義でありtestID、主に、、、、、およびを含むテスト要素のリストでした。valueexpected resulttypedescription
  2. ファイルを読み取り、その内容をループするJUnitテストを1つだけ実装しました。失敗した場合は、testIDとを使用してdescription失敗したテストをログに記録しました。

これは主に、runメソッドのようなインタープリターへの一般的な明確に定義されたインターフェイスが1つあるために機能し、リファクタリングは引き続き可能でした。私たちの場合、これによってメンテナンスの労力が増えることはありませんでした。実際、XMLファイルに要素を追加するだけで、新しいテストを簡単に作成できました。

ユニットテストを使用するのに最適な方法ではないかもしれませんが、私たちにとってはうまくいきました。

于 2011-10-09T07:11:04.187 に答える
1

他のJVM言語について話しているので、Groovyを検討しましたか?外部依存関係を追加する必要がありますが、コンパイル/テスト時にのみ(本番パッケージに入れる必要はありません)、複数行の文字列を提供します。そして、あなたの場合の1つの大きな利点は、その構文がJavaと下位互換性があることです(つまり、テストを書き直す必要がありません)。

于 2011-10-09T07:16:30.013 に答える
1

私は過去にこれをしました。ホームで提案されたものと同様のことを行いました。テストとその期待される結果を含む外部ファイルを使用しましたが、 @Parameterized テストランナーを使用しました。

@RunWith(Parameterized.class)
public class ParameterTest {
    @Parameters
    public static List<Object[]> data() {
        List<Object[]> list = new LinkedList<Object[]>();
        for (File file : new File("/temp").listFiles()) {
            list.add(new Object[]{file.getAbsolutePath(), readFile(file)});
        }

        return list;
    }

    private static String readFile(File file) {
        // read file 
        return "file contents";
    }

    private String filename;
    private String contents;

    public ParameterTest(String filename, String contents) {
        this.filename = filename;
        this.contents = contents;
    }

    @Test
    public void test1() {
        // here we test something
    }

    @Test
    public void test2() {
        // here we test something
    }
}

ここでは、ファイル名のパラメーターとファイルの内容を使用して、/temp 内の各ファイルに対してtest1()&を 1 回実行しています。test2()テスト クラスはインスタンス化され、@Parameters で注釈が付けられたメソッドのリストに追加する項目ごとに呼び出されます。

このテスト ランナーを使用すると、失敗した場合に特定のファイルを再実行できます。ほとんどの IDE は、失敗した単一のテストの再実行をサポートしています。@Parameterized の欠点は、名前が Eclipse JUnit プラグインに表示されるようにテストを適切に識別する方法がないことです。得られるのは 0、1、2 などだけです。ただし、少なくとも失敗したテストを再実行できます。

ホームが言うように、失敗したテストを正しく識別し、特に IDE の外部で実行する場合にデバッグを支援するために、適切なログ記録が重要です。

于 2011-10-10T21:25:51.737 に答える