2016-08-03 5 views
2

私は素晴らしいライブラリーを作成したいので、AbstractProcessorクラスに依存するライブラリーを作成しています。 プリプロセッサはコンパイル時に動作するので、そのコードのテスト方法がわかりません。AbstractProcessorのテスト(コンパイル時のJavaの注釈処理)

ビルドが失敗するテストシナリオがあります。しかし、私はそれをどのようにテストできますか? gradleを実行して終了コードを確認する必要がありますか?予想される原因によってビルドが失敗するかどうかを検証するためのきれいな方法がありますか、また何らかのパーサーを記述する必要がありますか?それはIMHOだけで良いカバー範囲のための巨大なオーバーヘッドになります。例を必要としているあなたのそれらのため

@SupportedAnnotationTypes("eu.rekisoft.java.preprocessor.Decorator") 
@SupportedSourceVersion(SourceVersion.RELEASE_7) 
public class ExamplePreprocessor extends AbstractProcessor { 

    public ExamplePreprocessor() { 
     super(); 
    } 

    @Override 
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 
     for(Element elem : roundEnv.getElementsAnnotatedWith(Decorator.class)) { 
      Method method = Method.from((ExecutableElement)elem); 
      if(!method.matchesTypes(String.class, StringBuilder.class)) { 
       processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "No! " + elem + " has the wrong args!"); 
      } else { 
       processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Yey " + elem + " this is fine!"); 
      } 
     } 
     return true; // no further processing of this annotation type 
    } 
} 

そして、ここでは、コンパイルされていないことができクラスです。

public class AnnotationedExample { 
    @Decorator 
    public int breakBuild() { 
     return -1; 
    } 

    @Decorator 
    public String willCompile(StringBuilder sb) { 
     return null; 
    } 
} 

そして最後に退屈な注釈:

@Retention(RetentionPolicy.SOURCE) 
@Target(ElementType.METHOD) 
public @interface Decorator { 
} 

GitHubでプロジェクトをチェックアウトし、プロジェクトをチェックアウトして01を実行するだけで済みます。。あなたは、linuxとmacのスクリプトに対する不足しているxの権限を修正しなければならないかもしれません。

+0

これまでに作成したコードとテストシナリオを共有してください。何が問題なの? –

+0

ちょうど私が何について話しているのか知りたいですか?それは非常に複雑なトピックであり、あなたがそれに慣れていれば、私の質問の抽象的なレベルはうまくいくはずです。しかし、これにより明確になる場合は、例を追加することができます。 – rekire

+0

@RobertColumbiaここでは、意図したとおりにコンパイルできない簡単なサンプルプロジェクトを紹介します。https://github.com/rekire/AnnotationTestingプロジェクトをチェックアウトし、 'gradlew cJ'を実行するだけです。スクリプトのx権限がありません。 – rekire

答えて

1

この問題は、以前のチームがコンパイラとアノテーションプロセッサを作成することで解決されているため、ソリューションを再利用できます。

javacチームはjtregというツールを使用します。 たとえば、jtreg testは、ソースファイルを異なるコマンドライン引数で6回コンパイルします。これは、それぞれ異なるexpected compiler outputを示します。

Checker Frameworkチームは、注釈プロセッサ専用のテストフレームワークを設計しました。このフレームワークを使用するtest caseがあります。//::のコメントは、注釈プロセッサがa warningまたはan errorを発行する予定の行を示しています。

+0

私はそのjtregライブラリを使用しようとしていますが、使用方法は分かりません。私はgrad内でjtregをチューニングしようとしています。今は 'java -Dprogram = jtreg -jar/tmp/jtreg/lib/jtreg.jar'を実行できますが、どのような引数を適用する必要がありますか?その '@ Compile'コメントは新しいコンパイルプロセスをどのように開始しますか?私はまったくそれを得ていない。 – rekire

+0

さて、私はそれが今管理されていると思いますが、私の参照ファイルは一致しません。ファイルの正確な形式を調べるにはどうすればよいですか?ちょうど期待されるエラー出力? – rekire

+0

はい、jtregは、目標ファイルと一致するようにコンパイラ出力を必要とします。 jtregは出力を賢明に解析しようとしません。jtregの実行方法については、jtregのドキュメントを参照することをお勧めします。 – mernst

1

Googleは、コンパイルをテストするための非常に優れたAPIを提供しています。 (https://github.com/google/compile-testing)。以下は、.javaファイルがjunitを使用するプロセッサでコンパイルされているかどうかをテストする例です。

package org.coffeebag.processor; 

import com.google.testing.compile.JavaFileObjects; 
import com.google.testing.compile.JavaSourceSubjectFactory; 
import org.junit.Test; 

import java.io.File; 
import java.net.MalformedURLException; 

import static org.truth0.Truth.ASSERT; 

public class ExampleTest { 

    @Test 
    public void EmptyClassCompiles() throws MalformedURLException { 
     final MyProcessor processor = MyProcessor.testMode(); 
     File source = new File("path/to/test/file.java"); 
     ASSERT.about(JavaSourceSubjectFactory.javaSource()) 
       .that(JavaFileObjects.forResource(source.toURI().toURL())) 
       .processedWith(processor) 
       .compilesWithoutError(); 
    } 
} 
関連する問題