|
|
WebOTX Manual V11.1 (第6版) 目次を表示 |
ここでは、MicroShed Testing を利用した WebOTX コンテナのテスト方法について、例を用いて説明します。
MicroShed Testing は、マイクロサービスアプリケーションの統合テストを簡単かつ素早く行うための Java ライブラリです。 このライブラリを使用することで、作成した Web アプリケーションを WebOTX のコンテナに配備し、データベースなどの他のコンテナと連携した環境上で自動的にテストを実施することができます。テストケースは Java で記述します。
例えば、MicroShed Testing が公開している以下のサンプルアプリケーションを WebOTX のコンテナ上で動作させる手順を用いて、説明します。
※このサンプルアプリケーションは MicroShed Testing で公開されているアプリケーション(maven-app)を Java EE 7 用に変更したものです。
サンプルアプリケーション maven-app.zip を解凍してください。
解凍した先に以下の Dockerfile が展開されます。
Dockerfile:
FROM webotx/webotx-express-ubi7:10.40.00.00 COPY target/myservice.war /opt/WebOTX/domains/domain1/autodeploy/ EXPOSE 8080
FROM で指定している Docker のイメージは WebOTX Uber JAR や WebOTX Standard 用の Docker イメージに置き換えることもできます。
COPY では、ビルドしたアプリケーションを配備するため、ドメインディレクトリ配下の autodeploy に配置しています。ここでコピーするファイル名は、アプリケーションによって変更する必要があります。
EXPOSE では、MicroShed Testing で使用する HTTP ポート番号を指定しています。
MicroShed Testing では、ここで EXPOSE されたポートを検索して、見つかったポートに対してポートフォワードが設定されます。このポートに対して、テスト実行時にホスト側からリクエストが行われます。
もし、EXPOSE を指定しなかった場合は、テスト実施時にポート番号が取得できず、テストに失敗するので注意してください。
MicroShed Testing は、アプリケーションが READY 状態となるまで待ち合わせてからテストを実施する必要があります。この待ち合わせを行うため、サンプルアプリケーションでは以下のように .withReadinessPath にて、/myservice/people から 200 応答が返ってくるまで待ち合わせるといった定義をしています。アプリケーションによって、どのようなリクエストで待ち合わせるか設定を変更してください。
src/test/java/org/example/app/it/JaxrsJsonIT.java(一部抜粋):
@Container
public static ApplicationContainer app = new ApplicationContainer()
.withAppContextRoot("/myservice")
.withReadinessPath("/myservice/people");
次のように Maven のコマンドを実行することで、Docker コンテナが起動してアプリケーションが配備された後、テストが実行されます。
このとき、Docker コンテナが起動するまでの待ち合わせ時間が、MicroShed の仕様でデフォルト 30 秒となっており、環境によっては Timeout が発生します。 もし、Timeout が発生する場合は、以下のように環境変数で CI=true を指定して、Docker コンテナが起動するまでの待ち合わせ時間を 90 秒とします。
Linux の場合:
CI=true mvn clean install
Windows の場合:
set CI=true mvn clean install
テストの実行結果は次のように出力され、全てテストが成功した場合は、Failures、Errors が 0 となります。
[INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running org.example.app.it.JaxrsJsonIT 0 DEBUG org.microshed.testing.ApplicationEnvironment - Found ApplicationEnvironment class org.microshed.testing.testcontainers.config.TestcontainersConfiguration with priority=-30, available=true 4 DEBUG org.microshed.testing.ApplicationEnvironment - Found ApplicationEnvironment class org.microshed.testing.ManuallyStartedConfiguration with priority=-10, available=false 4 DEBUG org.microshed.testing.ApplicationEnvironment - Found ApplicationEnvironment class org.microshed.testing.testcontainers.config.HollowTestcontainersConfiguration with priority=-20, available=false 6 INFO org.microshed.testing.jupiter.MicroShedTestExtension - Using ApplicationEnvironment class: org.microshed.testing.testcontainers.config.TestcontainersConfiguration 5894 INFO org.microshed.testing.testcontainers.ApplicationContainer - Found exposed ports: [8080/tcp] 5894 INFO org.microshed.testing.testcontainers.ApplicationContainer - Automatically selecting default HTTP port: 8080 5895 INFO org.microshed.testing.testcontainers.ApplicationContainer - Using ServerAdapter: org.microshed.testing.testcontainers.ApplicationContainer.DefaultServerAdapter 5903 DEBUG org.microshed.testing.testcontainers.config.TestcontainersConfiguration - No networks explicitly defined. Using shared network for all containers in class org.example.app.it.JaxrsJsonIT : (省略) : 9372 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: Starting Domain domain1, please wait. 9380 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: Redirecting output to /opt/WebOTX/domains/domain1/logs/server.log 9826 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: Edition is Express 43370 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: Domain domain1 is ready to receive client requests. Additional services are being started in background. 43410 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: Domain [domain1] is running [Version 10.40.00.00 (build xxxxxxxx)]. 43411 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: 43411 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: * Standard JMX Clients (like JConsole) can connect to JMXServiceURL: 43411 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: [service:jmx:rmi:///jndi/rmi://xxxxxxxxxx:6212/jmxrmi] for domain management purposes. 43411 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: 43412 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: * Domain listens on at least following ports for connections: 43412 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: [5858 6212 6712 8080 8443]. 43412 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: 43416 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDOUT: Command start-domain executed successfully. : (省略) : 61758 INFO org.microshed.testing.jaxrs.JsonBProvider - Response from server: 4618523015471329430 61798 INFO org.microshed.testing.jaxrs.JsonBProvider - Response from server: {"id":4618523015471329430,"name":"Newborn","age":0} [INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 61.81 s - in org.example.app.it.JaxrsJsonIT [INFO] [INFO] Results: [INFO] [INFO] Tests run: 8, Failures: 0, Errors: 0, Skipped: 0
既存のアプリケーションに対して、MicroShed Testing を使用するためには、Maven の依存モジュールに以下を追加します。
<dependencies>
<dependency>
<groupId>org.microshed</groupId>
<artifactId>microshed-testing-testcontainers</artifactId>
<version>0.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>
<!-- other dependencies... -->
</dependencies>
MicroShed Testing のテストケースとして、クラスまたはメソッドに @MicroShedTest アノテーションを付与して定義します。
@MicroShedTest
public class MyTestA {
@Container
public static ApplicationContainer app = new ApplicationContainer()
.withAppContextRoot("/myservice");
// ...
}
データベースなど複数のコンテナと連携してテストを実施したい場合は、次のように SharedContainerConfiguration.startContainers() を Override して、コンテナを起動します。
public class AppContainerConfig implements SharedContainerConfiguration {
@Container
public static GenericContainer<?> mongo = new GenericContainer<>("mongo:3.4")
// ...
@Container
public static ApplicationContainer app = new ApplicationContainer()
// ...
@Override
public void startContainers() {
mongo.start();
app.start();
}
}
@MicroShedTest
@SharedContainerConfig(AppContainerConfig.class)
public class MyTestA {
// ...
}
@MicroShedTest
@SharedContainerConfig(AppContainerConfig.class)
public class MyTestB {
// ...
}
MicroShed Testing の詳細な使い方については、以下の MicrShed の公式ページをご参照ください。
ここでは、Testcontainers を利用した WebOTX コンテナのテスト方法について、例を用いて説明します。
Testcontainersは、Javaテストケースに組み込むことで、テストケースごとにデータベースなどの他のコンテナを起動し、アプリケーション・コンテナ間での結合評価を行うことができるOSSです。
Testcontainersには以下のような利点があります。
テスト実行の度にコンテナが新しく生成され、その都度環境設定を行うことで、ステートレスなテストを実行することができます。
Selenium等、ブラウザのエミュレートを行えるフレームワークベースで動くWebブラウザのコンテナを使うことにより、任意のURLへアクセスするようなテストを実行することができます。
Testcontainersの利用には、テスト実行環境にDockerがインストールされている必要があります。
Testcontainersのライブラリは、mvnrepository.comで公開されています。
https://mvnrepository.com/artifact/org.testcontainers/testcontainers
Mavenによりアプリケーションを作成している場合は、アプリケーションのpom.xmlに以下のように依存関係を追加して下さい。
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>Testcontainersのバージョン</version>
<scope>test</scope>
</dependency>
以下にテストコードのサンプルを記載します。
テストケース実施前にPostgresのコンテナを起動し、テストケース内で接続しています。
public class SampleJunitTestPostgres {
public static final Logger LOGGER = LogManager.getLogger(SampleJunitTestPostgres.class);
Connection conn = null;
Statement stmt = null;
@ClassRule
public static GenericContainer POSTGRES = //コンテナを生成し、
new GenericContainer("postgres:12.3") // 開けるポートや環境変数を設定
.withExposedPorts(5432)
.withEnv("POSTGRES_PASSWORD", "postgrespw")
.withEnv("POSTGRES_USER", "postgresuser")
.withEnv("POSTGRES_DB", "postgresdb");
@Test
public void simplePostgres1() {
Boolean isSuccess = false;
try {
Thread.sleep(10000); // コンテナ起動を10秒間待ち合わせ
// 生成したPostgresコンテナへ接続
Class.forName("org.postgresql.Driver");
String url = "jdbc:postgresql://"
+ POSTGRES.getContainerIpAddress()
+ ":" + POSTGRES.getMappedPort(5432)
+ "/" + "postgresdb";
conn = DriverManager.getConnection(url, "postgresuser", "postgrespw");
isSuccess = true; // Connectでエラーが出なければ成功とする
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
conn = null;
}
}// 接続して例外が出なかったらテスト成功
assertThat(isSuccess).isEqualTo(true);
}
}
Testcontainers の詳細な使い方については、以下の Testcontainers の公式ページをご参照ください。