Написание интеграционных тестов с использованием PageObjects

Уровень опыта: средний

Наши учебники классифицируются как «новичок», «средний» и «продвинутый». Этот уровень находится на «среднем» уровне. Если вы еще никогда не разрабатывали плагин, вы можете найти это немного сложнее.

Обзор

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

Вы должны быть уже знакомы с написанием плагина JIRA и с его модульным тестированием. Также вы можете прочитать о предыдущем методе создания интеграционных тестов с использованием FuncTestCase.

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

Шаг 1. Настройка вашего плагина

Лучший способ начать создание собственных объектов страницы - включить объекты страницы JIRA в качестве ссылки и базы для ваших объектов. Поэтому вам нужно изменить свой pom.xml и добавить следующее:


<dependency>
    <groupId>com.atlassian.jira</groupId>
    <artifactId>atlassian-jira-pageobjects</artifactId>
    <version>${jira.version}</version>
    <scope>test</scope>
</dependency>

Шаг 2. Анатомия объекта страницы

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


public class CsvSetupPage extends AbstractJiraPage {
    @ElementBy(id = "nextButton")
    protected PageElement nextButton;
 
    @ElementBy(cssSelector = "#advanced h3.toggle-title")
    private PageElement advanced;
 
    @Override
    public TimedCondition isAt() {
        return nextButton.timed().isVisible();
    }
    
    @Override
    public String getUrl() {
        return "/secure/admin/views/CsvSetupPage!default.jspa?externalSystem=com.atlassian.jira.plugins.jira-importers-plugin:csvImporter";
    }
 
    public CsvSetupPage setCsvFile(String resource) {
        csvFile.type(resource);
        return this;
    }
 
    public CsvSetupPage setDelimiter(String delimiter) {
        showAdvanced();
        this.delimiter.clear();
        this.delimiter.type(delimiter);
        return this;
    }
 
    public CsvProjectMappingsPage next() {
        Poller.waitUntilTrue(nextButton.timed().isEnabled());
        nextButton.click();
        return pageBinder.bind(CsvProjectMappingsPage.class);
    }
}

Введем пару элементов:

 

  • PageElement - это элемент DOM, с которым вы хотите взаимодействовать (изменять, кликать, читать или писать)
  • Аннотирование @ElementBy определяет, как искать элемент; вы можете искать такие вещи, как id, cssSelector, name и tag
  • Метод isAt используется AbstractJiraPage для определения того, была ли загрузка страницы завершена и загружена ожидаемая страница; он использует внутреннюю аннотацию @WaitUntil
  • Метод getUrl, определенный в AbstractJiraPage, указывает, куда идти, чтобы открыть ожидаемую страницу
  • Объект pageBinder отвечает за привязку объекта страницы к DOM, следующий метод показывает, как перемещаться с одной страницы на другую

Как вы можете видеть, вы можете набрать или щелкнуть элементы. Вы также можете получить их атрибуты, искать элементы страницы внутри элементов страницы и т. д. Самое замечательное, что объекты страницы запущены в реальном браузере, поэтому вы действительно имитируете пользователя и свой опыт.

Шаг 3. Использование объектов страницы в ваших тестах

Я предполагаю, что вы используете JIRA Func Test Basics для создания теста интеграции. Чтобы упростить ситуацию, давайте предположим, что вы расширили TestBase (проверьте документацию JIRA Func Test Basics для лучшего, предлагаемого способа написания интеграционных тестов).


public class TestCsvSetupPage extends TestBase {
    @Test
    public void testSetupPage() {
        CsvSetupPage setupPage = jira().gotoLoginPage()
            .loginAsSysAdmin(CsvSetupPage.class);
        CsvProjectMappingPage mappingPage = setupPage
            .setCsvFile("JIM-77.csv").setDelimiter(";").next();
    }
}

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

Шаг 4. Запись утверждений для элементов

Вот как вы можете проверить, делает ли ваш код то, что вы ожидаете от него. Чтобы избежать условий гонки, ваш объект страницы всегда должен возвращать TimedQuery или TimedCondtion. Давайте проверим, правильно ли прочитано userEmailSuffix из конфигурации.


public class CsvProjectMappingPage extends AbstractJiraPage {
    @ElementBy(name = "userEmailSuffix")
    PageElement userEmailSuffix;
 
    // removed for brevity
    
    public TimedQuery<String> getUserEmailSuffix() {
        return userEmailSuffix.timed().getAttribute("value");
    }
}

Ваш тест может выглядеть следующим образом:


public TestCsvProjectMappingPage extends TestBase {
    @Test
    public void testIfConfigurationIsReadProperly() {
        CsvSetupPage setupPage = jira().gotoLoginPage()
            .loginAsSysAdmin(CsvSetupPage.class);
        CsvProjectMappingPage projectMappingPage = setupPage
            .setCsvFile("JIM-80.csv")
            .setConfigurationFile("JIM-80.config").next();
        Poller.waitUntil(projectMappingsPage.getUserEmailSuffix(), 
            (Matcher<String>) equalTo("atlassian.com"));
    }
}

Используйте Poller.waitUntil для проверки утверждения. Он будет опрашивать объект страницы до тех пор, пока не будет выполнено предположение или не пройдет тайм-аут. Это здорово, если у вас есть элементы, которые динамически создаются, или вы используете AJAX для извлечения данных. Он будет следить за тем, чтобы в вашем коде не было условий гонки.

Шаг 5. Написание утверждений для коллекций

Представьте, что мы хотим проверить, отображаются ли на странице правильные подсказки для пользователя. Вот объект страницы:


public class CsvFieldMappingsPage extends AbstractJiraPage {
    @Inject private Timeouts timeouts;
    @Inject private ExtendedElementFinder extendedElementFinder;
 
    @ElementBy (className = "bottom-wizard-hints")
    PageElement bottomWizardHints;
 
    // removed for brevity
 
    public TimedQuery<Iterable<PageElement>> getBottomWizardHints() {
        return Queries.forSupplier(timeouts, 
                extendedElementFinder.within(bottomWizardHints)
                    .newQuery(By.className("hint"))
                    .supplier());
    }
}

Вы можете проверить, содержит ли страница правильные подсказки в вашем тесте следующим образом:


Poller.waitUntil(fieldMappingsPage.getBottomWizardHints(), 
    IsIterableWithSize.iterableWithSize(3));
assertThat(PageElements.asText(fieldMappingsPage.getBottomWizardHints().now()),
                IsCollectionContaining.hasItems(
                        containsString("For issues with multiple"),
                        containsString("Existing custom fields must"),
                        containsString("CSV file has at least one empty")));

Шаг 6. Выполнение тестов на CI

Существует также простой способ запуска интеграционных тестов в режиме без заголовков в CI, все, что вам нужно сделать, это отредактировать pom.xml и установить свойство xvfb.enable:


<properties>
    <xvfb.enable>true</xvfb.enable>
</properties>

Atlassian Plugin SDK автоматически запустит Xvfb и проведет ваши тесты, используя его.

Шаг 7. Еще больше ресурсов для объектов страницы

Также есть подробное руководство, которое было опубликовано в блоге разработчика Дариушем Кордонски. Проверьте это, чтобы узнать больше!

Поздравляю, вот и все

Теперь вы можете написать интеграционные тесты для JIRA. О, и не забывайте, что есть шоколад!

 

ПОХОЖИЕ ТЕМЫ

  • Написание интеграционных тестов для вашего JIRA-плагина
  • Интеллектуальное тестирование с TestKit

 

По материалам Atlassian JIRA  Server Developer Writing integration tests using PageObjects