Eclipse:Java9モジュールシステムを使うと共にJUnitを使う方法
Eclipseで一応Java9モジュールシステムの開発をしてみようと思ったのだが、そこではたと気がついた。JUnitはどうすれば良いのだろうか?
以下ではEclipse 2019-06を対象とする。
問題
前提として以下がある。
- Eclipseでは、一つのプロジェクトは一つのモジュールにしかできない。module-info.javaは一つだけ。
- プロジェクト内にJUnitコードを含めたい。わざわざ別プロジェクトとしたくはない。
- しかしそうしてしまうと、module-info.javaにjunitが出現せざるをえなくなる。
- したがって、リリース時のmodule-info.classにもjunitが含まれてしまう。
- つまり、実行時にjunitが必要ということになってしまう。
具体的にどんな状況になるかだが、以下を作成してみる。
本体ソースはsrc下に、テストコードはtestというソースフォルダを作成して、その中に入れる。ソースは以下のような具合だ。
Main.java
package sample;
import java.sql.*;
import javax.swing.*;
public class Main {
public Main() {
Connection a;
JOptionPane b;
}
}
MainTest.java
package sample;
import org.junit.*;
public class MainTest {
@Test
public void test() {
}
}
そして、module-info.javaは
module sample {
requires java.sql;
requires java.desktop;
requires junit;
}
ライブラリは以下になっている。
この状態では、何をどうやろうが、module-info.javaからjunitをはずすことはできない。junitが正規の形で「このモジュール(sample)が必要とするもの」となってしまっているからだ。
解決策
これについての正式な文書や議論を見つけ出せないのだが、以下のようにすれば良いようだ。
- testソースフォルダを「テスト用」とマークし、コンパイル済バイナリの出力先を本体とは別にする。
- JUnitライブラリをモジュールパスではなく、クラスパスに入れる。
- module-info.javaからjunitを削除する
以下これをやってみる。
testソースフォルダを「テスト用」とマークする
ビルドパスを開くと以下になっているので、
「Contains test sources: No」になっているのをダブルクリックしてYesに変更する。
コンパイル済バイナリの出力先を本体とは別にする
上部に警告がでており、「テスト用にしたら別の出力先にしたいとだめだよ」と言っている。
そこで、下の「Allow output folders for source folders」をチェックし、sample/testのOutput folderをダブルクリックする。
このように適当な出力先を割り当てる。
Junitをクラスパスに入れる
モジュールパスにいれていたJUnitをクラスパスの方に変更する。
この時点でmodule-info.javaにエラーが発生していることがわかる。
module-info.javaからjunitを削除する
以下のエラーが発生しているので、junitを削除する。
.projectの状態
この単純な変更で生成された.projectは以下だ。
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="testout" path="test"> <!-- デフォルトとは別出力先 -->
<attributes>
<attribute name="test" value="true"/> <!-- テスト用ソースを示す -->
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="module" value="true"/> <!--モジュールパスにあることを示す -->
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
<!-- クラスパスにあることを示す -->
<classpathentry kind="output" path="bin"/> <!-- デフォルトの出力先 -->
</classpath>
まとめ
つまり、こういうことらしい。
- テストソースの出力先を本体とは別にすることにより、モジュールシステムの支配下に置かない
- JUnitをクラスパスに置くことにより、モジュールシステムの支配下に置かない。
- したがって、module-info.javaに書く必要なし。
- 各ユニットテストは、「クラスパスシステム」の下で動作する。
ということだ。
ディスカッション
コメント一覧
まだ、コメントがありません