Mavenの検証フェーズの再構築を停止する方法は?
-
30-09-2019 - |
質問
私が持っているMavenを使用して構築されたJavaプロジェクトを想像してください:
- いくつかの急速に実行されているユニットテスト:
- 開発者はコミットする前に実行する必要があります
- 私のCIサーバー(Hudson、FWIW)は、新しいコミットを検出すると実行され、失敗の場合にほぼ瞬時にフィードバックを与えます
- いくつかの遅い自動化された受け入れテスト:
- 開発者は、障害を再現して修正することを選択した場合に実行できます
- 私のCIサーバーは、ユニットテストを正常に実行した後に実行するはずです
これは典型的なシナリオのようです。現在、私は走っています:
- 「テスト」フェーズの単体テスト
- 「検証」フェーズでの受け入れテスト
2つのCIジョブが構成されており、両方ともプロジェクトのVCSブランチを指しています。
- 「MVNパッケージ」を実行する「コミットステージ」(コードをコンパイルしてユニットテストし、アーティファクトを構築します)。成功した場合、トリガーします。
- 「MVN検証」を実行する「自動受容テスト」(セットアップ、実行、および承認テストの取り壊し)
問題は、ジョブ2ユニットテストを行い、テスト中にアーティファクトを構築することです(検証フェーズがパッケージフェーズを自動的に呼び出すため)。これは、いくつかの理由で(重要性を減らすことにおいて)望ましくありません。
- ジョブ2によって作成されたアーティファクトは、ジョブ1によって作成されたアーティファクトと同一ではない可能性があります(たとえば、その間に新しいコミットがあった場合)
- フィードバックループを開発者に延長します。
- CIサーバー上のリソースを無駄にします
それで、私の質問は、ジョブ1が作成したアーティファクトを使用するようにジョブ2を構成するにはどうすればよいですか?
「MVN Verify」を実行するCIジョブが1つだけあることを理解しています。これにより、アーティファクトが1回だけ作成されますが、Farleyスタイルの展開パイプラインを実装するために、上記の個別のCIジョブが必要です。
誰でも役立つ場合は、受け入れられている答えの「プロジェクト2」の完全なMaven 2 POMを次に示します。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.cake</groupId>
<artifactId>cake-acceptance</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>Cake Shop Acceptance Tests</name>
<description>
Runs the automated acceptance tests for the Cake Shop web application.
</description>
<build>
<plugins>
<!-- Compiler -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<!-- Suppress the normal "test" phase; there's no unit tests -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.5</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<!-- Cargo (starts and stops the web container) -->
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0.5</version>
<executions>
<execution>
<id>start-container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- Don't wait for CTRL-C after starting the container -->
<wait>false</wait>
<container>
<containerId>jetty7x</containerId>
<type>embedded</type>
<timeout>20000</timeout>
</container>
<configuration>
<properties>
<cargo.servlet.port>${http.port}</cargo.servlet.port>
</properties>
<deployables>
<deployable>
<groupId>${project.groupId}</groupId>
<artifactId>${target.artifactId}</artifactId>
<type>war</type>
<properties>
<context>${context.path}</context>
</properties>
</deployable>
</deployables>
</configuration>
</configuration>
</plugin>
<!-- Failsafe (runs the acceptance tests) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
<skipTests>false</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Add your tests' dependencies here, e.g. Selenium or Sahi,
with "test" scope -->
<dependency>
<!-- The artifact under test -->
<groupId>${project.groupId}</groupId>
<artifactId>${target.artifactId}</artifactId>
<version>${target.version}</version>
<type>war</type>
</dependency>
</dependencies>
<properties>
<!-- The artifact under test -->
<target.artifactId>cake</target.artifactId>
<target.version>0.1.0-SNAPSHOT</target.version>
<context.path>${target.artifactId}</context.path>
<http.port>8081</http.port>
<java.version>1.6</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
この「テスト」プロジェクトはアーティファクトを作成していない場合でも、何らかのパッケージを使用する必要があります(ここでは「jar」を使用しました)。そうしないと、検証フェーズではテストは実行されません。
解決
2つのMavenプロジェクトをお試しください。最初のものには、ビルドテストとユニットテストが含まれています。ローカルリポジトリにアーティファクトをインストールします。 2番目のジョブは、最初のプロジェクトのアーティファクトを依存関係として宣言し、機能テストを実行する2番目のMavenプロジェクトを実行します。
私が今説明したシナリオが可能かどうかはわかりませんが、そうだと思います。
迅速な改善のために、ユニットテストをバイパスできます -Dmaven.test.skip=true
. 。 SCMのコードのリビジョン番号を2番目のジョブに渡すと、同じソースコードをチェックアウトできるはずです。
クローンワークスペースSCMプラグインを確認することもできます。これにより、追加のオプションが提供される場合があります。
他のヒント
私はそれが長い間だったことを知っていますが、これは十分にインデックスされており、答えはどれも尋ねられたことをしませんが、私はうまくいくものを見つけました:
mvn failsafe:integration-test
これにより、プロジェクトの構築のすべての中間ステップを通過することなく、テストが直接実行されます。追加したいかもしれません failsafe:verify
その後。
それで、私の質問は、ジョブ1が作成したアーティファクトを使用するようにジョブ2を構成するにはどうすればよいですか?
できません。
する必要はありません。 Maven Build Lifecycle あなたのニーズを満たすように聞こえる方法でセットアップされています。テストライフサイクルは、高速ジュニアのみを実行します。パッケージ検証を実行せずに最終状態を構築します。
CIジョブは1つだけです。 CIがThe Maven Deploy/インストールライフサイクルを実行すると、ジュニットに失敗した場合、ビルドが失敗しますが、検証スクリプトは実行されません。
統合テストのみを実行するために使用されるMavenプロファイルを定義できます。私はこれをたくさんします。
このようなもの:
<profiles>
<profile>
<id>integration</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId><version>2.17</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId><version>2.4</version>
<configuration>
<outputDirectory>/tmp</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
あなたはこれを呼び出します:
mvn verify -Pintegration
残念ながら、戦争プラグインをスキップすることはできませんが、その出力を邪魔にならない場所に送信できます(私は /TMPを使用しました)。 MilliseCondsを本当に節約したい場合は、Webリソースを無視することもできます(Web.xmlを除き、それなしでは機能しません)。
プロファイルを使用して、実行中の他のプラグインをスキップすることもできます。
統合テストのみを実行するMavenプロファイル(ここで示唆しているように)十分ではありません。また、の構成を確認する必要があります Maven-Compiler-Plugin もっている useincrementalcompilation = false. 。この方法でプロファイルを実行すると、自動的に再コンパイルされません。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>