Junit: расщепление интеграционного теста и юнит-тесты - PullRequest
120 голосов
/ 09 апреля 2010

Я унаследовал нагрузку теста Junit, но эти тесты (кроме большинства не работающих) представляют собой смесь реальных модульных тестов и интеграционных тестов (требующих внешних систем, БД и т. Д.).

Так что я пытаюсь придумать способ их отделить, чтобы я мог быстро и красиво запустить модульное тестирование и после него интеграционные тесты.

Возможны варианты ..

  1. Разделите их на отдельные каталоги.

  2. Перейти к Junit4 (из v3) и комментировать классы для их разделения.

  3. Используйте соглашение об именовании файлов, чтобы сказать, что такое класс, то есть AdapterATest и AdapterAIntergrationTest.

3 имеет проблему с тем, что в Eclipse есть опция «Запустить все тесты в выбранном проекте / пакете или папке». Поэтому было бы очень сложно просто запустить интеграционные тесты.

2: существует риск того, что разработчики могут начать писать интеграционные тесты в классах модульных тестов, и это просто становится беспорядочным.

1: Похоже, самое лучшее решение, но моя интуиция говорит, что там должно быть лучшее решение.

Итак, это мой вопрос, как вы разбиваете интеграционные тесты и правильные юнит-тесты?

Ответы [ 6 ]

136 голосов
/ 30 апреля 2012

Вы можете очень легко разделить их, используя категории JUnit и Maven.

Это очень и очень кратко показано ниже с помощью модуля разделения и интеграционных тестов.

Определение интерфейса маркера Первым шагом в группировке теста с использованием категорий является создание интерфейса маркера.

Этот интерфейс будет использоваться для пометки всех тестов, которые вы хотите запустить, как интеграционных тестов.

public interface IntegrationTest {}

Отметьте свои тестовые классы

Добавьте аннотацию категории в начало вашего тестового класса. Требуется имя вашего нового интерфейса.

import org.junit.experimental.categories.Category;
@Category(IntegrationTest.class)
public class ExampleIntegrationTest{
  @Test
  public void longRunningServiceTest() throws Exception {
  }
}

Настройка модульных тестов Maven Прелесть этого решения в том, что ничего не меняется для стороны модульного тестирования.

Мы просто добавляем некоторую конфигурацию в плагин maven surefire, чтобы он игнорировал любые интеграционные тесты.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <includes>
      <include>**/*.class</include>
    </includes>
    <excludedGroups>com.test.annotation.type.IntegrationTest</excludedGroups>
  </configuration>
</plugin>

Когда вы выполняете mvn clean test, будут выполняться только ваши немаркированные юнит-тесты.

Настройка тестов интеграции Maven Опять же, конфигурация для этого очень проста.

Для запуска только интеграционных тестов используйте:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <groups>com.test.annotation.type.IntegrationTest</groups>
  </configuration>
</plugin>

Если вы перенесете это в профиль с идентификатором IT, вы сможете запускать только быстрые тесты, используя mvn clean install. Чтобы запустить только интеграционные / медленные тесты, используйте mvn clean install -P IT.

Но чаще всего вы захотите запустить быстрые тесты по умолчанию и все тесты с -P IT. Если это так, то вы должны использовать трюк:

<profiles>
    <profile>
        <id>IT</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludedGroups>java.io.Serializable</excludedGroups> <!-- An empty element doesn't overwrite, so I'm using an interface here which no one will ever use -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Как видите, я исключаю тесты, помеченные java.io.Serializable. Это необходимо, поскольку профиль будет наследовать конфигурацию по умолчанию для плагина Surefire, поэтому даже если вы скажете <excludedGroups/> или <excludedGroups></excludedGroups>, будет использоваться значение com.test.annotation.type.IntegrationTest.

Вы также не можете использовать none, поскольку это должен быть интерфейс на пути к классам (Maven проверит это).

Примечания:

  • Зависимость от surefire-junit47 необходима, только если Maven не переключается на бегун JUnit 4 автоматически. Использование элемента groups или excludedGroups должно активировать переключатель. Смотрите здесь .
  • Большая часть кода, приведенного выше, была взята из документации для плагина Maven Failsafe. См. Раздел «Использование категорий JUnit» на этой странице .
  • Во время моих тестов я обнаружил, что это работает, даже когда вы используете аннотации @RunWith() для запуска комплектов или тестов на основе Spring.
38 голосов
/ 09 апреля 2010

Мы используем Maven Surefire Plugin для запуска модульных тестов и Maven Failsafe Plugin для запуска интеграционных тестов. Модульные тесты следуют **/Test*.java **/*Test.java **/*TestCase.java соглашениям об именах, интеграционные тесты - **/IT*.java **/*IT.java **/*ITCase.java. Так что это на самом деле ваш вариант номер три.

В нескольких проектах мы используем TestNG и определяем разные группы тестов для интеграции / модульных тестов, но это, вероятно, вам не подходит.

12 голосов
/ 09 апреля 2010

Я бы перешел на Junit4 только для того, чтобы иметь его :)

Вы можете разделить их на разные тестовые наборы. Я не знаю, как они организованы в Junit3, но в Junit4 должно быть просто создать тестовые наборы и поместить все реальные модульные тесты в один из них, а затем использовать второй набор для интеграционных тестов.

Теперь определите конфигурацию запуска для обоих наборов в eclipse, и вы можете легко запустить один набор. Эти наборы также могут быть запущены из автоматизированного процесса, позволяющего запускать модульные тесты каждый раз при изменении источника и, возможно, интеграционные тесты (если они действительно большие) только один раз в день или один раз в час.

10 голосов
/ 09 апреля 2010

В настоящее время я использую отдельные каталоги из-за организационной политики (и унаследованной от Junit 3), но я сам собираюсь перейти к аннотациям, сейчас я на Junit 4.

Я бы не был слишком обеспокоен тем, что разработчики помещают интеграционные тесты в ваши классы модульных тестов - добавьте правило в ваши стандарты кодирования, если это необходимо.

Мне интересно узнать, какие могут быть другие решения, кроме аннотаций или физического разделения классов ..

8 голосов
/ 12 декабря 2015

Использование IfProfileValue пружинная аннотация позволяет достичь этого без необходимого подключаемого модуля или конфигурации.

Аннотируйте классы или методы тестов интеграции с помощью IfProfileValue

import org.springframework.test.annotation.IfProfileValue;

@IfProfileValue(name="test-groups", value="integration")
public class ExampleIntegrationTest{
    @Test
    public void longRunningServiceTest() throws Exception {
    }
} 

Для запуска только с использованием модульных тестов:

mvn clean test

Для запуска с использованием интеграционных и юнит-тестов:

mvn clean test -Dtest-groups=integration

Кроме того, «Выполнить все тесты» в IDE будет запускать только модульное тестирование. Добавьте -Dtest-groups=integration к аргументам виртуальной машины, чтобы выполнить интеграцию и модульные тесты.

6 голосов
/ 11 апреля 2010

Нет правильного ответа. Как вы объяснили, есть несколько способов сделать это, которые будут работать. Я сделал и схему именования файлов, и разбил вещи на разные каталоги.

Звучит так, будто разделение вещей на разные каталоги может работать лучше для вас, и мне это кажется немного понятнее, так что я бы к этому склонился.

Не думаю, что я бы попробовал аннотации, потому что это мне кажется более детальным. Вы действительно хотите, чтобы эти два типа тестов смешались в одном файле? Я бы не стал.

...