如何阻止Maven的validation阶段重建工件?

想象一下使用Maven构建的Java项目,我有:

  • 一些快速运行的unit testing:
    • 开发人员应该在提交之前运行
    • 我的CI服务器(Hudson,FWIW)应该在检测到新提交时运行,在出现故障时提供几乎即时的反馈
  • 一些慢速运行的自动验收测试:
    • 开发人员可以选择运行,例如重现和修复故障
    • 我的CI服务器应在成功运行unit testing后运行

这似乎是一个典型的场景。 目前,我正在运行:

  • 该单元在“测试”阶段进行测试
  • “validation”阶段的验收测试

配置了两个CI作业,两者都指向项目的VCS分支:

  1. “Commit Stage”,运行“mvn package”(编译和unit testing代码,构建工件),如果成功,则触发:
  2. “自动验收测试”,运行“mvn verify”(设置,运行和拆除验收测试)

问题是作业2unit testing并重新构建被测工件(因为validation阶段会自动调用包阶段)。 由于几个原因(重要性降低),这是不可取的:

  • 作业2创建的工件可能与作业1创建的工件不同(例如,如果同时存在新的提交)
  • 将反馈循环延长到进行提交的开发人员(即他们需要更长时间才能发现他们破坏了构建)
  • 在CI服务器上浪费资源

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

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


万一它可以帮助任何人,这里是接受答案中“项目2”的完整Maven 2 POM:

 4.0.0 com.example.cake cake-acceptance 1.0 jar Cake Shop Acceptance Tests  Runs the automated acceptance tests for the Cake Shop web application.      org.apache.maven.plugins maven-compiler-plugin 2.3.1  ${java.version} ${java.version}     maven-surefire-plugin 2.5  true     org.codehaus.cargo cargo-maven2-plugin 1.0.5   start-container pre-integration-test  start    stop-container post-integration-test  stop      false  jetty7x embedded 20000    ${http.port}    ${project.groupId} ${target.artifactId} war  ${context.path}         org.apache.maven.plugins maven-failsafe-plugin 2.6   integration-test  integration-test    verify  verify      **/*Test.java  false         ${project.groupId} ${target.artifactId} ${target.version} war     cake 0.1.0-SNAPSHOT ${target.artifactId} 8081 1.6 UTF-8   

请注意,即使这个“测试”项目没有创建工件,它也必须使用某种打包(我在这里使用“jar”),否则在validation阶段不会运行任何测试。

尝试两个maven项目。 第一个包含构建和unit testing。 您可以在本地存储库中安装工件。 第二个作业运行第二个maven项目,该项目将第一个项目的工件声明为依赖项并运行function测试。

不确定我刚才描述的场景是否可行,但我认为是。

为了快速改进,您可以使用-Dmaven.test.skip=true绕过unit testing。 如果将scm中代码的修订号传递给第二个作业,则应该能够签出相同的源代码。

您还可以查看Clone Workspace SCM插件。 这可能会为您提供一些额外的选择。

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

你不能。

你不需要。 Maven Build生命周期的设置听起来像是满足您的需求。 测试生命周期只会运行快速连接。 包构建您的最终状态而不运行validation。

您只需要一个CI作业。 当CI运行maven部署/安装生命周期时,如果junits失败,则构建失败,validation脚本将不会执行。

您可以定义将用于仅执行集成测试的Maven配置文件。 我做了很多。

像这样的东西:

   integration  false     maven-surefire-plugin2.17  true    maven-war-plugin2.4  /tmp       

你可以用以下方法调用它:

 mvn verify -Pintegration 

不幸的是,不能跳过WAR插件,但你可以把它的输出发送到某个地方(我用过/ tmp)。 如果你真的想节省毫秒数,你也可以让它忽略网络资源(除了web.xml,如果没有它,它将无法工作)。

您还可以使用配置文件跳过您可能正在运行的任何其他插件,例如程序集插件,Cobertura,PMD等。

仅执行集成测试的Maven配置文件( 如此处所示 )是不够的。 您还需要确保maven-compiler-plugin的配置具有useIncrementalCompilation = false 。 以这种方式运行配置文件,不会自动重新编译,例如:

  org.apache.maven.plugins maven-compiler-plugin 3.3  1.8 1.8 false   

我知道已经有很长一段时间了,但这是很好的索引,没有一个答案能够满足要求,但我找到了一些有效的方法:

 mvn failsafe:integration-test 

这直接运行测试,无需完成构建项目的所有中间步骤。 您可能想要添加failsafe:verify在它之后failsafe:verify