Java 如何阻止Maven';s验证重建工件的阶段?

Java 如何阻止Maven';s验证重建工件的阶段?,java,maven-2,continuous-integration,hudson,continuous-deployment,Java,Maven 2,Continuous Integration,Hudson,Continuous Deployment,设想一个使用Maven构建的Java项目,我有: 一些快速运行的单元测试: 开发人员应该在提交之前运行 我的CI服务器(Hudson,FWIW)应该在检测到新提交时运行,在出现故障时提供几乎即时的反馈 一些运行缓慢的自动验收测试: 开发人员可以选择运行,例如复制和修复故障 我的CI服务器应在成功运行单元测试后运行 这似乎是一个典型的情况。目前,我正在运行: 单元测试处于“测试”阶段 “验证”阶段的验收测试 配置了两个CI作业,都指向项目的VCS分支: “提交阶段”,运行“mvn包

设想一个使用Maven构建的Java项目,我有:

  • 一些快速运行的单元测试:
    • 开发人员应该在提交之前运行
    • 我的CI服务器(Hudson,FWIW)应该在检测到新提交时运行,在出现故障时提供几乎即时的反馈
  • 一些运行缓慢的自动验收测试:
    • 开发人员可以选择运行,例如复制和修复故障
    • 我的CI服务器应在成功运行单元测试后运行
这似乎是一个典型的情况。目前,我正在运行:

  • 单元测试处于“测试”阶段
  • “验证”阶段的验收测试
配置了两个CI作业,都指向项目的VCS分支:

  • “提交阶段”,运行“mvn包”(编译和单元测试代码,构建工件),如果成功,将触发:
  • “自动验收测试”,运行“mvn验证”(设置、运行和拆除验收测试)
  • 问题是job 2单元再次测试和构建被测工件(因为验证阶段自动调用包阶段)。这是不可取的,原因有几个(重要性降低):

    • 作业2创建的工件可能与作业1创建的工件不同(例如,如果同时有新的提交)
    • 延长提交给开发人员的反馈循环(即,他们发现自己破坏了构建需要更长的时间)
    • 浪费CI服务器上的资源
    所以我的问题是,如何配置作业2以使用作业1创建的工件

    我意识到我可以只拥有一个运行“mvn verify”的CI作业,这将只创建一次工件,但我希望拥有上面描述的单独CI作业,以便实现Farley风格的部署管道


    如果它对任何人都有帮助,以下是公认答案中“项目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>
    
    
    4.0.0
    蛋糕
    蛋糕验收
    1
    罐子
    蛋糕店验收测试
    运行Cake Shop web应用程序的自动验收测试。
    org.apache.maven.plugins
    maven编译器插件
    2.3.1
    ${java.version}
    ${java.version}
    maven surefire插件
    2.5
    真的
    org.codehaus.cargo
    cargo-maven2-plugin
    1.0.5
    启动容器
    预集成测试
    开始
    停止容器
    整合后测试
    停止
    假的
    码头7X
    嵌入的
    20000
    ${http.port}
    ${project.groupId}
    ${target.artifactId}
    战争
    ${context.path}
    org.apache.maven.plugins
    maven故障保护插件
    2.6
    集成测试
    集成测试
    验证
    验证
    **/*Test.java
    假的
    ${project.groupId}
    ${target.artifactId}
    ${target.version}
    战争
    蛋糕
    0.1.0-SNAPSHOT
    ${target.artifactId}
    8081
    1.6
    UTF-8
    
    注意,即使这个“tests”项目没有创建工件,它也必须使用某种封装(我在这里使用了“jar”),否则在验证阶段不会运行任何测试

    所以我的问题是,如何配置 作业2使用由创建的工件 工作1

    你不能

    你不需要。设置的方式听起来会满足您的需要。测试生命周期将只运行fast junits。包生成您的最终状态而不运行验证


    您只需要一个CI作业。当CI在maven deploy/install生命周期中运行时,如果junits失败,构建失败,验证脚本将不会执行。

    尝试两个maven项目。第一个包含构建和单元测试。您可以在本地存储库中安装工件。第二个作业运行第二个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
    
    <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>
    
    mvn failsafe:integration-test