5

Представьте проект Java построен с использованием Maven, для которого у меня есть:Как остановить фазу проверки Maven для восстановления артефакта?

  • некоторые быстро бегущие модульные тесты, которые:
    • разработчики должны запустить перед совершением
    • моего CI сервер (Hudson, FWIW) должен работать при обнаружении нового коммита, что дает почти мгновенную обратную связь в случае сбоев
  • некоторые медленные выполняющихся автоматизированные тесты приемки, что:
    • разработчики могут запускать, если они выбирают, например. воспроизвести и исправить сбои
    • мой CI сервер должен выполняться после того, как успешно работает блок тестирует

Это выглядит как типичный сценарий. В настоящее время, я бегу:

  • модульных тестов в фазе «тест»
  • приемочные испытания в фазе «проверки»

Там находятся два задания CI сконфигурированные, как указывающие на VCS филиал проекта:

  1. «Commit Stage», который работает «МВН пакет» (компилировать и модульное тестирование коды, построить артефакт), который в случае успеха, запускающий:
  2. «Автоматизированное приемочные испытания», которая проходит «МВН проверяй» (установить, запустить и снести приемочные испытания)

Проблема в том, что модульные тесты задания 2 и строит артефакт испытуемый во всем снова (поскольку фаза проверки автоматически вызывает фазу упаковки). Это нежелательно по нескольким причинам (в убывающем важности):

  • артефакт, созданный работы 2 не может быть идентичен тому, что создал работу 1 (например, если был новый совершить в то же время)
  • удлиняет петля обратной связи с разработчиком, который сделал коммит (т.е. занимает больше времени для них, чтобы узнать, что они нарушили сборку)
  • траты ресурсов на сервере CI

Так что мой вопрос, как я могу настроить работу 2 для использования артефакта, созданного заданием 1?

Я понимаю, что у меня может быть только одно задание CI, которое запускает «mvn verify», что создаст артефакт только один раз, но я хочу, чтобы отдельные задания CI были описаны выше, чтобы реализовать контур развертывания в стиле Farley ,


В случае это помогает никому, вот полный Maven 2 ПОМ из «проекта 2» в принятом ответе:

<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»), иначе тесты не выполняются на этапе проверки.

+0

Только на благо тех, кто хочет лучше понять подход, см. «Непрерывная доставка» Джеза Хамбла и Дэвида Фарли. – 2011-05-14 23:09:19

+0

Именно эта книга побудила это усилие! Хорошо стоит цена. – 2011-05-18 04:29:38

ответ

4

Попробуйте два проекта maven. Первый содержит сборку и модульные тесты. Вы устанавливаете артефакты в своем локальном репозитории. Второе задание запускает второй проект maven, который объявляет артефакты первого проекта как зависимости и выполняет функциональные тесты.

Не уверен, что сценарий, который я только что описал, возможен, но я думаю, что это так.

Для быстрого улучшения вы можете обойти модульный тест с помощью -Dmaven.test.skip=true. Если вы передадите номер версии вашего кода в свой scm во второе задание, вы сможете проверить тот же исходный код.

Вы также можете проверить плагин SCM Workspace SCM. Это может предложить вам дополнительные возможности.

0

Так что мой вопрос, как я могу настроить задание 2 использовать артефакт, созданный работы 1?

Вы не можете.

Вам не нужно. Maven Build lifecycle настроен таким образом, который звучит так, как будто он удовлетворит ваши потребности. Жизненный цикл тестирования будет запускать только быстрые юниты. Пакет построит ваше конечное состояние без проверки.

Вам понадобится только одно задание на КИ. Когда CI запускает ваш жизненный цикл развертывания/установки maven, если junits не удается выполнить сборку, сценарии проверки не будут выполняться.

+1

То, что вы говорите, верно, но не соответствует моему (по общему признанию, неустановленному) требованию, чтобы было два отдельных задания CI, поскольку я строю конвейер развертывания и нуждаюсь в видимости, в которые изменения прошли этап фиксации, а также передал автоматическую этап принятия. Я уточнил этот вопрос. – 2010-12-02 02:14:08

0

Вы можете определить профиль 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 

К сожалению WAR плагин не может быть пропущен, но вы можете отправить свой выход куда-то в сторону (Я использовал/tmp). Если вы действительно хотите сохранить миллисекунды, вы можете также игнорировать веб-ресурсы (кроме web.xml, это не сработает без этого).

Вы также можете использовать профиль, чтобы пропустить какие-либо другие плагины, которые могут быть запущены, например, сборочный модуль, Cobertura, PMD и т.д.

0

Maven профиль, который выполняет только интеграционные тесты (as suggested here) не является достаточным , Вы также должны убедиться, что конфигурация 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> 
0

Я знаю, что это было давно, но это хорошо индексируются и ни один из ответов не делать то, что было предложено, но я нашел то, что работает:

mvn failsafe:integration-test 

Это прогоняет тесты напрямую, без прохождения всех промежуточных этапов строительства проекта. После этого вы можете добавить failsafe:verify.