Что такое сквозное тестирование
End-to-end или E2E-процесс: что это? Сквозное тестирование
и другие поведенческие факторы.
К примеру, компания Гугл при разработке своих продуктов следует правилу «70-20-10», цифры которого показывают процентное соотношение от общего количества тестов, то есть:
70% занимают юнит-тесты;
20% занимают интеграционные тесты;
Нет единого алгоритма сквозного тестирования, так как многое будет зависеть от сложности самого проекта и что конкретно нужно тестировать. Е2Е — это лишь название процесса тестирования, а не его метод или алгоритм. Но при этом выделяют два основных типа сквозного тестирования, на которых мы немного остановимся.
Любой сквозной тест — это:
в первую очередь тестирование UI;
тяжелый и медленный тест;
применение метода «черного ящика» и найм сторонних тестировщиков, никак не связанных с разработкой программы;
тяжелый «отлов» найденной проблемы;
тестирование всех модулей и всех систем целиком, поэтому требуется сложный и эффективный софт или работа «руками»;
Заключение
нагрузку на каждый трос или балку;
поведение моста при наводнении, землетрясении, пожаре или аварии на нем;
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Сквозные тесты
Dec 8, 2019 · 7 min read
Несколько слов о сквозных тестах.
О чем статья
Статья в больше степени будет описывать сквозные тесты. Будет описан процесс, реализованный в последнем моем проекте. Также статья балы написана как предложение развития автоматизациия тестирования в компании, которой я работаю.
Для чего нужны e2e тесты
Сквозное, end-to-end — это тестирование системы в целом, эмулируя реальную пользовательскую среду. Это тесты, запущенные в браузере, имитирующие щелчки мышью и нажатия клавиш. Сквозным оно называется, потому что проверяют бизнес функции системы. Если брать терминологию тестирования, то e2e — это поведенческое тестирование по методу «чёрного ящика» (проверка выполнения приложением заданных функциональных требований, при которой не используются знания о внутренней структуре тестируемого объекта). То есть мы тестируем, что система работает, как планировалось, с точки зрения конечного пользователя.
Пользователю всё равно, работает ли приложение «как планировалось», ему важно, чтобы функционал работал в соответствии с его собственными ожиданиями. Тестирование по сути это автоматизированный запуск приложения в браузере и последовательные действия, проверяющие весь функционал пользовательского интерфейса. Совершать все эти действия вручную было бы крайне неэффективно, поэтому создадим автоматические тесты.
В итоге тесты нужны для следующих вещей:
Пирамида тестирования
Вспомним пирамиду тестирования, где показывается распределение по типам тестов в приложении.
На написание и запуск E2E-тестов требуется время и ресурсы. Google например предлагает разделение 70/20/10: 70% unit тестов, 20% интеграционных тестов и 10% E2E-тестов. Точная комбинация будет отличаться для каждого проекта, но в целом она должна сохранить форму пирамиды.
Из пирамиды, как мы знаем, следует что тестов необходимо писать малое количество, это объясняется следующими причинами:
1. Хорошо написанных интеграционных и юнит-тестов должно хватить. E2E-тесты должны проверить, что все элементы корректно связаны между собой.
2. Скорость выполнения. Если их будет сотни, как юнит-тестов и интеграционных, то тестирование будет проходить очень долго.
3. Непредсказуемость. Так как имитируется пользовательская среда, то в таймаут могут не проходить некоторые тесты из-за API браузера. С юнит(интеграционными) тестами такого быть не может.
Когда использовать e2e тесты
По хорошему, e2e-тесты стоит использовать в каждом проекте, в котором есть команда(dev, qa, pm). Но стоит отметить, что внедрять e2e тесты стоит использовать только когда покрыты unit тесты и интеграционные, только тогда будет понятно, что еще не покрыто в системе. Также необходимо учитывать возможность написания тестов, если проект короткий mvp, то нет смысла писать сквозные тесты, так как большая часть функционала может быть переписана и переделана.
Виды тестирования
Перед тем как говорить о сквозных тестах, стоит понимать к какому виду тестирования он относится и какое место он занимает. Классификация тестов обширная и всю ее мы приводить не будем.
Знание системы
Самым высоким уровнем в иерархии подходов к тестированию будет понятие типа, которое может охватывать сразу несколько смежных техник тестирования. То есть, одному типу тестирования может соответствовать несколько его видов. Рассмотрим, для начала несколько типов тестирования, которые отличаются знанием внутреннего устройства объекта тестирования.
По целям
Таким образом сквозные тесты являются функциональными тестами методом черного ящика. Стоит это учитывать при разработке теста.
Unit vs E2E
Между модульными тестами и сквозными много отличий и часто возникает вопрос какие тесты использовать. Ответ очевиден использовать и оба вида тестов в соответствии с пирамидой тестирования. Все же стоит уточнить разницу между этими видами.
Модульные тесты:
Сквозные тесты:
Концепции
Создание e2e начинается с описания пользовательской истории. Насколько тщательно мы подготовим описание на этом этапе, настолько просто будет команде разработчиков написать E2E-тест, который будет демонстрировать что все системы работают правильно при реализации этого сценария. Спустя какое-то время, технические писатели или новая команда разработчиков, вместо чтения документации, могут воспользоваться тестами, для того чтобы запустить и посмотреть реализованные сценарии в реальном браузере или автоматически записать видео-уроки.
Жизненный цикл сквозного теста следующий:
Как все устроено
Запуск тестов возможен двумя способами: через ci в автоматическом режиме, либо локально на машине разработчика. Сами тесты запускаются с помощью фреймворка, который в совокупности в веб-драйвером составляют движок автоматизации e2e, который может генерировать отчет о выполнении, также движок запускает браузер и взаимодействует с ним(отправляет команды, запускает тесты), браузер в свою очередь запускает тестируемое приложение, которое взаимодействует в бекендом. Бекенд в стандартной манере взаимодействует в БД, в этом плане ничего не меняется, связка приложения и бекенда с БД, остается неизменным. Также движок автоматизации должен хранить в актуальном состоянии БД перед запуском каждого теста.
Protractor
Protractor — это программа Node.js, построенная поверх WebDriverJS. Protractor работает как интегратор решений, объединяющий мощные технологии, такие как Node.js, Jasmine, Selenium, Mocha, Cucumber и Web.
Каждый тест представляет собой два файла для теста страницы (spec и po). Ниже представлен код проверяющий заголовок на конкретный текст.
Каждая страница оборачивается в тестовую группу describe и каждый тест-кейс обозначается через it — синтаксис аналогичен Jasmine. Каждый элемент страницы ищется через встроенные в фреймворк методы. Все методы асинхронные, это стоит учитывать при разработке, чтобы тесты выполнялись стабильно.
Весь повторяющийся код переводится в beforeEach, если код специфичный для конкретных тестов, то он выносится в page Object. Так как protractor использует Selenium, то по умолчанию используется паттерн Page Object.
Page Object Pattern
Page Object активно используется при разработке тестов и стоит понимать почему именно этот шаблон проектирования используется в protractor. Page Object это шаблон проектирования, который широко используется в автоматизированном тестировании и позволяет разделять логику выполнения тестов от их реализации.
Style guide
Стайл гайд взят из https://www.protractortest.org/#/style-guide. В статье указаны правила, которые используются в наших проектах.
Автоматизация на проектах
1. Выбрать фреймворк для тестирования. В нашем случае мы выбрали protractor, так как он по умолчанию встроен в Angular, но также можно выбрать другой фреймворк, но мы пошли по меньшему сопротивлению. В других средах, необходимо выбирать фреймворк для тестирования.
2. Выбрать основные тесты. Так как мы определились что мы не можем использовать много e2e тестов из-за их дороговизны в разработке и скорости выполнения, поэтому необходимо выбрать костяк основной функциональности системы, которая должна обязательно выполняться.
3. Интеграция CI/CD. Этот шаг очень важен, так как тесты обязательно должны запускаться автоматически и не должны попадать ан стенд не оттестированные разработчиком. Этот пункт касается не только e2e тестов но и всей кодовой базы.
Сквозные тесты внедрены в пайплайн сборки, но могут валится(решается внедрением докера). Составлены предложения по развитию автоматизации тестирования. Кроме того необходимо больше проектов, где возможно внедрить сквозные автотесты. Но стоит отметить, что перед внедрением тестов стоит учитывать, что нужны устаканенные ТЗ и тест-кейсы с пользовательскими сценариями.
Как проводить сквозное (end-to-end) тестирование вашего приложения используя Cypress.io
В этой статье вы узнаете:
Что такое Cypress и когда его стоит использовать
Основы тестирования с использованием Cypress
Расширенные команды Cypress
Взаимодействие с элементами пользовательского интерфейса
Лучшие практики с использованием Cypress
Введение
Чтобы протестировать свои приложения, вам потребуется сделать следующие шаги:
Подождать пока сервер запустится
Провести ручное тестирование приложения(нажать на кнопки, ввести случайные текст в поля ввода или отправить форму)
Проверить, что результат вашего теста корректен(изменения заголовка, части текста и т.д.)
Повторить эти шаги ещё раз после простых изменений кода
Повторение этих шагов снова и снова становится утомительным и отнимает у вас слишком много времени и энергии. Что, если бы мы могли автоматизировать этот процесс тестирования Благодаря этому вы можете сосредоточиться на более важных вещах и не тратить время на тестирование пользовательского интерфейса снова и снова.
Именно здесь в игру вступает Cypress. При использовании Cypress единственное, что вам нужно сделать, это:
Написать код вашего теста(нажатие на кнопку, ввод текста в поля ввода и т.п.)
Запустить или перезапустить тест
Только и всего! Библиотека Cypress выполняет все тесты за вас. И самое приятное, что она не только сообщает вам все ли ваши тесты успешны или нет, но также сообщает вам, какой тест не удался.
Помимо этого, тестирование вашего кода — отличная практика, поэтому вам придется позже изучить соответствующий фреймворк. Cypress позволяет запускать тесты за считанные минуты.
Теперь, когда мы обсудили преимущества Cypress, давайте узнаем об основах этой библиотеки.
Начало
Установка и настройка Cypress
Сначала создайте отдельную папку для вашего проекта, а затем инициализируйте ее:
Инициализация проекта
Наконец, чтобы установить библиотеку Cypress:
Установка Cypress
Теперь, когда Cypress установлен, попробуйте запустить его с помощью следующей команды:
Открытие Cypress
Она открывает запускалку тестов(Test Runner):
Интерфейс Test Runner
А теперь давайте перейдём к написанию тестов.
Основы Cypress
Создание файла
Переход к cypress/integration
Теперь создайте файл JavaScript с именем basicTest.js :
Создание JavaScript файла
Если вы не отключили сервер Cypress, ваши новые файлы появятся в Test Runner в реальном времени:
Обновление структуры файлов в реальном времени
Теперь давайте напишем наш первый тест.
Простые тесты с утверждением и ожиданием значения
В вашем файле /cypress/integration/basicTest.js напишите следующий код:
Код к файлу basicTest.js
Строка 1: Функция describe сообщает Cypress название набора наших тестов.
Чтобы запустить вашу программу, щёлкните по basicTest.js в вашем сервере Cypress.
Щелчок по basicTest.js в Test Runner
Результат запуска теста
Отлично! Значит, наше утверждение было успешным.
Что, если мы сделаем заведомо ложное утверждение? Теперь в /cypress/integration/basicTest.js добавьте следующий код в пределах функции describe :
Код для добавление в basicTest.js
Строка 2: Если сумма 4 и 5 равна 10, тест будет пройден. В противном случае, незамедлительно остановлен.
Снова запустите код. Результат будет:
Результат нашего второго теста
Обратите внимание, как наш второй тест не удался. Если бы результат был правильным, тест прошел бы успешно.
Давайте больше поиграем с утверждениями. Добавьте в basicTest.js следующий код:
Код для добавления в basicTest.js
Строка 2: Если сумма 5 и 5 не равна 100, то тест должен пройти.
Результат выполнения теста:
Результат теста: успешно!
Отлично! Наш тест прошел. Функция expect выполняет BDD (behavior-driven) утверждения. В следующем разделе мы выполним утверждения, основанные на тестировании(test-driven assertions).
Сейчас /cypress/integration/basicTest.js должен выглядеть так:
Написание утверждений основанных на тестировании(test-driven assertions) с явным использованием assert
В вашем файле basicTest.js напишите следующий код:
Строка 10: Убеждаемся, что переменная name содержит строковое значение.
Строка 14: Убеждаемся, что переменная name не является целым числом.
Запустите код. Результатом будет:
Результат запуска нашего теста
Отлично! Наш код работает. В следующем разделе мы научимся работать с сайтами через Cypress.
Сейчас наш basicTest.js должен выглядеть так:
Запуск веб-сайтов
Код для basicCommandsTest.js
Сохраните свой код и нажмите на basicCommandsTest.js в меню Test Runner:
Клик по basicCommandsTest.js вTest Runner
Отлично! Наш код работает. В следующем разделе мы более глубоко погрузимся в тестирование с помощью Cypress.
В итоге basicCommandsTest.js должен выглядеть так:
Cypress: Расширенные команды
В этом разделе мы попытаемся взаимодействовать с элементами на странице. Однако, прежде чем продолжить этот процесс, нам нужно сначала научиться идентифицировать элементы HTML в Cypress.
Как идентифицировать элементы
Cypress использует селекторы JQuery для идентификации компонентов на веб-странице.
Получение элемента через id элемента
В качестве альтернативы, чтобы идентифицировать элемент myButton используя имя класса, могли бы использовать следующую строку:
Получение элемента через имя класса
Давайте теперь поработаем с взаимодействием с пользовательским интерфейсом нашего сайта.
Нажатие кнопки
В этом разделе мы будем использовать страницу The-Internet для запуска наших тестов. На этом веб-сайте мы будем использовать раздел добавления/удаления элементов.
Давайте сначала попробуем идентифицировать нашу кнопку «Добавить элемент».
Страница для тестирования
Скриншот из DeveloperTools
Соответствующий селектор для этой кнопки будет выглядеть так:
Идентификация элемента
Строка 2: Переходим на веб-страницу.
Строка 6: Связываем в одну цепочку получение элемента button и нажатие на эту кнопку.
Запустите код. Результат:
Вывод результата
Давайте теперь поработаем с вводом текста в текстовое поле.
Ввод текста
В этом разделе мы будем использовать страницу The-Internet’s login. Нам нужен способ сначала идентифицировать элементы.
Скриншот сайта для тестирования
Скриншот из DeveloperTools
Скриншот из DeveloperTools
Идентификация элемента через его id
Строка 3: Переходим на страницу входа в систему.
Строка 10: Нажимаем на кнопку «Отправить».
Запустите код. Результатом будет:
Вывод результата запуска кода
И мы закончили! В следующем разделе мы узнаем о работе с чекбоксами.
Переключение чекбоксов
Давайте сначала посмотрим на DevTools:
Developer Tools
Идентификация наших чекбоксов
В каталоге /cypress/integration/ создайте файл с именем runningCheckCommand.js и напишите следующий код:
Строка 7: Просим Cypress приостановить процесс тестирования на одну секунду.
Запустите код. Результат:
Результат запуска теста
Отлично! Наш код работает. Давайте теперь поработаем над неявными утверждениями с помощью Cypress.
Неявные утверждения
Ранее мы выполняли утверждения для переменных и объектов. Однако в реальном мире мы хотели бы выполнять утверждения для текста, расположенного в нашем элементе HTML, или проверять, есть ли у нашего элемента ul дочерние элементы li или нет.
Скриншот тестируемой страницы
Developer Tools
Наше утверждение
Для этого мы должны использовать следующий синтаксис:
Получение элемента и за тем утверждение
Альтернативно, можем выполнить такое утверждение:
Наше утверждение
Мы можем использовать эту строку кода:
Получение элемента и затем утверждение
Перейдите в /cypress/integration/runningClickCommand.js и добавьте следующий код:
Код для runningClickCommand.js
Запустите код. Результат в конце теста должен быть следующим:
Результат запуска
В итоге cypress/integration/runningClickCommand.js должен выглядеть так:
Команда each
Скриншот тестового сайта
Откройте Developer Tools:
Получение элемента и использование each затем
Перейдите в /cypress/integration/runningClickCommand.js и добавьте следующий фрагмент кода:
Код для runningClickCommand.js
Строка 3: Обёртываем этот элемент, чтобы мы могли выполнять с ним команды Cypress. Здесь мы отправляем команду щёлкнуть по этим элементам.
Результат выполнения кода должен быть следующим:
Результат выполнения кода
Наш код работает! Поскольку наш тест был быстрым, давайте попробуем добавить на страницу больше элементов.
Найдите следующий фрагмент кода:
Строка 2: Запускаем цикл, чтобы сообщить Cypress, что нужно нажать кнопку Add Element 20 раз.
Запустите код еще раз. Результат должен быть таким:
Результат выполнения кода
Как видите, наша программа автоматически удалила все элементы на странице без каких-либо ручных усилий. Отлично!
В следующей части статьи мы узнаем о том, что можно и чего нельзя делать при тестировании с Cypress.
В итоге cypress/integration/runningClickCommand.js должен выглядеть так:
Лучшие практики
Держите тесты изолированными
Рассмотрим ситуацию, когда вы тестируете свое приложение. Структура вашего проекта будет выглядеть примерно так:
Не самая лучшая структура
В вашем Test Runner это будет выглядеть так:
Отображение тестовой структуры в Test Runner
Команда Cypress утверждает, что структура вашего проекта должна быть организована как можно лучше. Лучше всего перегруппировать ваши файлы проекта в другие папки, например:
Хорошая структура проекта
Следовательно, это выглядело бы так:
По возможности используйте собственные команды
Взгляните на этот фрагмент кода:
Пример кода
В вашем cypress/support/commands.js напишите этот код:
Строка 2: Получаем элемент с соответствующим идентификатором, а затем вводим в него данные.
Теперь вернитесь в свой тестовый файл и замените его вот так:
Пример кода
Как видите, наш код выглядит значительно короче.
Избегайте «атомарных» тестов
Взгляните на этот фрагмент кода:
Cypress не одобряет такого поведения. Это неэффективно, и есть способ лучше переписать этот код, например:
Мы можем использовать метод and для связывания дополнительных команд should с нашим элементом.
Не запускайте сервер в Cypress
Команда exec присутствует для запуска команд в терминале. Но запускать сервер с помощью этой команды крайне не рекомендуется.
Команды терминала
Репозиторий GitHub и дополнительные ресурсы
Код GitHub
Дальнейшее чтение
Заключение
Тестирование — ключевой шаг в процессе разработки, поскольку он обеспечивает правильную работу вашего приложения. Некоторые программисты предпочитают вручную тестировать свои программы, поскольку написание тестов требует значительного количества времени и энергии. К счастью, Cypress решил эту проблему, позволив разработчику писать тесты в короткие сроки.
Спасибо, что дожили до конца! Если вы почувствовали какое-либо замешательство, я советую вам поиграть с кодом и разобрать примеры.