Введение в тестирование с Arquillian

Введение в тестирование с Arquillian

1. обзор

Arquillian - это среда тестирования интеграции, независимая от контейнеров, для Java EE. Использование Arquillian сводит к минимуму бремя управления контейнерами, развертываниями, инициализацией платформы и так далее.

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

2. Основные понятия

2.1. Архивы развертывания

Существует простой способ тестирования нашего приложения при запуске внутри контейнера.

Во-первых, классShrinkWrap предоставляет API для создания развертываемых файлов*.jar,*.war, и*.ear.

Затем Arquillian позволяет нам настроить тестовое развертывание с помощью аннотации@Deployment - для метода, который возвращает объектShrinkWrap.

2.2. Контейнеры

Arquillian различает три разных типа контейнеров:

  • Удаленный - тестируется с использованием удаленного протокола, такого как JMX

  • Управляемый - удаленные контейнеры, но их жизненный цикл управляется Arquillian

  • Embedded - локальные контейнеры, в которых тесты выполняются с использованием локальных протоколов.

Также мы можем классифицировать контейнеры по их возможностям:

  • Приложения Java EE, развернутые на сервере приложений, таком как Glassfish или JBoss

  • Контейнеры сервлетов, развернутые на Tomcat или Jetty

  • Автономные контейнеры

  • Контейнеры OSGI

Он проверяет путь к классу среды выполнения и автоматически выбирает доступный контейнер.

2.3. Тестовое обогащение

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

Мы можем внедрять зависимости с помощью@Inject, внедрять ресурсы с помощью@Resource, сеансовые компоненты EJB с помощью@EJB, и т. Д.

2.4. Несколько участников тестирования

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

@Deployment(name="myname" order = 1)

Где имя - это имя файла развертывания, а параметр order - порядок выполнения развертывания, поэтому теперь мы можем запускать тесты для нескольких развертываний одновременно, используя аннотацию:

@Test @OperateOnDeployment("myname")

Предварительный тест выполняется в контейнере развертыванияmyname с использованием порядка, определенного в аннотации@Deployment.

2.5. Аркиллианские расширения

Arquillian предлагает несколько расширений на тот случай, если наши потребности в тестировании не покрываются основной средой выполнения. У нас есть постоянство, транзакции, клиент / сервер, расширения REST и т. Д.

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

Обычно используемые расширения - это Drone, Graphene и Selenium.

3. Зависимости и настройка Maven

Давайте добавим в наш файлpom.xml следующую зависимость:


    org.jboss.arquillian
    arquillian-bom
    1.1.13.Final
    import
    pom


    org.glassfish.main.extras
    glassfish-embedded-all
    4.1.2
    test


    org.jboss.arquillian.container
    arquillian-glassfish-embedded-3.1
    1.0.0.Final
    test

Последнюю версию зависимостей можно найти здесь:arquillian-bom,org.glassfish.main.extras,org.jboss.arquillian.container.

4. Простой тест

4.1. Создать компонент

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

public class Component {
    public void sendMessage(PrintStream to, String msg) {
        to.println(message(msg));
    }

    public String message(String msg) {
        return "Message, " + msg;
    }
}

Используя Arquillian, мы хотим проверить, что этот класс ведет себя правильно, когда вызывается как компонент CDI.

4.2. Напишите наш первый аркиллианский тест

Во-первых, нам нужно указать, что наш тестовый класс должен запускаться с использованием специфичного для фреймворка механизма:

@RunWith(Arquillian.class)

Если мы собираемся запускать наши тесты внутри контейнера, нам нужно использовать аннотацию@Deployment.

Arquillian не использует весь путь к классам для изоляции тестового архива. Вместо этого он использует классShrinkWrap, который представляет собой Java API для создания архивов. Когда мы создаем архив для тестирования, мы указываем, какие файлы включить в classpath для использования теста. Во время развертыванияShrinkWrap изолирует только классы, необходимые для теста.

Используя методaddclass(), мы можем указать все необходимые классы, а также добавить пустой ресурс манифеста.

JavaArchive.class создает макет веб-архива с именемtest.war,, этот файл развертывается в контейнере, а затем используется Arquillian для выполнения тестов:

