Русский
Русский
English
Статистика
Реклама

Тестирование it-систем

Как с помощью веб-скрапинг и Puppeteer проанализировать аукционы Christies, Sothebys и Phillips. Кейс от Lansoft

29.06.2020 10:05:23 | Автор: admin
Как Web Scraping помог собрать нам данные по официальным коллекциям как у Белгазпромбанка.

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

Инструменты Web Scraping позволяют не только вручную, но и автоматически получать новые или обновленные данные для успешной реализации поставленных целей.

Для чего используется Web Scraping?

  • Сбор данных для маркетинговых исследований. Позволяет в сжатые сроки подготовить информацию для принятия стратегически важных решений в ведении бизнеса.
  • Для извлечения определенной информации (телефонов, е-мейлов, адресов) с различных сайтов для создания собственных списков.
  • Сбор данных о товарах для анализа конкурентов.
  • Очистка данных сайта перед миграцией.
  • Сбор финансовых данных.
  • В работе HR для отслеживания резюме и вакансий.


Команда Lansoft достаточно успешно освоила данный метод. Поэтому хотим поделиться с вами одним из кейсов по сбору данных для анализа датасэтов предметов искусства для нью-йоркской компании Pryph.

Pryph анализируют знаменитые аукционные дома такие как Christies, Sothebys и Phillips и резюмируют выводы о популярности различных авторов.

Кстати на этих аукционах были куплены несколько картин в нашумевшем деле Белгазпромбанка и Виктора Бабарико. По нашему мнению эти сделки никак нельзя назвать незаконными (ссылка news.tut.by/culture/349226.html)

Для работы мы выбрали инструмент Puppeteer. Это JavaScript библиотека для Node.js, которая управляет браузером Chrome без пользовательского интерфейса.

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

На самом деле есть более оптимальные способы скрапинга сайтов средствами node.js
(описаны тут habr.com/ru/post/301426).

Причины выбора Puppeteer в нашем случае были:

  • анализ всего 3 сайтов с понятными разделами и структурой;
  • активное продвижение данного инструмента компанией Google;
  • эмуляция работы реальных пользователя на UI без риска попасть в бан, как потенциальные DDOS атаки.


Итак, наша задача была зайти на сайты аукционных домов и по каждому виду аукционов собрать данные по продажам всех лотов за год с 2006 по 2019 годы.

Для примера мы вставили кусок кода, написанного на Puppeteer для извлечения ссылок картинок лотов с аукционного дома Phillips:

image

В подобном ключе команде Lansoft для каждого лота нужно было найти имя автора, описание работы, цену, детали о продаже и ссылку на предметы искусства.

image

Примеры ссылок на лоты:

www.phillips.com/detail/takashi-murakami/HK010120/110

www.sothebys.com/en/buy/auction/2020/contemporary-art-evening-auction/lynette-yiadom-boayke-cloister?locale=en

Например, на картинке выше мы видим имя автора TAKASHI MURAKAMI, название картины Blue Flower Painting B и данные по цене в $231,000-359,000. Все необходимые поля мы собирали и записывали в csv файлы, разбитые по годам.

Выглядело это так:

image

Как итог мы получили наборы csv файлов по продажам за разные годы. Размер файлов был порядка 6.000 строк. А далее клиент используя свои алгоритмы, делал анализ по трендам для различных авторов.

Результаты работы можно найти на сайте pryph.org/insights

Но в работе с Puppeteer есть некоторые нюансы:
  1. некоторые ресурсы могут блокировать доступ при обнаружении непонятной активности;
  2. эффективность Puppeteer не высока, ее можно повысить за счет троттлинга анимации, ограничения сетевых вызовов и т. д.;
  3. необходимо завершать сеанс, используя экземпляр браузера;
  4. контекст страницы/браузера отличается от контекста ноды, в которой работает приложение;
  5. использовать браузер, даже в Headless режиме не так эффективно и быстро по времени для больших анализов данных.
Подробнее..

Пишем интеграционные тесты на фронтэнд и ускоряем релизы

29.06.2020 16:21:22 | Автор: admin
Всем привет! Меня зовут Вова, я фронтэндер в Тинькофф. Наша команда отвечает за два продукта для юридических лиц. О размерах продукта я могу сказать цифрами: полный регресс каждого из продуктов двумя тестировщиками проходит от трех дней (без влияния внешних факторов).

Сроки значительные и напрашиваются на борьбу с ними. Способов борьбы несколько, основные из них:
  • Распил приложения на более мелкие продукты со своими релизными циклами.
  • Покрытие продукта тестами в соответствии с тестовой пирамидой.

Последний пункт и стал темой моей статьи.

image

Пирамида тестирования


Как мы знаем, в пирамиде тестирования три уровня: unit-тесты, интеграционные тесты и e2e-тесты. Думаю, с юнитами знакомы многие, как и с e2e, поэтому чуть подробнее остановлюсь на интеграционных тестах.

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

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

  1. Очень подробная документация.
  2. Легкий debugging тестов (у Cypress для этого сделан специальный GUI с time-travel по шагам в тесте).

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

Начало пути


В самом начале для организации кода использовался Angular Workspace с одним приложением. После установки пакета Cypress в корне приложения появилась папка cypress с конфигурацией и тестами, на данном варианте мы остановились. При попытке подготовить в package.json скрипт, необходимый для запуска приложения и прогона поверх него тестов, мы столкнулись со следующими проблемами:

  1. В index.html были зашиты некоторые скрипты, которые не нужны в интеграционных тестах.
  2. Для запуска интеграционных тестов необходимо было убедиться, что сервер с приложением запущен.

Проблему с index.html решили через отдельную конфигурацию сборки назовем ее сypress, в которой указали кастомный index.html. Как это реализовать? Находим в angular.json конфигурацию вашего приложения, открываем секцию build, добавляем там отдельную конфигурацию для Cypress и не забываем указывать эту конфигурацию для serve-режима.

Пример конфигурации для build:

