Проводя автотесты для скорости и надежности тестирования, в разработке и процессах CI/CD зачастую используют следующий стек технологий – Jenkins, Selenoid и Allure. Можно выделить несколько их преимуществ: у Jenkins это бесплатный доступ, большое количество возможностей и плагинов для расширения; у Selenoid – независимость окружений, каждый браузер запускается в отдельном контейнере; Allure, в свою очередь, в последние годы стал популярным инструментом для построения отчетов по результатам автотестов (подробнее об этом мы писали в прошлой статье). При этом информации о том, как эти инструменты можно сочетать, до сих пор достаточно мало, и мы хотим поделиться своим примером.

Ранее мы уже писали о задачах автоматизации тестирования и возможных проверках. В этой статье рассмотрим процессы построения пайплайна для Jenkins и настройку билда. Для реализации этой задачи нам понадобится следующее:

  • Установленный Jenkins (мы использовали Jenkins на локальной машине с Ubuntu 20.04).

  • Работающий локально проект на Python, в котором в requirements.txt прописаны все необходимые зависимости, подключён Allure и присутствуют автотесты с добавленными аннотациями. Например, @allure.title("Позитивный тест расчёта") или @allure.step("Заполнить поле {locator_name} текстом {text}"). С помощью этого мы получим “волшебство" в Allure – отчет со всеми деталями тестов.

  • Проект должен быть залит в репозиторий (в нашем случае GitHub).

  • Установленный Docker и Docker Compose.

Если ваш Jenkins не “подружился” с Docker, вы можете узнать об этом в логах после сборки билда. Вам потребуется добавить Jenkins в группу Docker – в частности, на Ubuntu это делается так: sudo usermod -a -G docker jenkins

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

Как выглядит структура описанного проекта:

/pages

страница для описания локаторов

базовая страница POM

страница с действиями и проверками в тесте

data.py

Dockerfile

Jenkinsfile

browsers.json

conftest.py

pytest.ini

requirements.txt

test_main_page.py

Настройки запуска сборки в Jenkins

Далее приведем пример настроек. Сразу уточним, что мы использовали Jenkins на русском, но его локализация полностью не завершена, поэтому отдельные примеры даны на английском:

  • Нажимаем “New Item”, вводим название, выбираем Pipeline – Ок.

  • Ставим галочку напротив “Do not allow concurrent builds”, чтобы один билд дожидался выполнения другого.

  • Выбираем “Удалять устаревшие сборки”. Указываем, сколько последних сборок надо хранить (в нашем примере 5).

  • Выбираем параметризованную сборку, нажимаем "Добавить параметр" – String Parameter – и далее:

    В поле “Имя” вводим переменную CMD_PARAMS.
    В значении по умолчанию указываем путь к тестам, которые хотим прогнать. У нас это test_main_page.py
    В описании вы можете добавить комментарии о том, какие возможности есть у сборки.
    Эти действия будут полезны при запуске сборок, позволят менять флаги запуска и подаваемые в работу тесты.

  • Переходим к заполнению Pipeline в настройках. Выбираем “Pipeline script from SCM”.

  • В качестве SCM выбран Git. Заполняем “Repository URL”, нажимаем “Add Credentials”, чтобы ввести логин и пароль для гита. Прописываем ветку, с которой необходимо забирать код, в нашем случае это */master. Просмотрщик репозитория – автоматически.

    “Script Path” – Jenkinsfile, который лежит у нас в корне проекта.

  • Нажимаем кнопку «Сохранить», и настройки готовы.

Добавление Allure Plugin

После установки Allure plugin переходим в Dashboard Jenkins > настройки Jenkins > Конфигурация глобальных установок > Allure Commandline в конце списка.

Конфигурирование Jenkinsfile

Теперь переходим к Jenkinsfile и самому пайплайну.

pipeline {
  agent any
  stages {
     stage("Build image") {
        steps {
    	catchError {
      	   script {
        	      docker.build("python-web-tests", "-f Dockerfile .")
      	 }
          }
       }
    }
     stage('Pull browser') {
        steps {
           catchError {
              script {
      	    docker.image('selenoid/chrome:92.0')
      	  }
           }
        }
     }
     stage('Run tests') {
        steps {
           catchError {
              script {
          	     docker.image('aerokube/selenoid:1.10.4').withRun('-p 4444:4444 -v /run/docker.sock:/var/run/docker.sock -v $PWD:/etc/selenoid/',
            	'-timeout 600s -limit 2') { c ->
              	docker.image('python-web-tests').inside("--link ${c.id}:selenoid") {
                    	sh "pytest -n 2 --reruns 1 ${CMD_PARAMS}"
                	}
                    }
        	     }
      	 }
         }
     }
     stage('Reports') {
        steps {
           allure([
      	   includeProperties: false,
      	   jdk: '',
      	   properties: [],
      	   reportBuildPolicy: 'ALWAYS',
      	   results: [[path: 'report']]
    	   ])
  	}
         }
     }
}

