2008.02.25 株式会社四次元データ 森
8. Maven2 プラグインの作成
- 8.1. プラグインの概要
- 8.2. プラグインの作成準備
- 8.3. プラグインの作成
- 8.4. プラグインのテスト
- 8.5. プラグインの配備及び実行
8.4. プラグインのテスト
ここでは前回作成した Maven2 プラグインのテストを実行してみます。
Maven プラグインのテストの実行方法は、大きく分けて三通り考えられます。
- Mojo クラスを実行し、その結果を評価する
- プラグインとして実行し、その結果を評価する
- Mojo クラスから処理を委譲されているクラスを実行し、その結果を評価する
どの方法を選択するかについては、そのプラグインが
「処理が Maven の環境にどれ位依存しているのか」によって変わってきます。
例えば、プロジェクトの依存関係を解析したり、ローカルレポジトリの情報を解析 したり、といった Maven の環境に強く依存しているケースについては、一番目 か二番目の 方法を選択する事になるでしょう。具体的にはプラグイン内で、MavenProject や MavenSettings, ArtifactRepository などを多用している場合です。
一番目か二番目の判断の分かれ目は、Mock を設定する事により十分にテスト出来る 場合には前者、Mock の作成自体が複雑になってしまう場合には後者といった点が ポイントになります。
また、Maven 環境への依存度が少ない場合、処理を Mojo クラスとは 別のクラスに委譲しておけば、そのクラスに対応する JUnit のテストケースを 記述すればよい、ということになります。 テストの観点から考えますと、作成したいプラグインの処理が Maven 環境に 強く依存しない場合には、処理を委譲するようなクラス設計にしておけば、 テストをしやすい形となります。
今回の例では Mojo クラスは pom.xml からのパラメータを読み取り、処理を委 譲しているだけなので、最初の方式でパラメータの受け渡しのみをチェックするような形とします。 委譲された CountExecuter.java は通常の Java クラスですので、JUnit のテストを行います。
テストの前の下準備としてテスト用の pom.xml をプラグインのプロジェクト配下 src/test/resources/countlines/pom.xml に配置します。プラグイン自身の pom.xml も依然として存在していますので混同しないように気をつけてください。
また、テストを行う Java クラスファイルは src/test/java 以下に今回の場合では com.example.maven.plugins というパッケージをつくり CountMojoTestCase.java としました。
8.4.1 Mojo オブジェクトの execute メソッド実行によるテスト
プラグインが正常動作するようにパラメータを当てて Mojo オブジェクトを直接実行できるように、まずはプラグイン本体、つまりプロジェクト直下の pom.xml に以下を記述します。
<dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-plugin-testing-harness</artifactId> <version>1.1</version> <scope>test</scope> </dependency>
ここで Maven2 のリポジトリ から最新の maven-plugin-testing-harness のバージョンを調べ、version タグ内に記述します。2008年2月現在は 1.1 が最新版となっています。
この記述により、AbstractMojoTestCase というクラスを利用することが出来ます。AbstractMojoTestCase でテスト用の pom.xml と、goal 名を指定することで、Mojo オブジェクトを以下のように取得することが可能になります。
File testPom = new File(getBasedir(),"src/test/resources/countlines/pom.xml"); CountlinesMojo mojo = (CountlinesMojo) lookupMojo("countlines", testPom); String dir = (String) getVariableValueFromObject(mojo, "dir"); String ext = (String) getVariableValueFromObject(mojo, "ext"); mojo.execute(); ...
lookupMojo ではテスト用の pom.xml より、Mojo オブジェクトを生成します。Mojo オブジェクト内のフィールドは上記を見ればわかるように getVariavleValueFromObject メソッドで取得します。このメソッドは private なフィールドであったとしても取得することができます。Mojo 実行後は assertEquals(expected,actual) メソッドなどを用いて、結果を比較することでテストが完了します。
この方法では、@parameter expression="${project}" などで指定したオブジェクトについては Mock ( maven-plugin-testing-harness では Stub という名前のクラス名が提供されています) を当てる事に注意します。maven-plugin-testing-harness では、MavenProject と Artifact 用に ArtifactStub, MavenProjectStub が提供されています。これらを利用するためには、テスト用の pom.xml のconfiguration タグ内に
<project implementation="org.apache.maven.plugin.testing.stubs.MavenProjectStub" />
と記述する必要があります。今回は Stub を用いることなくテスト用の pom.xml に
<plugin> <groupId>com.example.maven.plugins</groupId> <artifactId>maven-countlines-plugin</artifactId> <version>1.0-SNAPSHOT</version> <configuration> <dir>${basedir}</dir> <ext>jsp</ext> </configuration> </plugin> :
というようにしました。
アサーションの部分はたとえば以下のようになります。
String direxpected = new String("C\\workspace\\com\\example\\maven\\plugins"); assertEquals(direxpected, dir); String extexpected = "jsp"; assertEquals(extexpected, ext);
これによりテストを実行し、予想される挙動と結果が同じであれば、テストは成功となります。
8.4.2 Maven をそのまま実行することによるテスト
8.4.1 のテスト と同様に、このテストを実行する前にプロジェクト、つまりプラグイン本体に最初から存在する pom.xml に以下を記述します。
<dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-plugin-testing-tools</artifactId> <version>1.0-alpha-3</version> <scope>test</scope> </dependency>
同様に、Maven2 のリポジトリ から最新の maven-plugin-testing-tools のバージョンを調べ、version タグ内に記述します。2008年2月現在は 1.0-alpha-3 が最新版となっています。
Maven 経由の実行には、上記に含まれている BuildTool クラスを利用します。 BuildTool は setup で事前に取得しておくとよいでしょう。
private BuildTool buildTool; : protected void setUp() throws Exception { super.setUp(); buildTool = (BuildTool) lookup(BuildTool.ROLE, "default"); : }
テストメソッドは以下のようになります。
public void testExecute() { Properties cliProperties = new Properties(); List<String> goals = new ArrayList<String>(); goals.add("com.example.maven.plugins:maven-countlines-plugin:1.0-SNAPSHOT:countlines"); File buildLogFile = new File(getBasedir(),"target/test-classes/build.log"); try { :
などとして、実行結果に対しアサーションを行う必要があります。maven-plugin-testing-tools には他にも、pom.xml のファイルオブジェクトから MavenProject を作成する ProjectTool や、ArtifactRepository を作成する RepositoryTool も存在しています。
この方法ではコマンドラインにより Maven を実行するので、コードを変更した際、先にプラグインのインストールが必要になります。通常 Maven では install の前に test を実行しますので、Mojo クラスの実装を変更した場合はまず test をスキップしてローカルリポジトリにインストールします。
$ mvn -Dmaven.test.skip=true install $ mvn test
この後テストを実行します。
三番目の方法は単なる JUnit の単体テストですのでここでは割愛します。このようにさまざまな手法で Maven のテストを実行することができます。