"build": {..."configurations": { // Другие конфигурации"cypress": {"aot": true,"index": "projects/main-app-integrations/src/fixtures/index.html","fileReplacements": [{"replace": "projects/main-app/src/environments/environment.ts","with": "projects/main-app/src/environments/environment.prod.ts"}]}}}

Интеграция с serve:

"serve": {..."configurations": { // Другие конфигурации"cypress": {"browserTarget": "main-app:build:cypress"}}}

Из основного: для cypress конфигурации мы указываем aot сборку и подменяем файлы с environment это необходимо для создания prod-like сборки при тестировании.

Итак, с index.html разобрались, осталось поднять приложения, дождаться окончания сборки и прогнать поверх него тесты. Для этого используем библиотеку start-server-and-test и на ее основе напишем скрипты:

"main-app:cy:run": "cypress run","main-app:cy:open": "cypress open","main-app:integrations": "start-server-and-test main-app:serve:cypress http://localhost:8808/app/user/ main-app:cy:run","main-app:integrations:open": "start-server-and-test main-app:serve:cypress http://localhost:8808/app/user/ main-app:cy:open"

Как можно заметить, тут два типа скриптов: open и run. Режим open открывает GUI самого Cypress, где можно переключаться между тестами и использовать time-travel. Режим run это просто прогон тестов и получение конечного результата этого прогона, отлично подходит для запуска в CI.

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

Монорепозиторий


У описанного подхода есть очень заметная проблема: если в репозитории два и более приложений, то подход с одной папкой нежизнеспособен. Так и произошло у нас. Но случилось это довольно интересным способом. В момент внедрения Cypress мы переезжали на NX, а этот красавец из коробки дает возможность работать с Cypress. Каков принцип работы в нем:

  1. У вас есть приложение, например main-app, рядом с ним создается приложение main-app-e2e.
  2. Переименуйте main-app-e2e в main-app-integrations вы восхитительны.

Теперь вы можете прогонять интеграционные тесты одной командой ng e2e main-app-integrations. NX автоматически поднимет main-app, дождется ответа и прогонит тесты.

К сожалению, остались в стороне те, кто сейчас использует Angular Workspace, но ничего страшного, у меня есть рецепт и для вас. Файловую структуру будем использовать как и у NX:

  1. Создаем рядом с вашим приложением папку main-app-integrations.
  2. Создаем в ней папку src и заносим в нее содержимое папки cypress.
  3. Не забываем перенести cypress.json (изначально он появится в корне) в папку main-app-integrations.
  4. Правим cypress.json, указывая пути до новых папок с тестами, плагинами и вспомогательными командами (параметры integrationFolder, pluginsFile и supportFile).
  5. Cypress умеет работать с тестами в любых папках, для указания папки используется параметр
    project, поэтому меняем команду с cypress run/open на cypress run/open -project ./projects/main-app-integrations/src.

Решение под Angular Workspace максимально похоже на решение для NX, за исключением того, что папку создаем руками и она не является одним из проектов в вашем монорепозитории. В качестве альтернативы можно напрямую использовать билдер от NX для Cypress (пример репозитория на NX с Cypress, там можно подсмотреть итоговое использование nx-cypress билдера внимание на angular.json и проект
cart-e2e и products-e2e).

Visual Regressing


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

В качестве решения была взята библиотека cypress-image-snapshot. Внедрение не отняло много времени, и вот спустя 20 минут мы получили первый скриншот нашего приложения размером 1000 600 px. Радости было много, ведь интеграция и использование были слишком простыми, а полученная польза могла быть огромной.

После генерации пяти эталонных скриншотов мы запустили проверку в CI, как итог билд развалился. Оказалось, что скриншоты, созданные с помощью команд open и run, отличаются. Решение было довольно простым: снимать скриншоты только в CI-режиме, для этого убрали снятие скриншотов в local-режиме, например так:

Cypress.Commands.overwrite('matchImageSnapshot',(originalFn, subject, fileName, options) => {if (Cypress.env('ci')) {return originalFn(subject, fileName, options);}return subject;},);

В данном решении мы смотрим на параметр env в Cypress, установить его можно разными путями.

Шрифты


Локально тесты начали проходить при повторном запуске, пытаемся снова запустить их в CI. Результат можно увидеть ниже:



Довольно просто заметить разницу в шрифтах на diff-скриншоте. Эталонный скриншот был сгенерирован на macOS, а в CI на агентах установлен Linux.

Неправильное решение


Подобрали один из стандартных шрифтов (вроде это был Ubuntu Font), который давал минимальный попиксельный diff, и применили этот шрифт для текстовых блоков (сделано в
index.html, который предназначался только для cypress-тестов). Затем повысили общий diff до 0,05% и попиксельный diff до 20%. С такими параметрами мы прожили неделю до первого случая, когда потребовалось изменить текст в компоненте. В итоге билд остался зеленым, хотя скриншот мы не обновили. Текущее решение оказалось бесполезным.

Правильное решение


Исходная проблема была в разных окружениях, решение в принципе напрашивается само собой Docker. Для Cypress уже есть готовые docker-образы. Там есть разные вариации образов, нас интересует included, так как Cypress в нем уже включен в образ и не будет каждый раз заново происходить скачивание и распаковка Cypress binary (GUI Cypress запускается через бинарный файл, и скачивание вместе с распаковкой занимает больше времени, чем скачивание docker-образа).
На основе included docker-образа делаем свой docker-контейнер, для этого у себя мы сделали файл integration-tests.Dockerfile с подобным содержимым:

FROM cypress:included:4.3.0COPY package.json /app/COPY package-lock.json app/WORKDIR /appRUN npm ciCOPY / /app/ENTRYPOINT []

Хочется отметить обнуление ENTRYPOINT, это связано с тем, что он задан по умолчанию в образе cypress/included и указывает на команду cypress run, что не дает нам использовать другие команды. Также разбиваем наш dockerfile на слои, чтобы при каждом перезапуске тестов не выполнять повторно npm ci.

Добавляем .dockerignore файл (если его нет) в корень репозитория и в нем обязательно указываем node-modules/ и */node-modules/.

Для запуска в Docker наших тестов напишем bash-скрипт integration-tests.sh со следующим содержимым:

docker build -t integrations -f integration-tests.Dockerfile .docker run --rm -v $PWD/projects/main-app-integrations/src:/app/projects/main-app-integrations/src integrations:latest npm run main-app:integrations

Краткое описание: билдим наш docker-контейнер integration-tests.Dockerfile и указываем volume на папку с тестами, чтобы была возможность получить созданные скриншоты из Docker.

Снова шрифты


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



Думаю, самые внимательные заметили, что не хватает заголовка в попапе. Причина очень простая не успел загрузиться шрифт, так как не был подключен через assets, а находился на CDN.

Неправильное решение


Скачиваем шрифты с CDN, закидываем их в assets для cypress-конфигурации и в нашем кастомном
index.html для интеграционных тестов подключаем их. С таким решением мы прожили приличное время, пока у нас не изменился корпоративный шрифт. Второй раз проворачивать такую же историю желания не было.

Правильное решение


Было решено начать предзагружать все необходимые шрифты для теста в
index.html для cypress-конфигурации, выглядело это примерно так:

<linkrel="preload"href="...."as="font"type="font/woff2"crossorigin="anonymous"/>

Число падений тестов из-за не успевших загрузиться шрифтов снизилось до минимума, но не до нуля: все равно иногда шрифт не успевал загрузиться. На помощь пришло решение из KitchenSink самого Cypress waitForResource.
В нашем случае, так как уже была подключена предзагрузка шрифтов, мы просто переопределили команду visit в Cypress, в итоге она не просто навигируется на страничку, но и ждет загрузку указанных шрифтов. Также хотелось бы дополнить, что waitForResource решает проблему не только шрифтов, но и любой загружаемой статики, например картинок (из-за них у нас также ломались скриншоты, и waitForResource отлично помогло). После применения данного решения проблем со шрифтами и любой загружаемой статикой не было.

Анимации


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

Первое решение


Самое простое, что нам пришло в голову на начальном этапе: перед созданием скриншота останавливать браузер на определенное время, чтобы анимации успели завершиться. Шли по цепочке 100ms, 200ms, 500ms и в итоге 1000ms. Оглядываясь назад, я понимаю, что это решение изначально было ужасным, но хотелось именно предостеречь вас от такого же решения. Почему ужасным? Время анимаций разное, агенты в CI тоже могут подтупливать иногда, из-за чего любое время ожидания стабилизации страницы от раза к разу было разным.

Второе решение


Даже с ожиданием в 1 секунду страница не всегда успевала стать стабильной. После небольшого ресерча нашли инструмент у Angular Testability. Принцип основан на отслеживании стабильности ZoneJS:

Cypress.Commands.add('waitStableState', () => {return cy.window().then(window => {const [testability]: [Testability] = window.getAllAngularTestabilities();return new Cypress.Promise(resolve => {testability.whenStable(() => {resolve();}, 3000);});});});

Таким образом при создании скриншотов у нас вызывались две команды: cy.wait(1000) и cy.waitStableState().

С тех пор не было ни одного рандомно упавшего скриншота, но давайте вместе посчитаем, сколько времени тратилось на простаивание браузера. Предположим, у вас в тесте делается 5 скриншотов, для каждого есть стабильное время ожидания в 1 секунду и какое-то рандомное время, предположим 1,5 секунды в среднем (я не замерял среднее значение в реальности, поэтому взял из головы по собственным ощущениям). В итоге для создания скриншотов в тесте мы тратим дополнительно 12,5 секунды. Представим, что вы уже написали 20 тестовых сценариев, где в каждом тесте не менее 5 скриншотов. Получаем, что переплата за стабильность ~4 минуты при имеющихся 20 тестах.

Но даже не это самая большая проблема. Как уже обсуждалось выше, при локальном запуске тестов скриншоты не гоняются, а в CI гоняются, и из-за ожиданий на каждый скриншот срабатывали колбеки в коде, например на debounce Time, что уже создавало рандомизацию в тестах, ведь в CI и локально они проходили по-разному.

Текущее решение


Начнем с Angular-анимаций. Наш любимый фреймворк во время анимации на элементе DOM навешивает класс ng-animating. Это и стало ключом нашего решения, ведь теперь надо убедиться, что на элементе сейчас нет класса анимации. В итоге это вылилось в такую функцию:

export function waitAnimation(element: Chainable<JQuery>): Chainable<JQuery> { return element.should('be.visible').should('not.have.class', 'ng-animating');}

Кажется, ничего сложного, но именно это легло в основу наших решений. На что хочется обратить внимание в таком подходе: делая скриншот, вы должны понимать, анимация какого элемента может сделать ваш скриншот нестабильным, и перед созданием скриншота добавить assertion, который проверит, что элемент не анимируется. Но анимации также могут быть и на CSS. Как говорит сам Cypress, любые assertion на элементе ждут окончания анимации на нем подробнее тут и тут. То есть суть подхода в следующем: у нас есть анимируемый элемент, добавляем на него assertion should(be.visible)/should(not.be.visible) и Cypress сам дождется окончания анимации на элементе (возможно, кстати, решение с ng-animating не нужно и достаточно только проверок Cypress, но мы пока что используем утилиту waitAnimation).

Как сказано в самой документации, Cypress проверяет изменение позиции элемента на странице, но не все анимации про изменение позиции, есть также fadeIn/fadeOut-анимации. В этих случаях принцип решения тот же: проверяем, что элемент виден / не виден на странице.

При переезде с решения cy.wait(1000) + cy.waitStableState() на waitAnimation и Cypress Assertion пришлось потратить ~2 часа времени на стабилизацию старых скриншотов, но как итог мы получили +2030 секунд вместо +4 минут на время выполнения тестов.На данный момент мы тщательно подходим к ревью скриншотов: проверяем, что они выполнены не во время анимации элементов DOM и добавлены проверки в тесте на ожидание анимации. Например, мы часто добавляем отображение скелетонов на странице, пока данные не загрузились. Соответственно, на ревью сразу же прилетает требование, что при создании скриншотов в DOM не должен присутствовать скелетон, так как на нем находится анимация плавного исчезновения.

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

Размер скриншотов


Возможно, вы заметили интересную особенность: разрешение скриншотов по умолчанию 1000 600 px. К сожалению, есть проблема с размером окна браузера при запуске в Docker: даже если вы через Cypress поменяете размер viewportа, это не поможет. Мы нашли решение для браузера Chrome (для Electron не удалось быстро найти работающее решение, а предложенное в данном issue у нас не завелось). Для начала надо сменить браузер для запуска тестов на Chrome:

  1. Не для NX делаем с помощью аргумента --browser chrome при запуске команды cypress open/run и для run-команды указываем параметр --headless.
  2. Для NX в конфигурации проекта в angular.json с тестами указываем параметр browser: chrome, и для конфигурации, которая будет запускаться в CI, указываем headless: true.

Теперь делаем правки в plugins и получаем скриншоты размером 1440 900 px:

module.exports = (on, config) => {on('before:browser:launch', (browser, launchOptions) => {if (browser.name === 'chrome' && browser.isHeadless) {launchOptions.args.push('--disable-dev-shm-usage');launchOptions.args.push('--window-size=1440,1200');return launchOptions;}return launchOptions;});};

Даты


Тут все просто: если где-то отображается дата, связанная с текущей, снятый скриншот сегодня завтра упадет. Фиксим просто:

cy.clock(new Date(2025, 11, 22, 0).getTime(), ['Date']);

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

cy.matchImageSnapshot('salary_signing-several-payments', {blackout: ['.timer'],});

Flaky-тесты


Используя приведенные выше рекомендации, вы сможете добиться максимальной стабильности тестов, но не 100%, ведь на тесты влияет не только ваш код, но и окружение, в котором они запускаются.

В итоге какой-то процент тестов будет изредка падать, например из-за проседаний производительности агентов в CI. В первую очередь стабилизируем тест с нашей стороны: добавляем необходимые assertion перед снятием скриншотов, но на период починки таких тестов можно использовать retry упавших тестов с помощью cypress-plugin-retries.

Прокачиваем CI


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

  1. Команда npm ci.
  2. Поднятие приложения в aot-режиме.
  3. Запуск интеграционных тестов.

Взглянем на первый и второй пункт и поймем, что похожие шаги выполняются в другом вашем билде в CI билд со сборкой приложения.
Основное отличие это запуск не ng serve, а ng build. Таким образом, если сможем получить уже собранное приложение в билде с интеграционные тестами и поднять сервер с ним, то мы сможем сократить время выполнения билда с тестами.

Почему нам это потребовалось? Просто приложение у нас большое и выполнение
npm ci + npm start в aot-режиме на агенте в CI занимало ~15 минут, что в принципе требовало больших усилий от агента, и еще поверх этого запускались интеграционные тесты. Предположим, у вас уже написано 20+ тестов и на 19-м тесте у вас падает браузер, в котором прогоняются тесты, из-за большой нагрузки на агент. Как вы понимаете, перезапуск билда это снова ожидание установки зависимостей и запуска приложения.

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

Сервер со статикой


Нам нужна замена ng serve по поднятию сервера с нашим приложением. Вариантов много, начну с нашего первого angular-http-server. В его настройке нет ничего сложного: устанавливаем зависимость, указываем, в какой папке лежит наша статика, указываем, на каком порту поднять приложение, и радуемся.

Этого решения нам хватило на целых 20 минут, а потом мы поняли, что какие-то запросы хотим проксировать на тестовый контур. Подключить проксирование для angular-http-server не получилось. Конечным решением стало поднятие сервера на Express. Для решения задачи использовался сам express и express-http-proxy. Раздавать нашу статику будем с помощью
express.static, в итоге получается скрипт, похожий на этот:

const express = require('express');const appStaticPathFolder = './dist';const appBaseHref = './my/app';const port = 4200;const app = express();app.use((req, res, next) => {const accept = req.accepts().join().replace('*/*', '');if (accept.includes('text/html')) {req.url = baseHref;}next();});app.use(appBaseHref, express.static(appStaticPathFolder));app.listen(port);

Интересным моментом здесь является то, что перед прослушиванием роута по baseHref приложения мы также обрабатываем все запросы и ищем запрос на index.html. Это сделано для случаев, когда в тестах осуществляется переход на страницу приложения, путь которой отличается от baseHref. Если не сделать данный трюк, то при переходе на любую страницу вашего приложения, кроме главной, будет прилетать 404 ошибка. Теперь добавим щепотку проксирования:

const proxy = require('express-http-proxy');app.use('/common',proxy('https://qa-stand.ru', {proxyReqPathResolver: req => '/common' + req.url,}),);

Чуть подробнее рассмотрим происходящее. Есть константы:

  1. appStaticForlderPath папка, где находится статика вашего приложения.
  2. appBaseHref возможно, у вашего приложения есть baseHref, если нет можно указать /.

Проксируем же мы все запросы, начинающиеся на /common, причем при проксировании сохраняем тот же путь, который был у запроса, с помощью настройки proxyReqPathResolver. Если ее не использовать, то все запросы будут просто идти наhttps://qa-stand.ru.

Кастомизация index.html


Нам нужно было решить проблему с кастомным index.html, который мы использовали при ng serve приложения в режиме Cypress. Напишем простой скрипт на node.js. Исходными параметрами у нас был index.modern.html, требовалось превратить его в index.html и удалить оттуда ненужные скрипты:

const fs = require('fs');const appStaticPathFolder = './dist';fs.copyFileSync(appStaticPathFolder + '/index.modern.html', appStaticPathFolder + '/index.html');fs.readFile(appStaticPathFolder + '/index.html', 'utf-8', (err, data) => {const newValue = data.replace('<script type="text/javascript" src="http://personeltest.ru/aways/habr.com/auth.js"></script>','',).replace('<script type="text/javascript" src="http://personeltest.ru/aways/habr.com/analytics.js"></script>','',);fs.writeFileSync(appStaticPathFolder + '/index.html', newValue, 'utf-8');});

Скрипты


Очень не хотелось для запуска тестов в CI делать еще раз npm ci всех зависимостей (ведь это уже делалось в таске с билдом приложения), поэтому появилась идея создать отдельную папку под все эти скрипты со своим package.json. Назовем папку, например, integration-tests-scripts и закинем туда три файла: server.js, create-index.js, package.json. Первые два файла были описаны выше, разберем теперь содержимое package.json:

{"name": "cypress-tests","version": "0.0.0","private": true,"scripts": {"create-index": "node ./create-index.js","main-app:serve": "node ./server.js","main-app:cy:run": "cypress run --project ./projects/main-app-integrations ","main-app:integrations": "npm run create-index && start-server-and-test main-app:serve http://localhost:4200/my/app/ main-app:cy:run"},"devDependencies": {"@cypress/webpack-preprocessor": "4.1.0","@types/express": "4.17.2","@types/mocha": "5.2.7","@types/node": "8.9.5","cypress": "4.1.0","cypress-image-snapshot": "3.1.1","express": "4.17.1","express-http-proxy": "^1.6.0","start-server-and-test": "1.10.8","ts-loader": "6.2.1","typescript": "3.8.3","webpack": "4.41.6"}}

В package.json присутствуют только зависимости, необходимые для прогона интеграционных тестов (с поддержкой typescript и скриншот-тестирования) и скрипты по запуску сервера, созданию index.html и известный из главы по запуску интеграционных тестов в Angular Workspace start-server-and-test.

Запуск


Оборачиваем выполнение интеграционных тестов в новый Dockerfile integration-tests-ci.Dockerfile:

FROM cypress/included:4.3.0COPY integration-tests-scripts /app/WORKDIR /appRUN npm ciCOPY projects/main-app-integrations /app/projects/main-app-integrationsCOPY dist /app/distCOPY tsconfig.json /app/ENTRYPOINT []

Суть проста: копируем и разворачиваем папку integration-tests-scripts в корень приложения и копируем все, что необходимо для запуска тестов (у вас этот набор может отличаться). Основные отличия от предыдущего файла в том, что мы не копируем все приложение внутрь docker-контейнера, просто минимальная оптимизация времени выполнения тестов в CI.

Создаем файл integration-tests-ci.sh со следующим содержимым:

docker build -t integrations -f integration-tests-ci.Dockerfile .docker run --rm -v $PWD/projects/main-app-integrations/src:/app/projects/main-app-integrations/src integrations:latest npm run main-app:integrations

Во время запуска команды с тестами корневым станет package.json из папки integration-tests-scripts и в нем запустится команда main-app:integrations. Соответственно, так как эта папка развернется в корень, то и пути до папки со статикой вашего приложения нужно указывать с мыслью, что запускаться все будет из корня, а не из папки integration-tests-scripts.

Хочу также сделать небольшую ремарку: конечный bash-скрипт для запуска интеграционных тестов по мере его эволюции я называл по-разному. Так делать не нужно, это было сделано только для удобства чтения этой статьи. У вас должен всегда оставаться один файл, например integration-tests.sh, который вы уже развиваете. Если у вас несколько приложений в репозитории и их способы подготовки различаются, можно разруливать либо переменными в bash, либо разными файлами под каждое приложение зависит от ваших потребностей.

Итог


Информации было много думаю, теперь стоит подвести итог на основе написанного выше.
Подготовка средств для локального написания и прогона тестов с щепоткой скриншот-тестирования:

  1. Ставим зависимость для Cypress.
  2. Подготавливаем папку с тестами:
    1. Angular Single Application оставляем все в папке cypress.
    2. Angular Workspace создаем папку имя приложения-integrations рядом с приложением, на которое будут гоняться тесты, и переносим в нее все из папки cypress.
    3. NX переименовываем проект из имя приложения-e2e в имя-приложения-integrations.

  3. Кастомная cypress-сборка для поднятия приложения делаем в build-разделе конфигурацию Cypress, указываем там aot, подмену на свой отдельный index.html, подмену файла environment на prod-файл и указываем в serve-разделе сборку Cypress (данный пункт необходим, если вам нужны какие-то отличия от prod-сборки, в противном случае можно пропустить).
  4. Скрипты по запуску и прогону тестов:
    1. Angular Single Application готовим скрипт с serve-ом cypress-сборки и запуску тестов, комбинируем все это с помощью start-server-and-test.
    2. Angular Workspace аналогично с Angular Single Application, только указываем путь до тестов при запуске cypress run/open.
    3. NX запускаем тесты с помощью команд ng e2e.

  5. Подмешиваем скриншот-тестирование:
    1. Добавляем зависимость cypress-image-snapshot.
    2. Переопределяем стандартную команду по сравнению скриншотов для запуска ее только в CI.
    3. В тестах не делаем скриншотов на рандоме. Если скриншоту предшествует анимация, обязательно ждем ее например, добавляем Cypress Assertion на анимируемый элемент.
    4. Дату мокируем через cy.clock либо используем опцию blackout при снятии скриншота.
    5. Любую подгружаемую статику в runtime ожидаем через кастомную команду cy.waitForResource (картинки, шрифты и т. д.).

  6. Оборачиваем все это в Docker:
    1. Готовим Dockerfile.
    2. Создаем bash-файл.


Прогоняем тесты поверх собранного приложения:

  1. В CI учимся прокидывать между билдами артефакты собранного приложения (остается на вас).
  2. Готовим папку integration-tests-scripts:
    1. Скрипт по поднятию сервера вашего приложения.
    2. Скрипт по изменению вашего index.html (если вас устраивает изначальный index.html можно скипать).
    3. Добавляем в папку package.json с необходимыми скриптами и зависимостями.
    4. Готовим новый Dockerfile.
    5. Создаем bash-файл.


Полезные ссылки


  1. Angular Workspace + Cypress + CI в данном примере я создал базу для Angular Workspace приложения с накрученным CI на основе скриптов, описанных в статье (без поддержки typescript).
  2. Cypress обратите внимание на раздел trade-offs.
  3. Start-server-and-test запуск сервера, ожидание ответа и запуск тестов.
  4. Cypress-image-snapshot библиотека для скриншот-тестирования.
  5. Cypress recipes готовые наработки по Cypress, чтобы не изобретать свои велосипеды.
  6. Flaky Tests статья про нестабильные тесты, в конце есть ссылка на статью от Google.
  7. Github Action Cypress дает возможность использовать предустановленные конфиги для GitHub Action, в README куча примеров, из интересного встроенная поддержка wait-on. Также есть пример с docker.
Подробнее..

Sentry удаленый мониторинг багов в фронтенд приложениях React

03.07.2020 10:08:54 | Автор: admin

Мы изучаем использование Sentry с React.



Эта статья является частью серии, начинающейся с сообщения об ошибках Sentry на примере: Часть 1.


Реализация React


Сначала нам нужно добавить новый проект Sentry для этого приложения; с сайта Sentry. В этом случае мы выбираем React.


Мы вновь реализуем наши две кнопки, Hello и Error, приложение с React. Мы начинаем с создания нашего стартового приложения:


npx create-react-app react-app

Затем мы импортируем пакет Sentry:


yarn add @sentry/browser

и инициализируем его:


react-app / src / index.js


...import * as Sentry from '@sentry/browser';const RELEASE = '0.1.0';if (process.env.NODE_ENV === 'production') {  Sentry.init({    dsn: 'https://303c04eac89844b5bfc908ceffc6757c@sentry.io/1289887',    release: RELEASE,  });}...

Наблюдения:


  • Во время разработки у нас есть другие механизмы для наблюдения за проблемами, например консоль, поэтому мы включаем Sentry только для производственных сборок

Затем мы реализуем наши кнопки Hello и Error и добавляем их в приложение:


react-app / src / Hello.js


import React, { Component } from 'react';import * as Sentry from '@sentry/browser';export default class Hello extends Component {  state = {    text: '',  };  render() {    const { text } = this.state;    return (      <div>        <button          onClick={this.handleClick}        >          Hello        </button>        <div>{text}</div>      </div>    )  }  handleClick = () => {    this.setState({      text: 'Hello World',    });    try {      throw new Error('Caught');    } catch (err) {      if (process.env.NODE_ENV !== 'production') {        return;      }      Sentry.captureException(err);    }  }}

react-app / src / MyError.js


import React, { Component } from 'react';export default class MyError extends Component {  render() {    return (      <div>        <button          onClick={this.handleClick}        >          Error        </button>      </div>    )  }  handleClick = () => {    throw new Error('Uncaught');  }}

react-app / src / App.js


...import Hello from './Hello';import MyError from './MyError';class App extends Component {  render() {    return (      <div className="App">        ...        <Hello />        <MyError />      </div>    );  }}export default App;

Проблема (Исходные Карты)


Мы можем протестировать Sentry с производственной сборкой, введя:


yarn build

и из build папки введите:


npx http-server -c-1

Проблема, с которой мы немедленно столкнемся, заключается в том, что записи об ошибке Sentry ссылаются на номера строк в уменьшенном пакете; не очень полезно.



Служба Sentry объясняет это, вытягивая исходные карты для уменьшенного пакета после получения ошибки. В этом случае мы бежим от localhost (недоступного службой Sentry).


Решения (Исходные Карты)


Решение этой проблемы сводится к запуску приложения с общедоступного веб-сервера. Одна простая кнопка ответа на него, чтобы использовать сервис GitHub Pages (бесплатно). Шаги для использования обычно следующие:


  1. Скопируйте содержимое папки build в папку docs в корневом каталоге репозитория.


  2. Включите GitHub Pages в репозитории (из GitHub), чтобы использовать папку docs в master ветви


  3. Перенесите изменения на GitHub



Примечание: после того, как я понял, что мне нужно использовать create-create-app функция домашней страницы для запуска приложения. Сводилось к добавлению следующего к package.json:


"homepage": "https://larkintuckerllc.github.io/hello-sentry/"

Окончательная версия запущенного приложения доступна по адресу:


https://larkintuckerllc.github.io/hello-sentry/


Иллюстрация Пойманных Ошибок


Давайте пройдем через нажатие кнопки Hello.



С ошибкой, появляющейся следующим образом:



Наблюдения:


  • Этот отчет об ошибке не может быть более ясным, BRAVO.

Иллюстрация Неучтенных Ошибок


Аналогично, давайте пройдем через нажатие кнопки Error.



С ошибкой, появляющейся следующим образом:



Лучшая обработка неучтенных ошибок (рендеринг)


Введение Границ Ошибок

Ошибка JavaScript в части пользовательского интерфейса не должна нарушать работу всего приложения. Чтобы решить эту проблему для пользователей React, React 16 вводит новое понятие "границы ошибок".

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



Новое поведение для необнаруженных ошибок

Это изменение имеет важное значение. Начиная с React 16, ошибки, которые не были пойманы какой-либо границей ошибок, приведут к размонтированию всего дерева компонентов React.

Dan Abramov Error Handling in React 16

Важное уточнение, которое заняло у меня некоторое время, прежде чем я понял это, заключается в том, что вышеупомянутое поведение работает только с ошибками, генерируемыми в методе рендеринга (или, что более вероятно, в любом из методов жизненного цикла). Например, использование границ ошибок не принесло бы никакой пользы с нашей кнопкой Error; эта ошибка была в обработчике щелчка.


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


react-app / src / MyRenderError


import React, { Component } from 'react';export default class MyRenderError extends Component {  state = {    flag: false,  };  render() {    const { flag } = this.state;    return (      <div>        <button          onClick={this.handleClick}        >          Render Error        </button>        { flag && <div>{flag.busted.bogus}</div> }      </div>    )  }  handleClick = () => {    this.setState({      flag: true,    });  }}

Наблюдение:


  • При нажатии кнопки, React будет отображаться flag.busted.bogus, которая порождает ошибку


  • Без границы ошибки все дерево компонентов будет размонтировано



Затем мы пишем наш код границы ошибки (использует новый метод жизненного цикла componentDidCatch); это, по сути, пример, приведенный в статье Дэна Абрамова:


react-app / src / ErrorBoundary.js


import React, { Component } from 'react';import * as Sentry from '@sentry/browser';export default class ErrorBoundary extends Component {  constructor(props) {    super(props);    this.state = { hasError: false };  }  componentDidCatch(err, info) {    this.setState({ hasError: true });    Sentry.captureException(err);  }  render() {    if (this.state.hasError) {      return <h1>Something went wrong.</h1>;    }    return this.props.children;  }}

Наконец, мы используем этот компонент:


react-app / src / App.js


...import MyRenderError from './MyRenderError';class App extends Component {  render() {    return (      <ErrorBoundary>        <div className="App">          ...        </div>      </ErrorBoundary>    );  }}...

При этом нажатие кнопки Render Error отображает резервный пользовательский интерфейс и сообщает об ошибке Sentry.




Завершение


Надеюсь, вам было это полезно.


P.S. Телеграм чат по Sentry https://t.me/sentry_ru

Подробнее..

Блокируем заливку приватных ключей, архивов, больших файлов и не только в Gitlab CE

06.07.2020 10:05:56 | Автор: admin

Git hooks инструмент, помогающий держать в порядке ваш репозиторий. Можно настроить автоматические правила оформления ваших коммитов.


Все вы наверное знаете про pre-commit проверку вашего кода перед коммитом. Но ведь не все можно проверить перед коммитом. Некоторые ограничения хочется использоваться глобально на всем Gitlab.


Кто запутался в pre-commit и pre-receive хуках, в этом посте описываются различия между ними https://blog.gitguardian.com/git-hooks-automated-secrets-detection/ в абзаце "What are git hooks?".


Если у вас Gitlab Enterprise Edition, вы можете настроить хуки, которые описаны в посте через WEB интерфейс.


Но что делать, если у вас Gitlab Community Edition?


В этой статье будут описаны 5 pre-receive хуков, которые выполняются на сервере Gitlab Community Edition:


  • block_confidentials.sh Блокирование отправки приватных ключей и AWS токенов
  • block_file_extensions.sh Блокирование отправки архивов (Regex настраивается)
  • check-large-files.sh Блокирование отправки больших файлов (Размер настраивается)
  • reject-not-allowlist-email.sh Блокирование коммитов с email не из allow списка (Список email доменов настраивается)
  • require-issue.sh Блокирование коммитов без issue в названии (Список issue настраивается)

В основном хуки взяты из репозитория platform-samples в директории pre-receive-hooks (относится к GitHub Enterprise).


Весь исходный код серверных хуков вы можете посмотреть на Github https://github.com/patsevanton/git-server-pre-receive-hooks


Установка на Gitlab


  • Необходимо создать директорию /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d/
  • Скопировать в эту директорию хуки
  • Не забыть выставить права запуска для хуков (chmod +x файл-хука)

Блокирование отправки приватных ключей и AWS токенов


В файле block_confidentials.sh настраиваем список regex_list, который описывает конфиденциальную информацию.


# Define list of REGEX to be searched and blockedregex_list=(  # block any private key file  '(\-){5}BEGIN\s?(RSA|OPENSSH|DSA|EC|PGP)?\s?PRIVATE KEY\s?(BLOCK)?(\-){5}.*'  # block AWS API Keys  'AKIA[0-9A-Z]{16}'  # block AWS Secret Access Key (TODO: adjust to not find validd Git SHA1s; false positives)  # '([^A-Za-z0-9/+=])?([A-Za-z0-9/+=]{40})([^A-Za-z0-9/+=])?'  # block confidential content  'CONFIDENTIAL')

Добавляем в репозиторий приватный ключ, делаем коммит и при git push получаем ошибку.



Блокирование отправки архивов


В файле block_file_extensions.sh настраиваем case *.zip|*.gz|*.tgz, в котором указываются расширения файлов, которые будут блокироваться.


Добавляем в репозиторий zip архив, делаем коммит и при git push получаем ошибку.



Блокирование отправки больших файлов


В файле check-large-files.sh настраиваем параметр maxsize, который указывает размер файла в мегабайтах, выше которого отправка будет блокироваться.


Добавляем в репозиторий файл больше 1 мегабайта, делаем коммит и при git push получаем ошибку.



Блокирование коммитов с email не из allow списка


В файле reject-not-allowlist-email.sh настраиваем список email-доменов, для которых разрешены коммиты.


declare -a DOMAIN_ARRAY=("group1.com" "group2.com")

Меняем почту в git на ту, которой нет в разрешенном списке.


git config user.email user1@group3.com

Добавляем в репозиторий любой файл, делаем коммит и при git push получаем ошибку.



Блокирование коммитов без issue в названии


Этот серверный хук был взят из блога Majilesh.


В файле require-issue.sh настраиваем список commit_format, для которых разрешены коммиты.


commit_format="(JIRA|PROJECTKEY|MULE|ECOM|SAP|XLR-[1-9]+Merge)"

Добавляем в репозиторий любой файл, делаем коммит, в названии которого нет слов из commit_format и при git push получаем ошибку.



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


Telegram чат по Gitlab https://t.me/ru_gitlab

Подробнее..

2.07 онлайн-митап про микросервисы и Unit-тесты

24.06.2020 20:23:04 | Автор: admin
В четверг 2 июля собираемся обсудить очередной опыт распила монолита и рассказать, как Unit-тестирование сокращает время разработки. Старт в 16:00 мск, в 17:00 по Ижевску.

Участие бесплатно, нужна регистрация.

Упрощаем себе жизнь с помощью Unit-тестирования


Юнит-тесты повышают скорость разработки согласны?

  • расскажу, почему нетестируемые проекты увеличивают сроки релизов;
  • приведу аргументы в пользу написания юнит-тестов. Рассмотрим, почему хороший дизайн тестируемый, а обратное неверно;
  • плохие юнит-тесты хуже, чем ничего. Поговорим про требования к юнит-тестам. Например, почему важна изолированность или скорость выполнения тестов;
  • расскажу про лучшие практики юнит-тестирования с примерами на NUnit.



Как отпилить часть монолита и не сойти с ума


Я расскажу о нашем опыте отделения части функциональности сервиса в отдельный микросервис:

  • неправильная оценка задачи и её последствия. Как избежать ситуации, когда задача распухает, сроки переносятся, и все нервничают;
  • что делать и чего не делать с зависимостями при разделении проектов;
  • компромиссы, на которые должен идти разработчик или как перестать искать идеальные решения и начать делать рабочие.


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

А ещё смотрите там же на сайте анонс митапа по управлению проектами 9 июля.

И приходите, будем рады!
Подробнее..

Recovery mode 2.07 онлайн-митап про микросервисы и Unit-тесты

25.06.2020 00:10:20 | Автор: admin
В четверг 2 июля собираемся обсудить очередной опыт распила монолита и рассказать, как Unit-тестирование сокращает время разработки. Старт в 16:00 мск, в 17:00 по Ижевску.

Участие бесплатно, нужна регистрация.

Упрощаем себе жизнь с помощью Unit-тестирования


Юнит-тесты повышают скорость разработки согласны?

  • расскажу, почему нетестируемые проекты увеличивают сроки релизов;
  • приведу аргументы в пользу написания юнит-тестов. Рассмотрим, почему хороший дизайн тестируемый, а обратное неверно;
  • плохие юнит-тесты хуже, чем ничего. Поговорим про требования к юнит-тестам. Например, почему важна изолированность или скорость выполнения тестов;
  • расскажу про лучшие практики юнит-тестирования с примерами на NUnit.


Как отпилить часть монолита и не сойти с ума


Я расскажу о нашем опыте отделения части функциональности сервиса в отдельный микросервис:

  • неправильная оценка задачи и её последствия. Как избежать ситуации, когда задача распухает, сроки переносятся, и все нервничают;
  • что делать и чего не делать с зависимостями при разделении проектов;
  • компромиссы, на которые должен идти разработчик или как перестать искать идеальные решения и начать делать рабочие.


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

А ещё смотрите там же на сайте анонс митапа по управлению проектами 9 июля.

И приходите, будем рады!
Подробнее..

DINS QA EVENING (online) почему тестировщик должен построить CICD и как обеспечить качество на большом проекте

26.06.2020 18:17:05 | Автор: admin
Приглашаем на онлайн-митап DINS QA EVENING, он состоится 9 июля в 19:00.

Этим вечером Дмитрий Красильников из DINS расскажет, почему именно тестировщик должен построить CI/CD, и объяснит, как это сделать. Дмитрий Борисов из Nexign поговорит об эволюции инструментов и подходов обеспечения качества на большом проекте.

Для участия, пожалуйста, зарегистрируйтесь.
Подробная программа и информация о спикерах под катом.

image


Программа


19:00-19:40 QAOps, или почему тестировщик должен построить CI/CD
Дмитрий Красильников, DINS


Все мы любим небольшие релизы и микросервисы, благодаря которым они существуют. Ведь чем меньше наши сервисы, тем их больше, следовательно, мы выпускаем больше релизов. Но без автоматизации поставок они все застрянут в очереди на деплой у команды эксплуатации, и, как только мы с этим столкнемся, наши микросервисы станут сервисами, а сервисы монолитными монстрами. Что, в свою очередь, приводит к росту регрессии и количеству flaky-тестов, которые убьют непрерывную интеграцию. На примере нашей облачной распределенной системы я покажу, как выстроить процесс непрерывной поставки в условиях SLA 99,999 и перейти к микросервисам.

Доклад будет полезен ведущим специалистам и менеджерам.

Дмитрий Красильников Sr. QA Engineer. Хороший тестировщик и плохой человек. Вчера полностью ломал приложения для Smart TV, а сегодня держит в напряжении разработчиков компании DINS.

19:40-20:30 Развитие пайплайна разработки автотестов на примере большого проекта
Дмитрий Борисов, Nexign


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

Доклад будет интересен разработчикам автотестов и QA-тимлидам, которые заинтересованы в автоматизации проверок своего кода и упрощении процесса code review.

Дмитрий Борисов ведущий инженер-программист, TeamLead группы автоматизации интеграционного и системного тестирования в Nexign. Дмитрий с командой реализовали фреймворк автоматизации тестирования для bss-решения крупного мобильного оператора на Python и Robot Framework.

Как присоединиться


Участие бесплатное. В день проведения митапа мы пришлем ссылку на трансляцию на указанный при регистрации имейл.

Как проходят встречи


Записи предыдущих митапов можно посмотреть на нашем YouTube-канале.

О нас


DINS IT EVENING это место встречи и обмена знаниями технических специалистов по направлениям Java, DevOps, QA и JS. Несколько раз в месяц мы организуем встречи, чтобы обсудить с коллегами из разных компаний интересные кейсы и темы. Открыты для сотрудничества, если у вас есть наболевший вопрос или тема, которой хочется поделиться пишите на itevening@dins.ru!
Подробнее..

Анонс онлайн-митапа по тестированию три доклада про плохие процессы в команде, хотфиксы и первые шаги в автоматизации

07.07.2020 10:10:24 | Автор: admin

image


Наши тестировщики из Новосибирска соскучились по встречам с единомышленниками и приготовили онлайн-митап, который нельзя пропустить. Катя Синько порассуждает о том, как занять проактивную позицию и улучшить выстроенные процессы в команде. Инна Шундеева расскажет, как стать автоматизатором и не отступать перед трудностями. А Люда Малеева из Miro поделится советами, как организовать релизы без багов и что правильно делать, если на боевой их всё-таки нашли.


Когда: 9 июля в 16:00 (Мск)
Где: Ютуб-канал Контура


Менять процессы нельзя страдать Катя Синько, Контур


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


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


Качество релизов ответственность команды Люда Малеева, Miro


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


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


5 открытий: дневники автоматизатора Инна Шундеева, Контур


Всё больше тестировщиков руками смотрят в сторону автоматизации. Но этот путь кажется начинающим сложным и тернистым. А как стать автоматизатором, который смог?


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


До встречи! Жмите колокольчик на Ютубе, готовьте прохладительные напитки, подключайтесь и смотрите онлайн-митап Kontur Tech Talks по тестированию.

Подробнее..

Что такое CI (Continuous Integration)

25.06.2020 16:23:50 | Автор: admin
CI (Continuous Integration) в дословном переводе непрерывная интеграция. Имеется в виду интеграция отдельных кусочков кода приложения между собой. Чем чаще мы собираем код воедино и проверяем:

  • Собирается ли он?
  • Проходят ли автотесты?

Тем лучше! CI позволяет делать такие проверки автоматически. Он используется в продвинутых командах разработки, которые пишут не только код, но и автотесты. Его спрашивают на собеседованиях хотя бы понимание того, что это такое. Да, даже у тестировщиков.

Поэтому я расскажу в статье о том, что это такое. Как CI устроен и чем он пригодится вашему проекту.



Содержание




Что такое CI


CI это сборка, деплой и тестирование приложения без участия человека. Сейчас объясню на примере.

Допустим, что у нас есть два разработчика Маша и Ваня. И тестировщица Катя.

Маша пишет код. Добавляет его в систему контроля версий (от англ. Version Control System, VCS). Это что-то типа дропбокса для кода место хранения, где сохраняются все изменения и в любой момент можно посмотреть кто, что и когда изменял.

Потом Ваня заканчивает свой кусок функционала. И тоже сохраняет код в VCS.



Но это просто исходный код набор файликов с расширением .java, или любым другим. Чтобы Катя могла протестировать изменения, нужно:

  1. Собрать билд из исходного кода
  2. Запустить его на тестовой машине

Сборка билда это когда мы из набора файликов исходного кода создаем один запускаемый файл:



Собрать билд можно вручную, но это лишний геморрой: нужно помнить, что в каком порядке запустить, какие файлики зависят друг от друга, не ошибиться в команде Обычно используют специальную программу. Для java это Ant, Maven или Gradle. С помощью сборщика вы один раз настраиваете процесс сборки, а потом запускаете одной командой. Пример запуска для Maven:

mvn clean install

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



Но собрать билд получить приложение для тестирования. Его еще надо запустить! Этим занимается сервер приложения. Серверы бывают разные: wildfly, apache, jetty

Если это wildfly, то нужно:

  1. Подложить билд в директорию standalone/deployments
  2. Запустить сервер (предварительно один раз настроив службу)

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



А вот если убрать из этой схемы человека мы получим CI!



CI это приложение, которое позволяет автоматизировать весь процесс. Оно забирает изменения из репозитория с кодом. Само! Тут есть два варианта настройки:

  • CI опрашивает репозиторий Эй, ку-ку, у тебя есть изменения?? раз в N часов / минут, как настроите.

  • Репозиторий машет CI рукой при коммите: Эй, привет! А у меня обновление тут появилось! (это git hook или аналог в вашей VCS)


Когда CI получило изменения, оно запускает сборку билда и автотесты.

Если сборка провалилась (тесты упали, или не получилось собрать проект), система пишет элекронное письмо всем заинтересованным лицам:

  • Менеджеру проекта (чтобы знал, что делается!)
  • Разработчику, который внес изменения
  • Любому другому как настроите, так и будет.



Если сборка прошла успешно, CI разворачивает приложение на тестовой машине. И в итоге Катька может тестировать новую сборку!



Да, разумеется, один раз придется это все настроить рассказать серверу CI, откуда забирать изменения, какие автотесты запускать, как собирать проект, куда его потом билдить Но зато один раз настроил а дальше оно само!

Автотесты тоже придется писать самим, но чтож поделать =)



Если на пальцах, то система CI (Continuous Integration) это некая программа, которая следит за вашим Source Control, и при появлении там изменений автоматически стягивает их, билдит, гоняет автотесты (конечно, если их пишут).

В случае неудачи она дает об этом знать всем заинтересованным лицам, в первую очередь последнему коммитеру. (с) habr.com/ru/post/352282



Программы CI


Наиболее популярные Jenkins и TeamCity.

Но есть куча других вариаций CruiseControl, CruiseControl.Net, Atlassian Bamboo, Hudson, Microsoft Team Foundation Serve.


Как это выглядит


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

Когда я захожу в систему, я вижу все задачи. Задачи бывают разные:

  • Собрать билд
  • Прогнать автотесты
  • Развернуть приложение на тестовом стенде
  • Прогнать на этом стенде GUI тесты (или тесты Postman-a)
  • Оповестить всех заинтересованных по email о результатах сборки и тестирования

Задачи можно группировать. Вот, скажем, у нас есть проект CDI. Зайдя внутрь, я вижу задачи именно по этому проекту:



  • CDI Archetype и CDI Core это билды. Они проверяют, что приложение вообще собирается. Отрабатывают за пару минут и прогоняются на каждое изменение кода.
  • CDI Core with tests сборка проекта со всеми автотестами, которых, как видно на скрине, 4000+ штук. Тесты идут полчаса, но тоже прогоняются на каждый коммит.

Помимо автоматизированного запуска, я могу в любой момент пересобрать билд, нажав на кнопку Run:



Это нужно, чтобы:

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

Когда я заходу внутрь любой задачи я вижу историю сборок. Когда она запускалась? Кто при этом вносил изменения и сколько их было? Сколько тестов прошло успешно, а сколько развалилось?



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


Как CI устроен


Как и где CI собирает билд и прогоняет автотесты? Я расскажу на примере TeamCity, но другие системы работают примерно также.

Сам TeamCity ничего не собирает. Сборка и прогон автотестов проходят на других машинах, которые называются агенты:



Агент это простой компьютер. Железка или виртуальная машина, не суть. Но как этот комьютер понимает, что ему надо сделать?

В TeamCity есть сервер и клиент. Сервер это то самое приложение, в котором вы потом будете тыкать кнопочки и смотреть красивую картинку насколько все прошло успешно. Он устанавливается на одну машину.



А приложение-клиент устанавливается на машинах-агентах. И когда мы нажимаем кнопку Run на сервере:



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



Сервер отображает пользователю результат плюс рассылает email всем заинтересованным лицам.

При этом мы всегда видим, на каком конкретно агенте проходила сборка:



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

Допустим, исходно у нас был только один билд-агент Buran. Название может быть абсолютно любым, его придумывает администратор, когда подключает новую машину к TeamCity как билд-агента.

Мы собирали на нем проект, проводили автотесты все работало. А потом закупили вторую машинку и назвали Apollo. Вроде настроили также, как Буран, даже операционную систему одинаковую поставили CentOs 7.



Но запускаем сборку на Apollo падает. Причем падает странно, не хватает памяти или еще чего-то. Перезапускаем на Apollo снова падает. Запускаем на Буране проходит успешно!



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



Мы также можем для каждой сборки настроить список агентов, на которых она может выполняться. Зачем? Например, у нас на половине агентов линукс, а на половине винда. А сборку мы только под одну систему сделали. Или на винде вылезает какой-то плавающий баг, но исправлять его долго и дорого, а все клиенте на линуксе ну и зачем тогда?

А еще бывает, что агентов делят между проектами, чтобы не было драки этот проект использует Бурана и Аполло, а тот Чип и Дейла. Фишка ведь в том, что на одном агенте может выполняться только одно задание. Поэтому нет смысла покупать под агент крутую тачку, сразу кучу тестов там все равно не прогнать.

В итоге как это работает: сначала админ закупает компьютеры под агенты и устанавливает на них клиентское приложение TeamCity. Слишком крутыми они быть не должны, потому что много задач сразу делать не будут.



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

На отдельной машине админ устанавливает сервер TeamCity. И конфигурирует его настраивает сборки, указывает, какие сборки на каких машинах можно гонять, итд. На сервере нужно место для хранения артефактов результатов выполнения сборки.

У нас есть два проекта Единый клиент и Фактор, которые взаимодействуют между собой. Тестировщик Единого клиента может не собирать Фактор локально. Он запускает сборку в TeamCity и скачивает готовый билд из артефактов!

Дальше уже разработчик выбирает, какую сборку он хочет запустить и нажимает Run. Что в этот момент происходит:

1. Сервер TeamCity проверяет по списку, на каких агентах эту сборку можно запускать. Потом он проверяет, кто из этих агентов в данный момент свободен:



Нашел свободного? Отдал ему задачку!



Если все агенты заняты, задача попадает в очередь. Очередь работает по принципу FIFO first in, first out. Кто первый встал того и тапки.



Очередь можно корректировать вручную. Так, если я вижу, что очередь забита сборками, которые запустила система контроля версий, я подниму свою на самый верх. Если я вижу, что сборки запускали люди значит, они тоже важные, придется подождать.



Это нормальная практика, если мощностей агентов не хватает на всей и создается очередь. Смотришь, кто ее запустил:

  • Робот? Значит, это просто плановая проверка, что ничего лишнего не разломалось. Такая может и подождать 5-10-30 минут, ничего страшного
  • Коллега? Ему эта сборка важна, раз не стал ждать планового запуска. Встаем в очередь, лезть вперед не стоит.

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

  • поднять свою очередь на самый верх, чтобы она запустилась на первом же освободившемся агенте
  • зайти на агент, отменить текущую сборку
  • перезапустить ее! Хоть она и попадет в самый низ очереди, но просто отменять сборку некрасиво

2. Агент выполняет задачу и возвращает серверу результат



3. Сервер отрисовывает результат в графическом интерфейсе и сохраняет артефакты. Так я могу зайти в TeamCity и посмотреть в артефактах полные логи прошедших автотестов, или скачать сборку проекта, чтобы развернуть ее локально.

Настоятельно рекомендуется настроить заранее количество сборок, которые CI будет хранить. Потому что если в артефактах лежат билды по 200+ мб и их будет много, то очередной запуск сборки упадет с ошибкой кончилось место на диске:



4. Сервер делает рассылку по email тут уж как настроите. Он может и позитивную рассылку делать сборка собралась успешно, а может присылать почту только в случае неудачи Ой-ей-ей, что-то пошло не так!.


Интеграция с VCS


Я говорила о разных вариантах настройки интеграции CI VCS:

  • CI опрашивает репозиторий Эй, ку-ку, у тебя есть изменения?? раз в N часов / минут, как настроите.

  • Репозиторий машет CI рукой при коммите: Эй, привет! А у меня обновление тут появилось! (это git hook или аналог в вашей VCS)



Но когда какой используется?

Лучше всего, конечно, чтобы система контроля версий оповещала сервер CI. И запускать весь цикл на каждое изменение: собрать, протестировать, задеплоить. Тогда любое изменение кода сразу попадет на тестовое окружение, которое будет максимально актуальным.



Плюс каждое изменение прогоняет автотесты. И если тесты упадут, сразу ясно, чей коммит их сломал. Ведь раньше работало и после Васиных правок вдруг сломалось значит, это его коммит привел к падению. За редким исключением, когда падение плавающее.



Но в реальной жизни такая схема редко применима. Только подумайте у вас ведь может быть много проектов, много разработчиков. Каждый что-то коммитит ну хотя бы раз в полчаса. И если на каждый коммит запускать 10 сборок по полчаса очереди в TeamCity никогда не разгребутся!

У нас у одного из продуктов есть core-модуль, а есть 15+ Заказчиков. В каждом свои автотесты. Сборка заказчика это core + особенности заказчика. То есть изменение в корневом проекте может повлиять на 15 разных сборок. Значит, их все надо запустить при коммите в core.

Когда у нас было 4 билд-агента, все-все-все сборки и тесты по этим заказчикам запускались в ночь на вторник. И к 10 утра в TeamCity еще была очередь на пару часов.

Другой вариант закупить много агентов. Но это цена за саму машину + за лицензию в TeamCity, что уже сильно дороже, да еще и каждый месяц платить.

Поэтому обычно делают как:

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



2. Остальные сборки проверяют, были ли изменения в VCS например, раз в 15 минут. Если были, тогда запускаем.



3. Долгие тесты (например, тесты производительности) раз в несколько дней ночью.





CI в тестировании


Если мы говорим о разработке своего приложения, то тестирование входит в стандартный цикл. Вы или ваши разработчики пишут автотесты, которые потом гоняет CI. Это могут быть unit, api, gui или нагрузочные тесты.



Но что, если вы тестируете черный ящик? Приложение есть, исходного кода нету. Это суровые реалии тестировщиков интеграции поставщик отдает вам новый релиз приложения, который нужно проверить перед тем, как ставить в продакшен.

Вот, допустим, у вас есть API-тесты в Postman-е. Или GUI-тесты в Selenium. Можно ли настроить цикл CI для них?



Конечно, можно!

CI не ставит жестких рамок типа я работаю только в проектах с автотестами или я работаю только когда есть доступ к исходному коду. Он может смотреть в систему контроля версий, а может и не смотреть. Это необязательное условие!

Написали автотесты? Скажите серверу CI, как часто их запускать и наслаждайтесь результатом =)




Итого


CI непрерывная интеграция. Это когда ваше приложение постоянно проверяется: все ли с ним хорошо? Проходят ли тесты? Собирается ли сборка? Причем все проверки проводятся автоматически, без участия человека.

Особенно актуально для команд, где над кодом одного приложения трудятся несколько разработчиков. Как это бывает? По отдельности части программы работают, а вот вместе уже нет. CI позволяет очень быстро обнаружить такие проблемы. А чем быстрее найдешь тем дешевле исправить.



Отсюда и название постоянная проверка интеграции кусочков кода между собой.
Типичные задачи CI:

  • Проверить, было ли обновление в коде
  • Собрать билд
  • Прогнать автотесты
  • Развернуть приложение на тестовом стенде
  • Прогнать на этом стенде GUI тесты (или тесты Postman-a)
  • Оповестить всех заинтересованных по email о результатах сборки и тестирования




И все это автоматически, без вмешательства человека! То есть один раз настроили, а дальше оно само.

Если в проекте настроен CI, у вас будут постоянно актуальные тестовые стенды. И если в коде что-то сломается, вы узнаете об этом сразу, сервер CI пришлет письмо. А еще можно зайти в графический интерфейс и посмотреть все ли сборки успешные, а тесты зеленые? Оценить картину по проекту за минуту.

См также:
Continuous Integration для новичков

PS больше полезных статей ищите в моем блоге по метке полезное. А полезные видео на моем youtube-канале
Подробнее..

В чём сила дашбордов, как тестировать JS-библиотеки и чего стоит выпустить собственный фреймворк в open source

04.07.2020 12:05:52 | Автор: admin
Пост посвящается всем, кто виртуально не добрался до нашего онлайн-митапа, который мы посвятили инструментам автоматического тестирования. Без лишних слов публикуем видео с BugsBusters 2020 смотрите прямо сейчас, будет хорошее начало выходных.



Сила дашбордов

Егор Иванов, специалист по автоматизации тестирования (Яндекс.Деньги)

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


Таймкоды
0:55 Каким специалистам будет полезен доклад
1:10 Что такое дашборд? Примеры из жизни. Определение термина, основные типы.
4:05 Знакомство с командой интеграционного тестирования. Схема взаимодействия инструментов: Jira, Autorun, Locker, Pinger, Jenkins
7:32 Что делать, когда что-то идет не так роль дежурного
8:15 Дашборд дежурного: мастштабирование задач, использование Grafana
11:26 Как происходит отсылка метрик. Типы метрик.
13:09 Процесс отправки метрик из Java и sh
14:10 Как построить дашборд? Как можно использовать дашборды?
15:00 Пример 1 дашборд как визуализатор метрик
18:20 Пример 2 дашборд как мотиватор
22:18 Пример 3 дашборд для анализа
24:45 Пример 4 дашборд для экономии времени
27:00 Подведение итогов: что мы получили от внедрения дашбордов



Святой Грааль автоматизации: не можешь найти создай сам

Андрей Ганин, QA Head (Альфа-Банк)

Кажется, выбор инструментов для автоматизации огромный ровно до тех пор, пока вам не понадобятся E2E-тесты на C#. Я расскажу о том, как мы создавали собственный фреймворк: о трудностях, несбывшихся надеждах и тонкостях выпуска внутреннего продукта в open source.


Таймкоды
1:30 О чем пойдет речь в докладе?
2:20 Предыстория: как Альфа-банк задумался о сокращении времени на проверку внутренних продуктов.
3:32 Выявление основной проблемы отсутствии документации.
4:21 Итоги первой реализации фреймворка
5:28 Описание второй итерации. SpecFlow. Итоги второй реализации
8:32 What if?.. Создание инструмента, который мог бы безошибочно и без установки дополнительного ПО создавать автотесты.
9:20 Схема взаимодействия внутренний инструментов AFT Desk
10:58 А зачем это всё?
13:35 Разделение тестов с фреймворком. Как это происходит внутри?
16:31 Глобальное изменение: прекращение Microsoft развития фреймворка Net Framework. Переход на Net Standard
18:20 Как изменился процесс после перехода. Плюсы и минусы
20:57 Применимость фреймворка. Примеры. Паттерны Page Object
23:11 Как использовать технологии?
24:17 Как выглядит релиз новой версии в Open Source. Различия с внутренним решением
26:44 Выводы: зачем использовать фреймворк и кому это может пригодится? Планы развития



Как мы тестируем виджет Яндекс.Кассы

Дмитрий Сергиенко, старший тестировщик (Яндекс.Деньги)
Виджет Яндекс.Кассы это JS-библиотека, которая работает через iframe. Расскажу о своём опыте тестирования и о нашем инструменте WidgetRunner.


Таймкоды:
0:32 Как тестировать JS-библиотеку?
0:54 Виджет Яндекс.Кассы: что это такое.
2:45 Почему мы решили использовать iframe
3:04 Как же это все тестировать? Первый вариант (статичный html-файл), его минусы.
3:45 О платежном токене: что это и как его получить.
5:01 Почему 1 подход не сработал? Следующие подходы
6:09 Почему плохо тестировать только форму оплаты?
7:48 Требования к инструменту тестирования
8:40 WidgetRunner как работает инструмент и его функциональность
11:52 Выводы: что получили с внедрением инструмента WidgetRunner



Наш первый митап в онлайне прошел круто и драйвово: чуть больше 200 слушаталей в прямом эфире! А под конец мы еще и подарочные сертификаты разыграли в викторине участники остались довольными.

P.S. Скоро откроем регистрацию на Android-митап, на котором затронем темы мобильного тестирования. Следите за новостями!
Подробнее..

Из песочницы Программные IP-АТС и нагрузочное тестирование

29.06.2020 20:18:45 | Автор: admin
Всем доброго дня! Вот уже несколько лет я занимаюсь IP-телефонией и стал замечать, что хоть и Интернет полон информации, я говорю не только про российский сегмент, но найти иной раз нужную можно только на каком-либо заброшенном форуме, а то ее и вовсе нет. Если информации о IP-телефонии и самом протоколе sip предостаточно, то данных, как строиться программная IP-АТС, как происходит ее тестирование и отладка по понятным причинам нет, либо есть, но написаны таким языком, что понять может лишь тот, кто много лет работает в данной сфере.

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

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

Введение


Программная IP-АТС это автоматическая телефонная станция, работающая на основе протокола IP, мозгом которой является специальное программное обеспечение, реализующее коммутацию голоса (в данном случае пакетов с голосом) и прочие услуги, оказываемые абонентам.

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

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

Абонент говорит в трубку его голос кодируется с помощью программного или аппаратного кодека в набор битов. Кодек алгоритм сжатия голоса, самый простой и распространенный PCMA. Дальше эти биты с помощью протокола RTP отправляются адресату.

Если обобщить все выше сказанное, то у нас есть протокол SIP, управляющий сеансом связи, в его состав входит протокол SDP, который описывает сессию (используемые и доступные кодеки и прочую информацию), эти протоколы упаковываются в транспорт TCP или UDP и с помощью протокола IP отправляется в указанном направлении. Как только устанавливается логическое соединение, то с помощью кодека сжимается голос и упаковывается в RTP и с помощью протокола IP отправляется адресату.

Теперь попытаемся ответить на главный вопрос кто управляет всем этим? Software switch или коротко softswitch это мозг программной IP-АТС, управляющий всем внутренним и внешним взаимодействием. Softswitch у нас всех на слуху, все слышали про Asterisk и Freeswitch. Есть платные, есть бесплатные, есть с графическим интерфейсом, есть без.

На рисунке 1 я изобразил структурную схему программной IP-АТС, рассмотрим же ее подробнее. В первую очередь это операционная система (ОС), она должна быть совместима с железом, иметь нужные репозитории и быть удобной для работы. Про железо не будем говорить, пусть это будет некий сервер. Исходя из пожелания заказчика (ТЗ) подбирается мозг нашей IP-АТС Softswitch, это может быть тот же самый Asterisk или Freeswitch или написанный собственноручно Softswitch. На рисунке я разделил Softswitch и ПО, по сути это может быть одно приложение все зависит от требований заказчика, можно взять готовый, тот же самый Freeswitch, написать программу, которая будет управлять им и также реализовать дополнительный функционал. С Web-сервером все ясно, нам нужна прослойка между http-клиентом и Softswitch. Ну и соответственно БД, не будем же мы постоянно переписывать конфигурационные файлы. ОС дает нам среду для работы, так же необходимо писать дополнительные драйверы, если хочется подключить платы FXO и E1.

image
Рис 1. Структурная схема программной IP-АТС

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

Sipp и StarTrinity SIP Tester


Несколько недель назад была поставлена задача протестировать нагрузку, которую может выдержать наша программная IP-АТС. После долгих поисков я наткнулся на бесплатный генератор вызовов Sipp и платное StarTrinity SIP Tester. Ниже коротко опишу возможности данных приложений.

Начну пожалуй c самого простого со StarTrinity SIP Tester. Приложение работает только под Windows, имеет огромное количество возможностей, регистрацию пользователей, выступать как сервер регистрации, отправлять исходящие вызовы со множеством параметров, принимать входящие вызовы и отправлять заданные сообщения, по сути вы можете написать сами скрипт и приложение поможет вам в этом. Но весь функционал это тема отдельного поста, нам нужно для работы самое основное умение отправлять вызовы с заданным интервалом, не забывая о RTP. А теперь самое главное это приложение платное, но разработчики предоставляют и бесплатную немного урезанную версию, но по сути даже урезанной версией можно пользоваться, если проявить смекалку.

Бесплатная версия дает сделать 150 вызовов, при этом одновременных соединений может быть 50. Но после перезагрузки счетчик обнуляется и можно посылать вызовы заново.На рисунке 2 и 3 изображено приложение StarTrinity SIP Tester, можем увидеть по какому адресу, на какой номер, от кого, какой кодек, интервал и прочую информацию о вызовах. Так же стоит отметить, что есть Web-интерфейс и возможность самому делать скрипты, но что мне не понравилось, нельзя делать сценарии с неправильными параметрами.

image
Рис 2. Платная версия StarTrinity SIP Tester

image
Рис 3. Бесплатная версия StarTrinity SIP Tester

Если StarTrinity SIP Tester, это красивый графический интерфейс, который готов работать уже из коробки, то Sipp представился мне этаким монстром, которого надо скачать, скомпилить, добавить нужные пакеты. Но как оказалось этого не стоит бояться, на сайте разработчики оставили великолепный гайд, описывающий процесс установки и возможности данного приложения. Сразу предупреждают потребуется несколько дней, чтобы научиться писать скрипты, но в этом и есть плюс, вы досконально поймете сам протокол sip и изучите его поля. Пару слов, есть встроенные сценарии, они самые обычные отправил и принял вызов, все же остальное ищем в Интернете, некоторые пользователи делятся, но мне пришлось сидеть изучать спецификации и писать свои скрипты. Sipp есть и под Windows и Linux, но стабильнее работает под Linux.

Теперь к делу, выделять машину только под Sipp затратно, берем и делаем виртуальную машину, я использую VirtualBox под Ubuntu, проблем у меня не возникло. Установили в соответствии с гайдом, заходим в папку с приложением и запускаем приложение с нужными ключами.

image
Рис 4. Генератор вызовов Sipp

Описывать функционал Sipp я не буду, он аналогичен StarTrinity SIP Tester, какое приложение лучше, тут однозначного ответа нет, я пришел к выводу, что они отлично дополняют друг друга.

Нагрузочное тестирование


Теперь мы знаем, что из себя представляет программная IP-АТС и как она работает, также мы знаем функционал генераторов вызовов.

Опять же при тестировании мы должны понимать режим работы программной IP-АТС: режиме прокси (проксируется RTP+сигналка), полупрокси (проксируется только сигналка), перенаправления запроса (сообщение 300). От этого будет зависеть надо ли нам включать RTP при некоторых сценариях или нет. На рисунке 5 я набросал несколько вариантов тестирования.

Вариант 1 тестируем программную IP-АТС в режиме транзита, для этого нам понадобиться два разных ПК. На АТС прописываем маршрут, соответственно с одного Sipp/StarTrinity SIP Tester генерируем вызовы на другой Sipp/StarTrinity SIP Tester. Сразу скажу с StarTrinity SIP Tester на Sipp (или на оборот) генерировать вызовы не пробовал, но чисто в теории они должны быть полностью совместимы.

Вариант 2 тестируем программную IP-АТС в режиме транзита, для этого нам понадобиться два разных ПК. На АТС прописываем маршрут, соответственно с одного Sipp/StarTrinity SIP Tester генерируем вызовы на Asterisk. Для Asterisk я использую виртуальную машину VirtualBox под Ubuntu, проблем у меня не возникло. В диалплане Asterisk прописывем следующее:

image

При вызове на данный номер Asterisk отвечает и весь полученный голос посылает обратно.

image
Рис 5. Варианты конфигурации оборудования для нагрузочного тестирования

Вариант 3 тестируем программную IP-АТС в режиме оконечной станции, для этого нам понадобиться один ПК и IP-телефоны, на телефонах устанавливаем автоответ. На АТС регистрируем IP-телефоны, соответственно с одного Sipp/StarTrinity SIP Tester генерируем вызовы них.

Вариант 4 тестируем программную IP-АТС в режиме оконечной станции, для этого нам понадобиться один ПК и аналоговые ТА. На АТС прописываем аналоговые ТА, соответственно с одного Sipp/StarTrinity SIP Tester генерируем вызовы них. На сколько я знаю, но сам не сталкивался есть определенные приборы, которые подключаются к аналоговым линиям и могут программироваться к примеру подымать трубку при вызове, но если данных возможностей нет, придётся вручную подымать трубки.

Вот и все, естественно на программной IP-АТС включаем логи, или выводим консоль с отладкой и смотрим возникшие ошибки. Так можно определить предел производительности и отказа. Кстати, совет, на виртуальную машину устанавливайте Wireshark, tshark, tcpdump, так вы в режиме реального времени сможете отслеживать и анализировать весь трафик на вашем интерфейсе.

Подведение итогов


Подведем итоги, мы с вами поверхностно познакомились с построением программной IP-АТС и генераторами вызовов Sipp и StarTrinity SIP Tester и научились имитировать нагрузку. Если хорошо подумать, то с помощью этих генераторов вызовов можно спокойно протестировать весь стек Sip.

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

LOADING

Ссылки

1.Sipp sipp.readthedocs.io/en/v3.6.0/#
2.StarTrinity SIP Tester startrinity.com/VoIP/SipTester/SipTester.aspx
3.Книги и прочая информация asterisk.ru/knowledgebase/books
Подробнее..

Эта небольшая статья расскажет вам об интеграции JDI Light с Selenium Grid

23.06.2020 10:15:03 | Автор: admin
JDI это семейство фреймворков для автоматизации тестирования. На данный момент состоит из JDI Light для UI автоматизации, JDI Dark для бэкэнд автоматизации и JDI Mobile. Название расшифровывается как Just do it: главная идея JDI в том, чтобы с помощью него было легко тестировать и поддерживать тесты, а все удачные рабочие находки сохранять и аккумулировать.

Selenium Grid это кластер, состоящий из нескольких Selenium-серверов. Он предназначен для организации распределённой сети, позволяющей параллельно запускать много браузеров на большом количестве машин. Имеется выделенный сервер, который носит название хаб или коммутатор, а остальные сервера называются ноды или узлы.

Интеграция:
Первое, что нам понадобится, это сам selenium grid, скачать его можно на официальном сайте selenium (selenium.dev/downloads/), там же можно ознакомиться с документацией.

Далее необходимо запустить selenium grid, для этого в папке со скачанным файлом открываем командную строку и выполняем команды.
  1. Запуск selenium grid в режиме хаба:
    java -jar selenium-server-standalone-3.141.59.jar -role hub -port 4444
    • selenium-server-standalone-3.141.59.jar файл selenium grid
    • port 4444 порт, на котором будет работать хаб, необходимо знать, чтобы подключать ноды и создавать RemoteWebDriver.

  2. Подключение ноды к хабу:
    java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone-3.141.59.jar -role node -hub localhost:4444/grid/register -browser browserName=chrome,maxInstances=3,platform=WINDOWS -port 5557

Также для настройки нод можно использовать json файлы. Подробнее о возможностях и настройке Selenium Grid можно прочитать на официальном сайте проекта selenium (selenium.dev/documentation/en/grid/)

Проверить, запустился ли хаб, и подключены ли к нему ноды, можно из консоли или, перейдя по ссылке, где зарегистрирован хаб. В представленой выше конфигурации мы создали его локально на порте 4444, поэтому после открытия ссылки (localhost:4444/grid/console) в браузере мы увидим следующий сайт:


Настройка selenium grid завершена, и мы переходим к его использованию.

В случае использования чистого Selenium WebDriver, чтобы получить объект WebDriver, нам будет необходимо создать объект

RemoteWebDriver(URL remoteAddress, Capabilities capabilities)- remoteAddress  url хаба- capabilities  конфигурации браузера


При создании объекта мы обратимся к хабу и попробуем взять у него ноду, у которой есть необходимый нам браузер. Если такая нода не найдена, будет выброшено исключение.
Из коробки Selenium WebDriver не предоставляет возможности изменять браузер на лету или хранить необходимый нам браузер в файле настроек. Для реализации этих возможностей разработчики тратят силы и время.

Но разработчики JDI Light позаботились о реализации этих возможностей. Используя JDI, можно сэкономить время и силы, так как для получения объекта WebDriver нам нужно будет лишь добавить адрес хаба в файл настроек JDI:
driver.remote.url=http://localhost:4444/wd/hub
и указать в файле настроек браузер, на котором необходимо выполнить тесты:
driver=chrome
Дополнительная информация о файле настроек и других возможностях JDI Light (jdi-docs.github.io/jdi-light/#jdi-settings)
Хаб попытается найти подходящую ноду. В случае если нода не будет найдена, выбросится исключение:
java.lang.RuntimeException: java.lang.RuntimeException: Failed to do screenshot. No Drivers run

Приятного использования. И спасибо за внимание.
Подробнее..

Simctl управление симуляторами Apple через терминал

15.06.2020 00:20:27 | Автор: admin
Всем привет! Меня зовут Паша Лесюк, я работаю мобильным тестировщиком в компании Циан. В этой статье я расскажу о возможностях управления яблочными симуляторами из командной строки.


simctl утилита командной строки для взаимодействия с симуляторами. Она очень похожа на ADB для Android, устанавливается вместе со средой разработки Xcode и используется вместе с xcrun (Xcode-раннер командной строки). Двоичный файл программы можно найти по пути:

/Applications/Xcode.app/Contents/Developer/usr/bin/simctl

Содержание
Работа с объектами устройств
Просмотр списка доступных команд и информации по ним
Просмотр списка доступных устройств, сред выполнения, устройств и пар устройств
Создание нового устройства
Запуск устройства
Апгрейд устройства
Клонирование устройства
Очистка данных и настроек устройства
Переименование устройства
Вывод переменных среды устройства
Проверка состояния загрузки устройства
Выключение устройства
Удаление устройств

Работа с контентом устройств
Снятие скриншота и видео с устройства
Добавление медиа на устройство
Открытие URL на устройстве
Управление сертификатами устройства
Установка приложения на устройство
Запуск приложения на устройстве
Предоставление, отзыв и сброс разрешений приложения
Отображение информации о приложении
Отображение пути к контейнерам установленного приложения
Закрытие приложения на устройстве
Удаление приложения с устройства
Симуляция отправки пуш-уведомления
Изменение и очистка статус-бара устройства
Установка темной или светлой темы

Работа с логами и внутренними механизмами устройств
Выполнение указанной операции на устройстве
Включение и отключение подробного логирования на устройстве
Отображение логов с устройства
Сбор диагностической информации и логов

Заключение
Включение и отключение полноэкранного режима окна симулятора
Включение и отключение отображения нажатий на устройстве

Работа с объектами устройств


Просмотр списка доступных команд и информации по ним


Команда simctl без подкоманд выводит в консоль список всех доступных подкоманд (далее будет использоваться термин команда).

$ xcrun simctl

Для просмотра подробной информации по команде нужно использовать команду help с названием искомой команды.

$ xcrun simctl help list

Просмотр списка доступных устройств, сред выполнения, устройств и пар устройств


Команда list выводит список всех установленных устройств и окружений. Рядом с каждым устройством будет отображен UDID (уникальный идентификатор устройства), который можно прокидывать в некоторые подкоманды simctl.

$ xcrun simctl list

Пример UDID:

4599F586-F482-4E9C-92A7-8AC4EF348BD9

Список можно фильтровать по заголовкам: devices, devicetypes, runtimes, pairs.

$ xcrun simctl list devices== Devices ==-- iOS 11.0 --    iPhone 7 (422566D6-AD4C-40E5-AC64-233043A00814) (Shutdown)-- iOS 13.4 --    iPhone 8 (CB87B315-F01A-41AA-9C85-6FE24E5A66B9) (Shutdown)

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

$ xcrun simctl list devices available

Примером поискового запроса может служить выборка по устройствам c экраном 12.9 дюймов.

$ xcrun simctl list devicetypes 12.9== Device Types ==iPad Pro (12.9-inch) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro)iPad Pro (12.9-inch) (2nd generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--12-9-inch---2nd-generation-)iPad Pro (12.9-inch) (3rd generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--12-9-inch---3rd-generation-)iPad Pro (12.9-inch) (4th generation) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--12-9-inch---4th-generation-)

Можно вывести более подробную информацию списка c помощью параметра -v.

$ xcrun simctl list -v devices== Devices ==-- iOS 11.0 (15A8401) [/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 11.0.simruntime] --    iPhone 7 (7B68E927-161C-440C-AABE-654CD96E8694) (Shutdown)-- iOS 13.3 (17C45) [/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime] --    iPhone 8 (F3909F6E-E227-4BD7-939F-D3D05B1B8AAD) (Shutdown)

Можно вывести информацию в формате JSON с помощью параметра -j или --json.

$ xcrun simctl list -j -v devices{    "devices" : {    "com.apple.CoreSimulator.SimRuntime.iOS-13-3" : [        {        "dataPath" : "\/Users\/pavel\/Library\/Developer\/CoreSimulator\/Devices\/9EA47EEB-F19F-44EE-9854-EA06BEB8FBD1\/data",        "logPath" : "\/Users\/pavel\/Library\/Logs\/CoreSimulator\/9EA47EEB-F19F-44EE-9854-EA06BEB8FBD1",        "udid" : "9EA47EEB-F19F-44EE-9854-EA06BEB8FBD1",        "isAvailable" : true,        "deviceTypeIdentifier" : "com.apple.CoreSimulator.SimDeviceType.iPhone-7-Plus",        "state" : "Shutdown",        "name" : "iPhone-7-Plus"        },        {        "dataPath" : "\/Users\/pavel\/Library\/Developer\/CoreSimulator\/Devices\/F3909F6E-E227-4BD7-939F-D3D05B1B8AAD\/data",        "logPath" : "\/Users\/pavel\/Library\/Logs\/CoreSimulator\/F3909F6E-E227-4BD7-939F-D3D05B1B8AAD",        "udid" : "F3909F6E-E227-4BD7-939F-D3D05B1B8AAD",        "isAvailable" : true,        "deviceTypeIdentifier" : "com.apple.CoreSimulator.SimDeviceType.iPhone-8",        "state" : "Shutdown",        "name" : "iPhone 8"        }    ],    ...

Создание нового устройства


Для создания нового симулятора используется команда create, после которой указываются имя устройства, его тип и среда (эти данные есть в выводе команды list). После выполнения команды отобразится UDID созданного симулятора.

$ xcrun simctl create iPhone-7-Plus com.apple.CoreSimulator.SimDeviceType.iPhone-7-Plus com.apple.CoreSimulator.SimRuntime.iOS-13-49EA47EEB-F19F-44EE-9854-EA06BEB8FBD1

Запуск устройства


Команда boot запускает устройство с указанным UDID, делая его доступным для взаимодействия.

$ xcrun simctl boot CB87B315-F01A-41AA-9C85-6FE24E5A66B9

После запуска устройства можно передавать команду booted вместо UDID. Если запущено несколько устройств, то simctl выберет одно из них.

Чтобы увидеть симулятор в действии нужно запустить приложение Simulator.

$ open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/

Апгрейд устройства


Команда upgrade позволяет повысить версию среды устройства до необходимой.

$ xcrun simctl upgrade 422566D6-AD4C-40E5-AC64-233043A00814 com.apple.CoreSimulator.SimRuntime.iOS-13-4

Клонирование устройства


Команда clone позволяет клонировать существующее устройство, копируя его тип и среду.

$ xcrun simctl clone booted NewPhone

Очистка данных и настроек устройства


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

$ xcrun simctl erase booted

Если нужно сбросить данные всех симуляторов, то нужно использовать команду erase all.

$ xcrun simctl erase all

Переименование устройства


Изменить имя устройства можно с помощью команды rename.

$ xcrun simctl rename booted MyiPhone

Вывод переменных среды устройства


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

$ xcrun simctl getenv booted SIMULATOR_SHARED_RESOURCES_DIRECTORY/Users/pavel/Library/Developer/CoreSimulator/Devices/F3909F6E-E227-4BD7-939F-D3D05B1B8AAD/data

Проверка состояния загрузки устройства


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

  • -b загружает указанный симулятор, если он не загружен.
  • -d отображает информацию о миграции данных.
  • -c постоянно отслеживает состояние загрузки и выключения.

$ xcrun simctl bootstatus booted$ xcrun simctl bootstatus booted -c

Выключение устройства


Когда работа с симулятором закончена, можно выключить его, используя команду shutdown.

$ xcrun simctl shutdown booted

Для выключения всех симуляторов используется команда shutdown all.

$ xcrun simctl shutdown all

Удаление устройств


В ходе работы с симуляторами может накапливаться большое количество старых устройств, многие из которых могут быть недоступны для последних версий iOS. Для их удаления используется команда delete unavailable.

$ xcrun simctl delete unavailable

Для удаления конкретного симулятора используется команда delete.

$ xcrun simctl delete booted

Для удаления всех устройств используется команда delete all.

$ xcrun simctl delete all

Работа с контентом устройств


Снятие скриншота и видео с устройства


Можно просто использовать шорткат 4, навести курсором на окно симулятора, нажать пробел и сделать скриншот. Но тогда на скриншоте кроме самого экрана будут видны рамки симулятора.
Для снятия скриншота только экрана используется команда io в связке со screenshot. Можно сохранять изображения в формате .png, .tiff, .bmp, .gif и .jpeg.

$ xcrun simctl io booted screenshot ~/Pictures/app-screenshot.png


Аналогично, можно просто использовать шорткат S в открытом приложении Simulator, скриншот окна сохранится на рабочем столе.

Также можно использовать команду io в связке с recordVideo для записи видео взаимодействия с экраном симулятора. Можно сохранять видео в формате .mov, .h264, .mp4 и .fmp4.

$ xcrun simctl io booted recordVideo ~/Movies/app-preview.mp4

Для завершения записи нужно нажать C в окне терминала.

Добавление медиа на устройство


Команда addmedia используется для добавления фото или видео на симулятор.

$ xcrun simctl addmedia booted ~/Pictures/test.png$ xcrun simctl addmedia booted ~/Pictures/test.gif$ xcrun simctl addmedia booted ~/Pictures/test.mp4

Также можно просто перетащить файл из Finder в окно симулятора.

Открытие URL на устройстве


Команда openurl открывает указанный URL на симуляторе.

$ xcrun simctl openurl booted "https://www.google.com/"

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

$ xcrun simctl openurl booted maps://

Управление сертификатами устройства


Команда keychain позволяет добавлять сертификаты в доверенное корневое хранилище или keychain, а также сбрасывать keychain.

$ xcrun simctl keychain booted add-root-cert ~/my-selfsigned.cer$ xcrun simctl keychain booted add-cert ~/my-selfsigned.cer$ xcrun simctl keychain booted reset

Установка приложения на устройство


Можно легко установить приложение на симулятор если известен путь к файлу .app. Для этого используется команда install.

$ xcrun simctl install booted ~/Циан.app

Также можно просто перетащить приложение из Finder в окно симулятора.

Перечень opensource-приложений для iOS можно найти тут.

Запуск приложения на устройстве


Запуск приложения осуществляется с помощью команды launch и указанием bundle ID.

$ xcrun simctl launch booted ru.cian.mobile

Как узнать bundle ID описано тут.

Предоставление, отзыв и сброс разрешений приложения


Команда privacy может предоставлять, отзывать и сбрасывать разрешения приложения.

$ xcrun simctl privacy <device> <action> <service> <bundle ID>

Значения action (действия) могут быть следующие:

  • grant предоставляет доступ к сервису. Неободим bundle ID.
  • revoke запрещает доступ к сервису. Необходим bundle ID.
  • reset сбрасывает доступ к сервису. bundle ID опционален.

Значения service (службы) могут быть следующие:

  • all применяет действие ко всем службам.
  • calendar предоставляеть доступ к календарю.
  • contacts-limited предоставляет доступ к основной контактной информации.
  • contacts предоставляет полный доступ к контактной информации.
  • location предоставляет доступ к службам определения местоположения при использовании приложения.
  • location-always предоставляет доступ к службам определения местоположения в любое время.
  • photos-add предоставляет доступ на добавление фотографий в библиотеку фотографий.
  • photos предоставляет полный доступ к библиотеке фотографий.
  • media-library предоставляет доступ к медиа-библиотеке.
  • microphone предоставляет доступ к микрофону.
  • motion предоставляет доступ к фитнес-данным.
  • reminders предоставляет доступ к напоминаниям.
  • siri предоставляет возможность использовать приложение вместе с Siri.

Пример использования:

$ xcrun simctl privacy booted grant photos ru.cian.mobile$ xcrun simctl privacy booted grant location ru.cian.mobile$ xcrun simctl privacy booted revoke all ru.cian.mobile

На данный момент не все сервисы доступны для настройки. Отсутствуют уведомления, здоровье, Bluetooth и Face ID.

Отображение информации о приложении


Команда appinfo выводит информацию о приложении.

$ xcrun simctl appinfo booted ru.cian.mobile

Формат отображения информации следующий:

{    ApplicationType = User;    Bundle = <PATH_TO_APP_FILE>;    BundleContainer = <PATH_TO_APP_FILE_FOLDER>;    CFBundleDisplayName = "Циан";    CFBundleExecutable = "Циан";    CFBundleIdentifier = "ru.cian.mobile";    CFBundleName = "Циан";    CFBundleVersion = 1;    DataContainer = <PATH_TO_DATA_FOLDER>;    GroupContainers =     {        <GROUP_CONTAINER_NAME> = <PATH_TO_GROUP_CONTAINER_FOLDER>;    };    Path = <PATH_TO_APP_FILE>;    SBAppTags =     (    );}

Отображение пути к контейнерам установленного приложения


Можно вывести путь к контейнерам приложения через команду get_app_container с указанием bundle ID. У команды есть несколько опций для указания типа контейнера:

  • app указывает на расположение самого приложения и используется по умолчанию.

$ xcrun simctl get_app_container booted ru.cian.mobile$ xcrun simctl get_app_container booted ru.cian.mobile app

  • data указывает на расположение данных приложения.

$ xcrun simctl get_app_container booted ru.cian.mobile data

  • groups указывает на расположение группы приложений. Если групп несколько, то нужно использовать имя искомой группы.

$ xcrun simctl get_app_container booted ru.cian.mobile groups$ xcrun simctl get_app_container booted ru.cian.mobile group.ru.cian.mobile.widget

Закрытие приложения на устройстве


Закрытие приложения осуществляется с помощью команды terminate и указанием bundle ID.

$ xcrun simctl launch terminate ru.cian.mobile

Удаление приложения с устройства


Можно удалить приложение с симулятора с помощью команды uninstall, используя bundle ID.

$ xcrun simctl uninstall booted ru.cian.mobile

Симуляция отправки пуш-уведомления


Для отправки пуша нужно подготовить файл, который должен содержать структуру в формате JSON и сохранить его с расширением .apns (Apple Push Notification service):

{    "aps": {        "alert": {            "title": "Tester on Steroids",            "body": "About mobile apps testing"        },        "badge": 3,        "sound": "default"    }}

Затем нужно дать разрешение на отправку приложению уведомлений. После этого нужно выполнить команду push с указанием устройства, bundle ID и пути до файла .apns.

$ xcrun simctl push booted ru.cian.mobile ~/Documents/mocks/push.apns

Если добавить в файл параметр "Simulator Target Bundle", то необходимость указывать каждый раз bundle ID отпадает.

{    "aps": {        "alert": {            "title": "Tester on Steroids",            "body": "About mobile apps testing"        },        "badge": 3,        "sound": "default"    },    "Simulator Target Bundle": "ru.cian.mobile"}

$ xcrun simctl push booted ~/Documents/mocks/push.apns

Также, если указан параметр "Simulator Target Bundle", то файл можно просто перетащить в окно симулятора.

Изменение и очистка статус-бара устройства


У команды status_bar есть три подкоманды:

  • override принимает параметры для элементов статус-бара и меняет их в зависимости от значений.

$ xcrun simctl status_bar booted override --time 10:30 --dataNetwork wifi --wifiMode active --wifiBars 2 --cellularMode active --cellularBars 3 --operatorName @tester_on_steroids --batteryState charging --batteryLevel 75

  • list выводит значения перезаписанных параметров.

$ simctl status_bar booted listCurrent Status Bar Overrides:=============================Time: 10:30DataNetworkType: 1Cell Mode: 3, Cell Bars: 3Operator Name: @tester_on_steroidsBattery State: 1, Battery Level: 75, Not Charging: 1

  • clear очищает перезаписанный статуc-бар.

$ simctl status_bar booted clear

Установка темной или светлой темы


Данная опция доступна для симуляторов с iOS от 13.0 и выше. C помощью команды ui appearance можно поменять тему устройства на темную или светлую.

$ xcrun simctl ui booted appearance dark$ xcrun simctl ui booted appearance light

Работа с логами и внутренними механизмами устройств


Выполнение указанной операции на устройстве


Команда spawn создает указанный процесс на симуляторе.

$ xcrun simctl spawn booted defaults write ru.cian.mobile ResetDatabase -bool YES

Здесь используется интерфейс defaults, в котором флагу ResetDatabase устанавливается значение YES. Это удобный способ менять пользовательские настройки до запуска приложения.

Включение и отключение подробного логирования на устройстве


Команда logverbose позволяет включать и отключать подробное логирование на устройстве. Для того, чтобы изменения вступили в силу, нужно перезапустить симулятор.

$ simctl logverbose booted enable$ simctl logverbose booted disable

Отображение логов с устройства


В iOS существует пять уровней логов:

  1. Default. Используется для сбора информации о вещах, которые могут привести к сбою.
  2. Info. Полезная, но необязательная информация для устранения ошибок.
  3. Debug. Информация, которая может быть полезна во время разработки или устранения конкретной проблемы. Отслеживание debug-логов предназначено для использования на стадии разработки, а не на стадии эксплуатации программы конечными пользователями.
  4. Error. Используется для сбора информации об ошибках процесса.
  5. Fault. Используется для сбора информации об ошибках системного уровня или мульти-процессов.

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

$ xcrun simctl spawn booted log stream

По умолчанию вывод логов будет включать в себя уровни default, error и fault. Для использования уровней info и debug нужно использовать аргумент --level. --level=info будет отображать уровни по умолчанию, а так же info. --level=debug будет отображать уровни по умолчанию, а так же info и debug.

$ xcrun simctl spawn booted log stream --level=info$ xcrun simctl spawn booted log stream --level=debug

Также можно фильтровать логи. Например, по конкретному приложению или по типу ивентов и сообщений.

$ xcrun simctl spawn booted log stream --predicate 'processImagePath endswith "Циан"'$ xcrun simctl spawn booted log stream --predicate 'eventMessage contains "error" and messageType == info'

Чтобы выключить вывод логов нужно нажать C в окне терминала.

C помощью операции log collect можно сделать дамп журнала логов.

$ xcrun simctl spawn booted log collect

Сбор диагностической информации и логов


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

$ xcrun simctl diagnose

Журнал будет включать в себя:

  • системные логи,
  • логи симулятора,
  • устройства и окружения,
  • настройки устройств,
  • дополнительную информацию.

В журнале будет содержаться конфиденциальная информация, поэтому с этими данными нужно быть осторожным.

После генерации журнала будет открыта папка с архивом, содержащим всю информацию.

Заключение


В заключение хотелось бы поделиться еще парой полезных команд для работы с симуляторами.

Включение и отключение полноэкранного режима окна симулятора


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

defaults write com.apple.iphonesimulator AllowFullscreenMode 1defaults write com.apple.iphonesimulator AllowFullscreenMode 0

Включение и отключение отображения нажатий на устройстве


Отображает тапы на симуляторе. Удобно при записи видео.

defaults write com.apple.iphonesimulator ShowSingleTouches 1defaults write com.apple.iphonesimulator ShowSingleTouches 0



P.S.
Если вам интересна тема тестирования, то приглашаю вас подписаться на мой блог в телеграме.
Подробнее..

Из песочницы Маски тестировщика (вопросы для успешного перехода к тестерскому расстройству личности)

18.06.2020 12:21:50 | Автор: admin
Я делаю то, за что мне платят стандартный капиталистический подход к работе на дядю в Западной части нашего мира. В момент свет гаснет, станки останавливаются и все расходятся по своим делам. Интересно, что методологи в стиле Скрам и Канбан, которые говорят о командной работе, также жестко проводят черту между ролями и тем, кто, что и когда делает. Но это там! А у нас? А у нас роль в команде (буду говорить о тестировщиках (QA)) коррелирует со знаниями из разных сфер, важностью морального и душевного равновесия в коллективе и ответственностью за проделанную работу. Все это адаптирует методологии в командах немного под другим углом, отличным от запада.

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

Тестировщик программного обеспечения сегодня занимает ключевую позицию в выпуске продукта и вот почему. Если вы смотрели фильм Стекло, то непременно помните чудесного разнообразного персонажа Орда, страдающего расстройством личности. Так вот чем опытнее, чем полезнее и чем профессиональнее специалист по тестированию, тем больше масок личностей он может на себя примерить, но в отличие от бедняги Орды, способен ими управлять.
Сегодня я расскажу о некоторых из них с объяснением своей позиции и мнения. В конце статьи вы получите дополнительный список с базовыми вопросами для себя в каждой из описанных ролей для успешного перехода к тестерскому расстройству личности ( это шутка)
а начну я конечно же с:

Маска пользователь!


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

Маска саппорт менеджер


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

Маска бизнес-аналитика


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

Маска проджект-менеждер


Проджект-менеждер. Тестирование это последний этап в разработке продукта перед релизом. Это значит, что тестировщик (хороший такой, прожженный) знает и коммуницирует со всеми членами команды, знает воркфлоу проекта, знает, как устроены все артефакты скрама в команде и в случае чего может их подхватить и применить, например, демо митинг или ретроспективу. Хороший тестировщик видит узкие места в процессах работы команды потому, что все они в итоге превращаю тестирование в слабое звено проекта. Например: плохая оценка задач это всегда аврал в конце спринта и почему релиз не готов не успели протестировать, отсутствие код-фриза это сбои тестирования и упущенные баги из-постоянного фарша в тестовой среде, кто упустил баги тестировщики и т.д Тестировщик, самая ответственная позиция в команде, так как он одобряет продукт к выпуску, а, значит, он и несет ответственность за все, что будет происходить дальше (это я про всплывающие баги), в независимости от того, что послужило этому причиной. Поэтому, заботясь о себе, тестировщик заботится о команде.

Маска психоаналитик


Тестировщик-психоаналитик (возвращаясь к вышеуказанному пункту) общается вплотную со всеми членами команды и теми, кто работает с командой косвенно. Он знает настроения в команде, знает боль и страдания ее членов и, конечно же, как губка прокачивает это все через себя. Получается, что мало того, что тестировщик сам всегда в зоне повышенного стресса, так еще именно он и становится подушкой для горьких слез своих коллег, что в результате и становится инструментом сближения сотрудников для дальнейшего повышения эффективности.
Вывод наклевывается достаточно простой нужно уметь ставить себя на место других и если бы так могли и умели делать все члены команды разработки, такая команда отправляла бы людей на марс уже давным давно. Но вывод простой, а вот на практике применить это куда тяжелее. Мы все разные, команды разные, заказчики разные и тд. Но не стоит опускать рук, можно начать с обычного утреннего вопроса коллеге как дела? как настроение?

Обещанный список вопросов


Вопросы маска пользователь


  • Что меня раздражает в том, что я вижу?
  • Что мне не понятно?
  • Могу ли я сделать так, как хочу (имеется в виду, последовательность степов)?

Вопросы маска саппорт-менеджер


UX дизайн адекватен?

  • Все ли подсказки и советы на месте?
  • Актуальны ли подсказки и эффективны?
  • Понятен гайд?
  • Гайд актуален?
  • Что про людей с ограниченными возможностями? (вопрос риторический у нас к сожалению о них не задумываются)
  • Есть ли демо версия разработанного продукта?
  • Демо удобное и актуальное?

Вопросы маска бизнес аналитик


  • Чего мне может не хватить как пользователю?
  • Что меня раздражало как пользователя и как это улучшить?
  • Какие ресурсы могут быть затрачены на предполагаемые улучшения?
  • Что предложить на известные проблемы?

Вопросы проджект менеджер


  • Почему скрам?
  • Почему канбан?
  • Почему не скрам или канбан?
  • А что если отказаться от или внедрить.? (гибкие методологии на то гибкие)

Вопросы психоаналитик


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

Перевод Если вы используете моки, то вы хоть что-то тестируете?

25.06.2020 20:11:16 | Автор: admin

Было ли у вас ощущение, что ради тестирования вы делаете код труднее для чтения? Допустим, у вас есть код, который ещё не тестировался. У него есть ряд побочных эффектов, и вас просят сначала прогнать тесты. Вы начинаете следовать советам вроде передачи глобальных переменных в виде параметров или извлечения проблемных побочных эффектов, чтобы сделать вместо них заглушки в тестах.

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

Вы останавливаетесь и задумываетесь: Допустимо ли менять сигнатуры кода ради тестирования? Тестирую ли я реальный код или совершенно другой класс, в котором не происходит то, что нужно? Перед вами может возникнуть дилемма. Вы уверены, что стоит и дальше придерживаться этого подхода? Или это потеря времени?

Вопрос на миллион: для устаревшего кода нужно писать модульные тесты или интеграционные?

Парадокс


Вы могли оказаться в одной из этих ситуаций:



Не знаю, как вам, а мне эти ситуации оооооочень близки. Они смешные, поскольку правдивые (и это неприятно).

Вам говорят, что нужно делать заглушки для проблемных зависимостей и писать модульные тесты. Но в какой-то момент возникает ощущение, что в ваших тестах растёт слепая зона. Какие у вас есть гарантии, что код будет вести себя корректно при использовании настоящей БД в бою? Не станет ли у вас ещё больше проблем, если вы интегрируетесь с настоящей базой данных?

Я тоже сталкивался с этой дилеммой! Долгое время я продвигал Testing Pyramid. Там утверждают, что нужно писать больше модульных тестов, потому что они быстрые и более надёжные, чем интеграционные тесты.

Также я много занимался фронтендом. В последние годы набирает популярность мантра Пишите тесты. Не слишком много. В основном, интеграционные, которую продвигает Кент Доддс. Он очень умён и является авторитетом в тестировании фронтенд-приложений. Есть даже инструменты вроде Cypress для тестирования большинства веб-приложений с помощью сквозных тестов! Ещё ближе к пользователю!

Как вы разрешите этот парадокс? Как будет правильно? Стоит ли делать заглушки, чтобы тесты были быстрыми и надёжными? Или лучше писать интеграционные тесты, которые менее надёжны, но вылавливают больше проблем?

Прежде чем мы продолжим, позвольте сказать: замечательно, что перед вами встала эта дилемма. Она представляется вам проблемой, но это означает, что вы движетесь в правильном направлении! Это естественное препятствие на пути, и вы его преодолеете. У этой загадки есть решение.

Практичный взгляд на тестирование


Я на некоторое время погрузился в эту проблему и попробовал разные подходы. Решение пришло после памятной дискуссии с J. B. Rainsberger.

Я понял, что никакого парадокса нет. Есть разные определения модуля.

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


Изолированные тесты


Я считаю, что деление на модульные и интеграционные тесты недостаточно понятно. Такая категоризация приводит к проблемам и спорам, хотя цель у нас одна: облегчить изменение ПО с помощью быстрой и точной обратной связи, когда вы что-то ломаете.

Поэтому я предпочитаю говорить об изолированных тестах.

Не уверен, что этот термин лучше. Но он мне пока нравится, потому что заставляет задаваться крайне важным вопросом: изолированные от чего?

Мой ответ: изолированные от того, что сложно тестировать.

Что сложно тестировать


Случайность, время, сеть, файловую систему, базы данных и т.д.

Всё это я называю инфраструктурой, а остальное доменом. Сочетание домена и инфраструктуры выглядит очень полезным и практичным взглядом на проектирование ПО. И не только для меня. Такое разделение заложено в основу многих удобных для сопровождения архитектур, таких как гексагональная архитектура (Hexagonal Architecture) (известная как порты и адаптеры (Ports and Adapters)), луковая архитектура (Onion Architecture), чистая архитектура (Clean Architecture), функциональное ядро / императивная оболочка (Functional Core / Imperative Shell) и т.д.

Всё это нюансы, которые говорят об одном: домен и инфраструктуру лучше разделять. Эту идею продвигает и функциональное программирование: изолированные побочные эффекты на периметре вашей системы. Побочные эффекты это инфраструктура. А её трудно тестировать.

Да, но чем это поможет?


Если коротко, это подсказывает вам, что именно нужно извлекать и заменять заглушками. Не переносите бизнес-логику в инфраструктуру, иначе намучаетесь с тестированием.

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

Но ведь в коде инфраструктуры могут быть баги!

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

Суть вот в чём: у вас должна быть возможность тестировать все виды поведения вашего приложения без сохранения данных в PostgreSQL. Нужна in-memory БД. Вам всё ещё нужно проверять работоспособность интеграции с PostgreSQL, но для этого достаточно всего несколько тестов, а это заметное отличие!

Всё это была теория, давайте вернёмся к реальности: у нас есть код, который ещё не протестирован.

Возвращаемся к устаревшему коду


Думаю, вам поможет такой взгляд на тестирование. Не нужно увлекаться заглушками, но при работе с устаревшим кодом придётся увлечься. Временно. Потому что этот код представляет собой винегрет из того, что сложно тестировать (инфраструктуры) и бизнес-логики (домена).

Вам нужно стремиться извлечь инфраструктурный код из доменного.

Затем сделайте так, чтобы инфраструктура зависела от домена, а не наоборот. В бизнес-логике должно быть как можно меньше инфраструктуры. У вас получатся быстрые, надёжные, изолированные тесты, покрывающие большую часть логики приложения, и несколько интеграционных тестов для проверки работы инфраструктурного кода с реальной базой данных, внешним API, системными часами и т.д.

Останутся ли у вас заглушки? И да, и нет.

У вас будут альтернативные реализации инфраструктуры, поэтому вы всё ещё сможете исполнять production-логику без использования настоящей БД.

Как узнать, что реализация БД работает корректно? Напишите несколько интеграционных тестов. Как раз столько, чтобы хватило для проверки корректности поведения. J. B. Rainsberger называет это Тестами контракта. Думаю, лучше всего пояснить на этом примере.

Можете следовать этому рецепту


Вот как можно работать с устаревшим кодом:

  1. Используйте методику Extend & Override для ликвидации неприятных зависимостей. Это хороший первый шаг. Вырежьте инфраструктурную часть из оставшегося кода, чтобы можно было начать писать тесты.
  2. Инвертируйте зависимость между кодом и извлечённой инфраструктурой. Для этого используйте внедрение зависимостей (Dependency Injection). Придётся принять архитектурные решения: можно ли сгруппировать некоторые извлечённые методы в согласованный класс? Например, сгруппировать то, что относится к сохранению и извлечению сохранённых данных. Это ваш инфраструктурный адаптер.
  3. Если вы пишете на статически типизированном языке, то извлеките интерфейс из созданного класса. Это простой и безопасный рефакторинг. Он позволит завершить инверсию зависимости: сделает код зависимым от интерфейса, а не от конкретной извлечённой реализации.
  4. В тестах сделайте фальшивую реализацию этого интерфейса. Скорее всего, она будет хранить информацию в памяти. Она должна воспроизводить такой же интерфейс и вести себя так же, как и боевая реализация, которую вы вытащили.
  5. Напишите тест контракта. Это гарантирует, что фальшивая и боевая реализации ведут себя так, как вы ожидаете! Тест контракта проверит корректность работы интерфейса. Поскольку вы прогоните одинаковые серии тестов на обеих реализациях, вы будете знать, что можно доверять своим изолированным тестам. Вы в безопасности! Отличное руководство для начинающих.
  6. Сделайте так, чтобы интерфейс выражал потребности бизнеса, а не подробности реализации. Рекомендую развивать архитектуру в этом направлении. Но это приходит с практикой и не должно быть помехой.

После того как вы это сделаете, тесты покроют 80 % вашего кода, потому что в нём не будет сложных мест. Останется написать несколько тестов для проверки корректности подключения, но не тратьте на это силы, пока тестируете чистую логику. Больше никаких слепых зон!

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

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

Всё будет отлично


Это непросто.

У меня ушло несколько лет на размышления. И я всё ещё читаю, слушаю и пробую этот подход в разных ситуациях (пока что работает).

Но всё это важно: тестирование, архитектура и устаревший код. Все эти навыки взаимосвязаны. Практикуясь в одном, вы растёте и в другом.

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

И последнее: вам не обязательно сразу выполнять все 6 этапов. Можете заниматься этим итеративно. Нужно верить в этот процесс (вот почему он хорошо подходит для практики), но он работает. Если вас беспокоит потеря времени на излишнее количество заглушек, то это потому, что вы всё ещё на первом этапе. Идите дальше! Заглушек станет меньше, а у вас появится больше уверенности в точности тестов.

Инфраструктурные адаптеры + тесты контрактов = недостающие части пилы для устаревшего кода.

Возвращайтесь к работе и продолжайте писать эти тесты. А затем идите дальше.
Подробнее..

Перевод Нагрузочное тестирование производительности вашего сайта

19.06.2020 20:14:58 | Автор: admin
И снова здравствуйте. В июле Otus запускает новый курс Нагрузочное тестирование. В преддверии старта курса традиционно делимся с вами полезным материалом.




Поскольку 5 миллиардов человек во всем мире самоизолируются, все больше и больше наших ежедневных взаимодействий происходят через интернет. Ритейлеры по всему миру переводят обслуживание своих клиентов из офисов в онлайн, школы и учебные заведения пытаются находить альтернативы в интернете, и даже общение в кругу семьи переносится на Zoom и Webex вместе с нашими рабочими встречами (с детьми и домашними животными на фоне).

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

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

Лучшие советы для успешного тестирования производительности


1. Запускайте нагрузочные тесты из производственной среды


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

2. Масштабируйте свои тесты от маленького к большому и далее к огромному


Если вы очень спешите протестировать большой наплыв пользователей, вы можете случайно пропустить уровень нагрузки, на котором у вас в данный момент могут быть проблемы, потому что вы пропустили слишком много уровней одновременно. Разгоняйтесь понемногу, а затем наращивайте свои тесты все больше и больше. Перед каждым тестом останавливайтесь, чтобы отслеживать результаты, и убедитесь, что вы удовлетворены ими, прежде чем переходить на следующий уровень. В BlazeMeter мы начинаем с отладочного тестирования, которое выполняется как функциональный тест, просто чтобы убедиться, что тест выполняет то, что вы хотите чтобы он выполнял. Затем мы проводим калибровочные испытания. Эта калибровка проводится, чтобы убедиться, что тестовая платформа, на которой выполняется тестирование, на самом деле не является узким местом. Теперь мы можем перейти к гвоздю программы: тестированию производительности. Начните тестирование с 10% целевой нагрузки и постепенно увеличивайте до полной целевой нагрузки. Убедитесь, что разгон постепенный, чтобы вы могли контролировать симптомы.

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

Вот как может выглядеть узкое место. Число попаданий/с падает, а время отклика резко возрастает:



3. Запланируйте тесты


Также вы можете планировать, как выполнять ваши бизнес-цели. Вместе с вашей командой определите, какие тесты вам нужны. Вот типы тестов, которые вы можете запустить:

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

Стресс-тесты стресс-тесты могут помочь вам понять пределы прочности системы.

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

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

Изоляционный тест это повторный тест для проверки, была ли устранена известная системная ошибка или проблема, ранее обнаруженная в этом же тесте.

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

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

4. Мониторинг внутренних результатов нагрузочного теста


Нагрузочное тестирование позволяет просматривать и анализировать KPI производительности, такие как время отклика и латентность, а также корреляции между ними. Но также важно просмотреть ключевые показатели эффективности, такие как Cache Hits и DB Queries, просмотреть лог ошибок на предмет исключений, а также просмотреть стандартные характеристики оборудования, такие как загрузка ЦП/памяти/сети и состояние автоматического масштабирования.

Различные решения расширяют возможности анализа результатов испытаний. DX APM, New Relic, App Dynamics и другие решения обеспечивают мониторинг производительности приложений и мониторинг конечных пользователей, а Amazon Cloud Watch отслеживает облачные ресурсы AWS.

5. Включите отслеживание производительности конечного пользователя в бэкэнд-тестирование


Автоматический или вручную анализируйте то, что испытывают ваши пользователи, благодаря уникальной функции BlazeMeter мониторингу опыта конечных пользователей. Новые возможности функционального тестирования выполняют тест Selenium в фоновом режиме, пока выполняется нагрузочный тест, через Taurus. Тест Selenium создает Waterfall Report, который показывает, что пользователь будет видеть в своем веб-браузере в разные моменты во время нагрузочного теста. Это может быть особенно полезно при отладке, например, из-за того, что определенная страница не была загружена должным образом с точки зрения пользователя в определенный момент нагрузочного теста.

6. Настройте резервные серверы и локации


Сбои могут случиться даже с Бейонсе (ну ладно, не с Бейонсе). Создавая резервные серверы и локации, вы можете быть уверены, что готовы продолжать предоставлять услуги в очень короткие сроки.

7. Проверьте ваши сторонние интеграции


Когда вы вносите изменения в свое приложение или сайт, вы не просто влияете на свой собственный продукт. Вы также можете влиять на сторонние сценарии в своем приложении или на сайте или же можете вызвать сбой сторонних устройств и серверов, если не подготовите их должным образом. Например, для разных CDN требуются разные подходы, а для балансировки нагрузки AWS (ELB) требуется прогрев перед балансировкой.

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

8. Внедрить мониторинг API


После того, как вы закончите тестирование, вам все равно захочется узнать, как ваш сайт ведет себя в дикой природе. Вы можете использовать возможности функционала BlazeMeter 360 Degree Monitoring для мониторинга ваших критически важных API-интерфейсов в производственной среде, чтобы убедиться, что ваш веб-сайт или приложение функционируют должным образом. Он будет служить системой предупреждения, чтобы вы знали, когда ваша система работает не так, как от нее ожидают.

Скрытый текст
Хотите прокачать свое тестирование? Подпишитесь на бесплатную онлайн-аккредитацию в университете BlazeMeter здесь.

Готовы начать тестирование производительности вашего сайта? Вы можете бесплатно воспользоваться платформой непрерывного тестирования BlazeMeter и начать тестирование своего сайта в ближайшие несколько минут. Зарегистрируйтесь здесь, чтобы начать тестирование.



Узнать подробнее о курсе.


Подробнее..

Анатомия юнит тестирования

21.06.2020 20:19:44 | Автор: admin
Юнит тесты обязательная часть моих проектов. Это база, к которой добавляются другие виды тестов. В статье Тестирование и экономика проекта, я изложил доводы почему тестирование выгодно для экономики проекта и показал, что юнит тестирование лидирует с экономической точки зрения. В комментариях было высказано мнение, что тестирование требует больших усилий, и даже юнит тестирование не приемлемо из-за этого. Одной из причин этого является неопытность команды в тестирование. Чтобы написать первую тысячу тестов команда тратить много времени, пробуя и анализируя различные подходы.

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


Вначале мое определение юнит тестирования это тестирование одного продакш юнита в полностью контролируемом окружении.

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

О наследование


Постарайтесь не применять наследование. Вместо него используйте композицию зависимостей. Часто наследование применяют для реализации принципа DRY (dont repeat yourself) вынося общий код в родителя, но тем самым нарушая принцип KISS (keep it simple stupid) увеличивая сложность юнитов.

AAA (Arrange, Act, Assert) паттерн.


Если посмотреть на юнит тест, то для большинства можно четко выделить 3 части кода:
Arrange (настройка) в этом блоке кода мы настраиваем тестовое окружение тестируемого юнита;
Act выполнение или вызов тестируемого сценария;
Assert проверка, что тестируемый вызов ведет себя определенным образом.
Этот паттерн улучшает структуру кода и его читабельность, однако начинать писать тест нужно всегда с элемента Act.

Driven approach.


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

Суть в том, что код который вы пишите должен иметь причину своего существования. Важно, что бы причина была существующей, а не предполагаемой, и эта причина должна иметь в конечном итоге связь с бизнес историей.
С чего мы начинаем разработку конкретного функционала? с требований бизнеса, которые типично выглядят так: Пользователь с любой ролью должен иметь возможность создать запись, таким образом он выполнить такую то бизнес операцию.
Используя driven approach первое что мы должны сделать
  • Это создать место в UI слое, где пользователь может создать запись, скажем страницу в приложении, на которой будет кнопка Создать запись. Почему мы это сделали? потому что это требует бизнес история.
  • Кнопка Создать запись будет требовать реализации обработчика click события.
  • Обработчик события будет требовать реализации создания записи в терминах слоя бизнес логики.
  • В случае клиент-серверной архитектуры, клиент будет обращаться к некоторому end point на стороне сервера для создания этой записи.
  • Сервер в свою очередь может работать с базой данных, где такая запись должна быть создана в отдельной таблице.


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

Данные подход позволяет небольшими шагами реализовывать сложные бизнес истории, оставаясь все время сфокусированным только на нужном функционале и избегать over engineering.

AAS (Act, Assert, Setup) паттерн.



AAS этот тот же AAA паттерн, но с измененным порядком частей, отсортированных с учетом Driven approach и переименованной Arrange частью в Setup, чтобы отличать их по названию.

Первое, что мы делаем, при создании теста мы создаем Act. Обычно это создание экземпляра класса тестируемого юнита и вызов его функции. С одной стороны это самый простой шаг, а с другой это то, что диктует нам бизнес история.
Второе мы проверяем что Act действует ожидаемо. Мы пишем Assert часть, где выражаем требуемые последствия Act, в том числе с точки зрения бизнес истории.

И вот когда у нас готовы первые 2 части мы можем остановиться и подумать, как наш юнит будет выполнять требуемые действия. Да, да, именно сейчас мы можем первый раз задуматься, как реализовать его.

Смотрите, сам вид Act и его сигнатура продиктованы предыдущим шагом, тут нам нечего изобретать. Как предыдущий шаг хочет вызывать наш юнит, так он и будет его вызывать. Ожидаемые действия тоже продиктованы предыдущим шагом и самой бизнес историей.

Так что именно сейчас, когда мы будем писать последнюю часть теста мы можем остановиться и продумать, как наш юнит будет работать и какое runtime окружение ему для этого нужно. И здесь мы переходим более подробно к Контролируемому окружению и дизайну юнита.

Принципы SOLID.



Из принципа SOLID, с точки зрения юнит тестирования очень важны 2 принципа:

Single responsibility principle позволяет снизить количество тест кейсов для юнита. В среднем на юнит должно приходиться от 1 до 9 тест кейсов. Это очень хороший индикатор качества юнита если тест кейсов больше или хочется их сгруппировать, то вам точно нужно разделить его на два и больше независимых юнитов.

Dependency inversion principle позволяет легко создавать и управлять сложнейшими окружениями для тестирования через IoC контейнеры. В соответствии с данным принципом, юнит должен зависеть от абстракций, что позволяет передавать ему любые реализации его зависимостей. В том числе, и не продакшен реализации, созданные специально для его тестирования. Эти реализации не имеет в себе никакой бизнес логики и созданы не только под конкретный тестируемый юнит, но и под конкретный сценарий его тестирования. Обычно они создаются с помощь одной из библиотек для mock объектов, такой как moq.

IoC контейнеры позволяют автоматически создавать экземпляр тестируемого юнита и экземпляры его зависимостей, сразу реализованные как mock объекты. Использование такого IoC контейнера очень важный шаг к снижению стоимости поддержания кода и его дружелюбности к автоматическому рефакторингу.

Качество кода


Кстати несколько слов о качестве кода тестов и продакшн. Самым качественным кодом должен быть код тестов. Причина этому одна это его размер. На 1 строку продакшн кода в среднем приходиться 2-3 строки тестового кода, то есть его в 2-3 раза больше чем продакшн кода. В этих условиях он должен хорошо читаться, быть структурированным, иметь хорошую типизацию и быть очень дружелюбным к инструментам автоматического рефакторинга. Это цели, которые достойны отдельных мероприятий и усилий.

Однотипность тестирования


Много приложения реализовано в распределенной и модульной архитектуре, где разные части написаны на различных языках, скажем клиент-серверные приложения, где клиент написан под веб на typescript и сервер написанный на c#. Важной целью для таких проектов будет приведение тестов для любой части, независимо от языка к единому подходу. Это значит, что все тесты на проекте используют AAA или AAS подход. Все тесты используют mock библиотеки с похожим API. Все тесты используют IoC. И все тесты используют одинаковые метафоры. Это позволяет повысить переносимость удачных практик на разные части проекта, упростить адаптацию новых коллег (выучил раз и применяй везде).

Моя команда создает клиент-серверные приложения, где мы используем angular на клиенте и .net core для серверной части. В следующей статье я хочу показать на примерах, как мы пишем юнит тесты под angular и с#. Как мы делаем их похожими, как располагаем в проектах, какие библиотеки применяем.
Подробнее..

Как получить OpenIDOAuth2 токен для тестирования front-end rest сервисов?

27.06.2020 20:16:09 | Автор: admin
Сейчас трудно встретить систему в которая бы не была rest и не использовала OAuth. Особенностью архитектуры таких систем является необходимость наличия валидного токена для доступа к требуемому Frontend Business REST API в HTTP заголовке (хэдере) Authorization: Bearer TOKEN.

Поэтому если мы хотим напрямую проводить тесты через фронтальный rest нам нужен этот токен. Вопрос как его взять? И так это сделать красиво и правильно? Вот тут я не знаю.

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

Есть обычная типовая система с веб рест фронтом и типовым Single-Page-Application браузерным клиентом на JS. Аутентификация и авторизация KeyCloak с Authorization Code Grant.
Надо обеспечить регулярное нагрузочное тестирование фронтовых рест сервисов.

Задача достаточная простая, если у нас есть токены которые мы можем просто вставить в заголовок и использовать JMeter для генерации необходимого потока запросов. Вот тут я и споткнулся, веб браузер получает токен просто и естественно (KeyCloak JS), но как его получить без браузера методом последовательных HTTP запросов и без исполнения JS я так и не понял
Токен в системе проверяется непосредственно в рест сервисе, а не на API Gateway. Отключить проверку нельзя ибо нет такой возможностью. Просто тестировать без токена не получится.

Далее мы подумали, а почему бы не использовать имеющиеся у нас функциональные end-to-end Selenium тесты, но быстро отказались от этого так как необходимый ресурс одновременно работающих браузеров оказался достаточно велик. Для минимум 50 потоков нам нужны были 50Гб + 25 ядер. Однако, это дало нам идею что токен можно получить через Селениум, а далее передать его в JMeter для использования.

В результате, по быстрому был сделан MVP по следующей схеме:
  • Повышаем время жизни токенов для тестового окружения
  • Отключаем кэши в системе, чтобы сымитировать уникальность пользователей.
  • С помощью Selenium приложения поводим процедуры логина тестовой группы пользователей и сбрасываем в файл их токены. Для чтения токена используем вызов JS через WebDriver return keykcloak.token;
  • С помощью JMeter проводим нагрузочные тестирования с использование токенов пользователей
  • Отчет JMeter всем нравиться




Мы поставили время жизни токенов в 36 часов. Вторичный код авторизации забираем напрямую из соответствующей базы. Время логина одного пользователя составляет около 10 сек, что дает нам 360 токенов в час. Это позволяет при желании легко подготовить их достаточное количество.

Сейчас, оператор запускает на выделенном ноутбуке селениум для сбора токенов на ночь, и на утро подготовленный файл токенов готов и можно запускать JMeter для нагрузки.
Схема работает, заказчик доволен простотой и дешевизной решения, и предлагает перенести это уже на нормальные рельсы с парой контейнеров и запуском из Jenkins.

А мне вот решение кажется кривым. Ну должен же быть способ обойтись без селениума! Напишите если кто знает. Я не смог ничего нагуглить на тему тестирования OpenID&OAuth2.
Подробнее..

Как выбрать мобильные девайсы для тестирования и не налажать

05.07.2020 02:06:52 | Автор: admin
Данная статья написана специально для OTUS преподавателем курса QA Lead Анастасией Шариковой.





Всем привет! Меня зовут Анастасия Шарикова, я руковожу отделом тестирования в Bookmate и веду телеграм канал Yet another QA.

Уверена, что многие, когда приходили на позицию QA Leada, ожидали сложных и интересных задач по выстраиванию процессов, настройке системы автотестов, налаживанию функционального и нефункционального тестирования, в конце-концов задач по управлению сотрудниками. Но в итоге оказалось, что все это есть, но сочетается с такими бытовыми штуками, как расчет зарплат, определение бюджета на отдел и прочих проблем, связанных с финансами и зачастую от этого никуда не деться, особенно в маленьких и средних компаниях. Тем не менее, внимательность к таким темам отличный способ дополнительно повысить качество вашего продукта и найти и предотвратить проблем уже на самых ранних этапах.

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

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

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

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

Основные параметры, влияющие на подбор:


  • Внешняя аналитика: тут нам на помощь могут прийти как международные подборки по самым популярным устройствам (такие, как, например deviceatlas.com), так и банальные варианты типа сортировки в яндекс.маркете по самым популярным устройствам. Тут важно не купиться на удочку самых лучших телефонов, т.к мнение экспертов зачастую очень расходится с мнением обычных потребителей. Главное помнить про то, на какую страну и ЦА ориентирован ваш продукт, и основываться на этом условии.
  • Внутренняя аналитика: в этом случае у нас огромное количество вариантов, на что можно опираться, к тому же это самые четкие данные и именно по нашему продукту. Что же мы тут можем использовать? Данные систем аналитики, таких как Firebase или информацию по устройствам из Google Play. И важно не забывать брать в расчет не только устройства и оси, которыми пользуются ваши сотрудники, но и те, на которых система чаще всего ловит ошибки и креши.
  • Тенденции на рынке: каждый месяц на рынок выходят новые игроки и устройства, появляются обновления осей и новые лидеры рынка, и все это важно учитывать. Примеры то, насколько стало больше за последний год устройств со шторкой/бровкой или санкции США против Huawei.


Не забываем про особенности нашей аудитории:


Всегда важно помнить об особенностях конкретно вашего продукта и его ЦА и стараться избегать субъективности даже если вам кажется, что iPhone 11 Pro венец творения компании Apple, это не принесет вам особой пользы в работе, если аудитория вашего приложения для обработки фотографий школьники, которым родители подарили шестой или седьмой айфон. Это же работает и в обратную сторону если вы знаете, что вашим сервисом пользуются обеспеченные люди и оно будет установлено в основном на iPad Pro новейшей модели то придется раскошелиться на него, иначе жди беды.
Особенно важно заметить про страны пользования почти у всех стран есть свои фишки, так что аудитория приложения для условной Индии в среднем будет отличаться от пользователей из Скандинавии.

Важные особенности и фишки на примере iOS и Android:


Конечно, в рамках статьи не охватить все-все сложности и особенности, но я постараюсь упомянуть основные:

iOS


  • В сравнении с андроидом, мало устройств, и они не так уж и часто выходят, аналогично и с осями, которые надо учитывать.
  • Проще держать адекватный усредненный набор типов экранов и не забывать что у некоторых есть retina, это может быть важно для некоторых типов тестов. Но, конечно, не всегда. Тем не менее, основные баги по верстке можно словить на комбинации четырех-пяти айфонов от пятого до одиннадцатого. И не забывайте про шторку!
  • Учитывайте, какие вы поддерживаете версии iOS и старайтесь сделать так, чтобы они равномерно распределялись по устройствам.
  • Не забывайте про магию Split View режима и старайтесь держать хотя бы одно устройство, которое его поддерживает
  • Проблемой при закупке может всегда возникнуть цена, особенно, если вы стараетесь выпускать адаптированные версии в первую же неделю продаж но, с другой стороны айфоны и долго не протухают, так что это можно считать долгосрочным вложением. Конечно, кто-то тут может со мной поспорить, но на моей практике именно техника Apple жила дольше при постоянном использовании для нужд тестирования.


Android


  • Очень много устройств и это боль. И тут точно никуда без аналитики потому что именно на ней и должна в случае андроида оцениваться ваша аудтория, иначе придется покупать что попало, а это не приводит к продуктивным результатам. Опять же, есть соблазн тестировать на том, что модно, современно и быстро работает, но если ваши юзеры сидят на китайских Oppo то вы можете и не узнать, что там, оказывается, ничего и не запускается.
  • Учитывайте особенности оболочек андроида и сторов особенно внимательно надо работать с теми, которые отключают по умолчанию сервисы Google Play, в том числе и стор. Старайтесь держать в парке разные варианты, в том числе и голый андроид.
  • Если с планшетами в Apple все довольно просто, то в андроиде это чистое безумие, потому что большинство из них имеют старые оси, плохого качества экраны и очень медленное железо. Конечно, этого и стоило ожидать от планшетов за 1999 рублей, но если ваша аудитория ими пользуется, а вы делаете тяжелую игрушку, то ее может вырубать прямо на старте. Пример из жизни: компания, в которой я работала, заключила контракт с одним из производителей телефонов о том, что они предустанавливают наше приложение к ним, но когда телефоны пришли в офис оказалось, что в них настолько мало памяти, что не запускаются даже предустановленные приложения из коробки. Пришлось, конечно, упрощать наш сервис.
  • Помните, что несмотря на традиционное отношение к андроиду, как дешевым телефонам, в последние годы их флагманы стоят сравнимо с флагманами Apple, а то и больше, к тому же у них часто появляются такие экспериментальные особенности, как скошенные экраны, раскладушки и прочее.


Где покупать?


Надеюсь, что читателю этой статьи повезло или повезет, и этот вопрос его не коснется он лишь поставит таск в Jira на закупку и через пару дней получит свеженький телефон. Но что делать, если вы работаете в компании, где вам надо принимать это решение самим? Вариантов несколько:

  • Официальные представители: да, часто это может быть дороже, но зато скорее всего это более надежно и лучше гарантия. И лайфхак для тех, кто дочитал до этой части статьи: не всегда, но часто, если написать письмо в представительство определенного производителя о том, насколько вам нужно определенное устройство, объяснив, как вы будете его использовать, вам могут выслать его или бесплатно и навсегда, или во временное пользование. А это часто очень актуально.
  • Розничные магазины: тут я объединяю все магазины, которые продают не левак, с чеками и гарантией, например, своей. Серый не всегда плохой, особенно это может касаться айфонов, например. Главное покупать в проверенных местах, а не в палатке на рынке.
  • Avito и прочие: конечно, тут я объединяю все варианты покупки б/у у частников. Конечно, этого стоит избегать, но если вы осознаете, что вам кровь из носа нужен телефон, который не выпускают уже 3 года, а ваши юзеры упорно им пользуются то иногда стоит пойти на риск.
  • Сотрудники: и еще один лайфхак если спросить у ваших коллег, то наверняка выяснится, что у пары-тройки сотрудников в тумбочке валяется ненужный телефон, который они благородно могут отдать во временное или бессрочное пользование вашему отделу!


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



Узнать подробнее о курсе QA Lead от OTUS.


Подробнее..

Категории

Последние комментарии

© 2006-2020, personeltest.ru