Пайплайн разделен на этапы stage, в которых выполняются следующие действия:

  • stage("Build image") – здесь собираем контейнер с нашими тестами (что происходит в Dockerfile, опишем отдельно).

  • stage('Pull browser') – на данном этапе поднимаем контейнер с браузером, если он не был скачан ранее, скачиваем.

  • stage('Run tests') – пожалуй, самый интересный и запутанный этап. Здесь мы скачиваем образ и подключаем контейнер Selenoid, а скрипт -p 4444:4444 -v /run/docker.sock:/var/run/docker.sock -v $PWD:/etc/selenoid/ прокидывает порт 4444 для Selenoid и путь к конфигурации браузера (как вы помните, browsers.json лежит в корне $PWD:/etc/selenoid/). Флаг -limit 2 указывает на количество запускаемых браузеров, здесь важно помнить, что количество поднимаемых браузеров зависит от мощности машины, рекомендуется 1 CPU + 1 Gb оперативки на один браузер. Про флаги таймаутов подробнее можно почитать тут. Далее запускаем тесты из контейнера, который собрали ранее:

  • И последний этап stage('Reports') – это создание отчета Allure. Здесь нужно указать путь к папке со сгенерированными отчётами, в нашем случае это path: 'report'. Этот этап можно пропустить, если вы не используете Allure.

Получение драйвера из Selenoid

Следующий пункт, по которому могут возникнуть вопросы – это установка параметров драйвера для того, чтобы всё работало в Jenkins.

В conftest.py в нашем примере следующая фикстура для получения драйвера:

@pytest.fixture(scope="function")
def browser():
	chrome_options = webdriver.ChromeOptions()
	browser = webdriver.Remote(
    	   command_executor='http://selenoid:4444/wd/hub',
    	   desired_capabilities={'browserName': 'chrome',
                          	'version': '92.0'},
    	   options=chrome_options)
 
	browser.maximize_window()
 
	yield browser
	browser.quit()

Здесь обращаемся к адресу selenoid и порту 4444. Если вы хотите подключить дополнительно Selenoid UI и наблюдать за тем, что происходит в браузере, необходимо передать параметр 'enableVNC': True в desired_capabilities и, конечно, добавить Selenoid UI в пайплайн. Версия браузера в conftest.py должна соответствовать версии в browser.json.

{
  "chrome": {
     "default": "92.0",
     "versions": {
        "92.0": {
           "image": "selenoid/chrome:92.0",
           "port": "4444"
            }
        }
    }
}

Настройка Dockerfile

Dockerfile будет содержать немного инструкций, т.к. проект скромен и не требуется дополнительных слоёв:

FROM python:3.8.12

COPY requirements.txt .

RUN pip install -r requirements.txt

COPY . .

Берём образ Python, копируем наши зависимости, устанавливаем их и копируем наш код.

Сохранение отчета

И небольшой штрих в pytest.ini для того, чтобы отчеты Allure сохранялись в нужной папке:

[pytest]

addopts = --alluredir=report

В настроенном проекте Jenkins нажимаем кнопку «Собрать с параметрами». При этом есть возможность внести в передаваемый параметр путь к тесту, количество потоков -n или количество перезапусков --reruns на случай, если вы измените решение. После этого можно нажать «Собрать» и ждать прогона тестов. Откройте билд прогона тестов, нажмите на его номер и затем откройте Allure-отчёт, где вы можете увидеть результаты прогона и подробное описание тестов.

Если у вас что-то не запустилось, в первую очередь стоит проверить документацию Selenoid, логи в падающем билде Jenkins (и уже после этого, если нужно, поискать другие способы). 

Вывод

В приведенном примере можно один раз настроить сборку билдов и получить “комбайн”, чтобы прогонять автотесты на необходимом количестве независимых браузеров. Важно, что провести тесты можно в любое удобное время (см. отдельный пункт в настройках и комментарий по заполнению в Jenkins), например, ночью. Город засыпает, тесты просыпаются, а утром команда получает отчеты по сотням и тысячам проведенных проверок. 

Спасибо за внимание! Надеемся, что наш опыт был вам полезен.

Комментарии (0)