TestNG & Selenium: разделите тесты на «группы», запускайте их по порядку внутри каждой группы - PullRequest
6 голосов
/ 31 октября 2011

Мы используем TestNG и Selenium WebDriver для тестирования нашего веб-приложения.

Теперь наша проблема в том, что у нас часто есть несколько тестов, которые должны выполняться в определенном порядке, например:

  • войдите в приложение
  • введите некоторые данные
  • отредактируйте данные
  • проверьте, что они отображаются правильно

Теперь, очевидно, эти тесты нужно запустить вэтот точный порядок.

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

Так что мы хотели бы иметь возможность каким-то образом поместить тесты в«группы» (необязательно группы в смысле TestNG), а затем выполните их так, чтобы:

  • тесты внутри одной «группы» всегда выполнялись вместе и в одном и том же порядке
  • , норазные тестовые группы в целом могут выполняться в любом порядкеразвитый индепеЯсно).

    Есть ли способ достичь этого с помощью TestNG?

    Решения, которые мы попробовали

    • Сначала мы просто поставили тесты, которыепринадлежат одному классу и используют dependsOnMethods, чтобы заставить их работать в правильном порядке.Раньше это работало в TestNG V5, но в V6 TestNG иногда чередует тесты из разных классов (при соблюдении порядка, установленного dependsOnMethods).Кажется, не существует способа сказать TestNG «Всегда запускать тесты из одного класса вместе».
    • Мы рассмотрели написание метода-перехватчика .Однако это имеет недостаток, заключающийся в том, что запуск тестов из среды IDE становится более сложным (поскольку прямой вызов теста в классе не будет использовать перехватчик).Кроме того, тесты, использующие dependsOnMethods, не могут быть упорядочены перехватчиком, поэтому мы должны прекратить его использование.Возможно, нам придется создать нашу собственную аннотацию, чтобы указать порядок, и мы хотели бы максимально использовать стандартные функции TestNG.
    • Документы TestNG предлагают использовать preserve-order длязаказ тестов.Это выглядит многообещающе, но работает, только если вы перечислите каждый метод тестирования отдельно, который кажется избыточным и сложным в обслуживании.

    Есть ли лучший способ добиться этого?

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

    PS

    *Ответ 1060 * Аланнинга указывает на то, что мы могли бы просто сохранить все тесты независимыми, выполнив необходимые настройки внутри каждого теста.В принципе, это хорошая идея (и некоторые тесты делают это), однако иногда нам нужно протестировать полный рабочий процесс, каждый шаг которого зависит от всех предыдущих шагов (как в моем примере).Чтобы сделать это с «независимыми» тестами, это будет означать многократное выполнение одной и той же многоэтапной установки, и это сделает наши и без того медленные тесты еще более медленными.Вместо трех тестов:
    • Тест 1: вход в приложение
    • Тест 2: ввод некоторых данных
    • Тест 3: редактирование данных

    мы бы получили

    • Тест 1: вход в приложение
    • Тест 2: вход в приложение, введите некоторые данные
    • Тест 3: вход в приложениевведите некоторые данные, отредактируйте данные и т. д.

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

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

Ответы [ 3 ]

4 голосов
/ 01 ноября 2011

Вы смешиваете «функциональность» и «тест». Разделение их решит вашу проблему.

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

Ваши другие тесты на самом деле не должны полагаться на ваш логин "Тест", просто класс / метод логина.

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

Обновление:

Оказывается, у этого уже есть имя, шаблон Page Object. Вот страница с примерами использования этого шаблона на Java:

http://code.google.com/p/selenium/wiki/PageObjects

1 голос
/ 11 ноября 2011

Существует простой (хотя и хакерский) обходной путь для этого, если вам удобен ваш первый подход:

Сначала мы просто помещаем тесты, которые принадлежат друг к другу, в один класс, и используем для создания метода меткиони бегут в правильном порядке.Раньше это работало в TestNG V5, но в V6 TestNG иногда будет чередовать тесты из разных классов (при соблюдении порядка, на который навязаны зависимостиOnMethods).Кажется, нет способа сказать TestNG «Всегда запускать тесты из одного класса».

У нас была похожая проблема: нам нужно, чтобы наши тесты выполнялись по классам, потому что мы не моглиt гарантировать, что тестовые классы не мешают друг другу.

Вот что мы сделали: Поместите

@Test( dependsOnGroups= { "dummyGroupToMakeTestNGTreatThisAsDependentClass" } )

Аннотация в Абстрактный класс тестирования или интерфейс, от которого наследуются все ваши тесты.Это поместит все ваши методы в «первую группу» (группа, как описано в этом параграфе , а не TestNG-groups).Внутри групп порядок в классе.Благодаря Седрику Беусту, он предоставил очень быстрый ответ для этого .

Редактировать: Группа dummyGroupToMakeTestNGTreatThisAsDependentClass фактически должна существовать, но вы можете просто добавить для этого фиктивный тестовый набор..

1 голос
/ 01 ноября 2011

Попробуйте в зависимости от группы, а также в зависимости от метода.Добавьте все методы в одном классе в одну группу.Например

@Test(groups={"cls1","other"}) 
public void cls1test1(){
}
@Test(groups={"cls1","other"}, dependsOnMethods="cls1test1", alwaysrun=true) 
public void cls1test2(){
}

In class 2
@Test(groups={"cls2","other"}, dependsOnGroups="cls1", alwaysrun=true) 
public void cls2test1(){
}
@Test(groups={"cls2","other"}, dependsOnMethods="cls2test1", dependsOnGroups="cls1", alwaysrun=true) 
public void cls2test2(){
}
...