@Deployment
public static JavaArchive createDeployment() {
    return ShrinkWrap.create(JavaArchive.class)
      .addClass(Component.class)
      .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}

Затем мы вводим наш компонент в тест:

@Inject
private Component component;

Наконец, мы выполняем наш тест:

assertEquals("Message, MESSAGE",component.message(("MESSAGE")));

component.sendMessage(System.out, "MESSAGE");

5. Тестирование корпоративных Java Beans

5.1. Корпоративный компонент Java

С Arquillian мы можем протестировать внедрение зависимостей Enterprise Java Bean, для этого мы создаем класс, у которого есть метод для преобразования любого слова в нижний регистр:

public class ConvertToLowerCase {
    public String convert(String word){
        return word.toLowerCase();
    }
}

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

@Stateless
public class CapsConvertor {
    public ConvertToLowerCase getLowerCase(){
        return new ConvertToLowerCase();
    }
}

КлассCapsConvertor внедряется в служебный компонент:

@Stateless
public class CapsService {

    @Inject
    private CapsConvertor capsConvertor;

    public String getConvertedCaps(final String word){
        return capsConvertor.getLowerCase().convert(word);
    }
}

5.2. Протестируйте Enterprise Java Bean

Теперь мы можем использовать Arquillian для тестирования нашего корпоративного Java Bean, введяCapsService:

@Inject
private CapsService capsService;

@Test
public void givenWord_WhenUppercase_ThenLowercase(){
    assertTrue("capitalize".equals(capsService.getConvertedCaps("CAPITALIZE")));
    assertEquals("capitalize", capsService.getConvertedCaps("CAPITALIZE"));
}

ИспользуяShrinkWrap,, мы гарантируем, что все классы правильно подключены:

@Deployment
public static JavaArchive createDeployment() {
    return ShrinkWrap.create(JavaArchive.class)
      .addClasses(CapsService.class, CapsConvertor.class, ConvertToLowerCase.class)
      .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}

6. Тестирование JPA

6.1. Упорство

Мы также можем использовать Arquillian для проверки персистентности. Сначала мы собираемся создать нашу сущность:

@Entity
public class Car {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    private String name;

    // getters and setters
}

У нас есть таблица с названиями автомобилей.

Затем мы собираемся создать наш EJB для выполнения основных операций с нашими данными:

@Stateless
public class CarEJB {

    @PersistenceContext(unitName = "defaultPersistenceUnit")
    private EntityManager em;

    public Car saveCar(Car car) {
        em.persist(car);
        return car;
    }

    public List findAllCars() {
    Query query
      = em.createQuery("SELECT b FROM Car b ORDER BY b.name ASC");
    List entries = query.getResultList();

    return entries == null ? new ArrayList<>() : entries;

    public void deleteCar(Car car) {
        car = em.merge(car);
        em.remove(car);
    }
}

С помощьюsaveCar мы можем сохранить названия автомобилей в базе данных, мы можем получить все автомобили, сохраненные с помощьюfindAllCars,, а также мы можем удалить автомобиль из базы данных с помощьюdeleteCar.

6.2. Проверить настойчивость с Аркиллианом

Теперь мы можем выполнить некоторые базовые тесты, используя Arquillian.

Сначала мы добавляем наши классы в нашShrinkWrap:

.addClasses(Car.class, CarEJB.class)
.addAsResource("META-INF/persistence.xml")

Затем мы создаем наш тест:

@Test
public void testCars() {
    assertTrue(carEJB.findAllCars().isEmpty());
    Car c1 = new Car();
    c1.setName("Impala");
    Car c2 = new Car();
    c2.setName("Lincoln");
    carEJB.saveCar(c1);
    carEJB.saveCar(c2);

    assertEquals(2, carEJB.findAllCars().size());

    carEJB.deleteCar(c1);

    assertEquals(1, carEJB.findAllCars().size());
}

В этом тесте мы сначала создаем четыре экземпляра автомобиля и проверяем, что количество строк в базе данных совпадает с тем, которое мы создали.

8. Заключение

В этом уроке мы:

  • введены основные понятия Arquillian

  • ввел компонент в тест Арквилиана

  • проверил EJB

  • проверенная стойкость

  • выполнил тест Arquillian с использованием Maven

Вы можете найти код из статьиover on Github.