Giter VIP home page Giter VIP logo

e2e-fatigue's Introduction

E2E Testing fatigue

Video

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

"Иногда вам может показаться, что ваша жизнь разработчика довольно скучна. Не давайте себе заскучать - займитесь тестированием, и ваша жизнь не будет больше скучной никогда."

Проблема

Несколько недель назад я получил задачу по покрытию тестами нашего мобильного приложения под iOS.

Опыт

У нас уже был опыт написания E2E-тестов для Android приложения, но в связи с появившимся свободным от разработки временем, поняли, что необходимо озадачиться тестами и под iOS. Тесты для приложения под Android были необходимостью, ибо версия для этой OS отличается "стабильной" нестабильностью. Было решено привлечь js-разработчиков для помощи Android-коллеге. Необходимость написания тестов под iOS осознали, ну впрочем как обычно, когда гром грянул.

Что есть Е2Е-тестирование?

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

Почему об этом стоит рассказать прямо сейчас?

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

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

В любом случае, этот доклад будет полезен и для вас.

Инструменты

Любой человек при решении совершенно новых для него задач начинает с выбора инструмента (-ов), которые помогут ему справиться с работой. С этого начали и мы. Если прямо сейчас выбирать среди инструментов для E2E-тестирования мобильных приложений под обе (прости MSFT) платформы, то гугл выдаст вам по сути два ответа - это Appium и Calabash. Отличия между инструментами просты:

  1. Appium работает со всеми языками, которые поддерживает Selenium Webdriver, а Calabash работает на Ruby.
  2. Если вы работали уже с Selenium Webdriver, то и с Appium вы работать умеете, а Calabash имеет свой API, но при этом сценарии можно писать на Cucumber.
  3. Appium имеет GUI для инспектирования элементов на странице (получения их id, xpath, etc), в Calabash для этого есть cli.
  4. Appium имеет больший круг поклонников ввиду низкого порога вхождения, а также аналогичного API как у Selenium Webdriver.

В общем, ввиду имеющегося опыта работы с Selenium Webdriver, а точнее с его js-реализацией webdriver.io, был выбран именно Appium.

В качестве фреймворка для тестирования и ассертов был выбран tape, а если быть точным, то его модификация tape-async. Tape написан тем же человеком, что и Browserify, ник на гитхабе substack. Tape мы уже использовали для unit и e2e-тестов в вебе, поэтому не видели необходимости что-то менять. А изначально выбор на него пал после прочтения статьи Эрика Эллиота на Medium.

Платформа для тестирования - iOS 9.3, iPhone Simulator (5s), Xcode 7.3.

С чего начать?

Если с запуском tape еще все ясно (главное - не забудьте зареквайрить babel-register), то с остальными инструментами придется повозиться.

Немного утилитарных вещей на старте упростят вам жизнь в будущем. Что сделали мы:

  1. Утилита для проверки - запущен ли Appium
  2. Утилита для нахождения запущенного симулятора
  3. Свой раннер тестов, чтобы реюзать существующий симулятор и синглтон хэлпера
  4. Ну и раннер всего и всея, чтобы проверить, что запущен Аппиум, найти нужный симулятор, который запущен, либо выбрать дефолтный, а также запустить, наконец, уже тесты.

Helper

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

  1. backToHome.js - позволяет из любого состояния вернуться на главный экран
  2. cache.js
  3. createMenuButtonId.js - возвращает xpath для указанной кнопки на главном экране
  4. fixLocationError.js
  5. getAttr.js - позволяет получить значение атрибута для указанного xpath элемента
  6. getSource.js
  7. init.js
  8. iosDoneButtonIdCreator.js
  9. login.js - произведет авторизацию для указанного (дефолтного) пользователя
  10. logout.js - разлогинится в приложении
  11. mapOverVisible.js
  12. skywalker.js

Выделенные функции, пожалуй, самые полезные и популярные.

Договоренности

В команде существуют договоренности при написании тестов:

  1. Каждый тестовый набор должен начинаться с главного экрана (для консистентности).
  2. Каждый тестовый набор должен проходить, если запущен исключительно он, а также если он запущен в последовательности с другими тестовыми наборами.
  3. Каждый тестовый набор внутри себя должен выполнить все пререквизиты (залогиниться или разлогиниться, etc).
  4. Не использовать метод .pause(%TIME_IN_MS%) внутри тестов, т.к. он исключительно замедляет работу тестов, и ни к чему хорошему не приводит.
  5. Разрешается использовать .pause(%TIME_IN_MS%) там где вообще никак не поможет .waitForVisible(ELEMENT_XPATH, %TIME_IN_MS%) - у нас это один случай, и то только в Android. Так что помните - 99.9% задач решается без пауз.

К чему нужно быть готовым?

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

  1. Благо есть ситуации, когда это можно легко исправить путем увеличения времени по таймауту для метода .waitForVisible(), например, когда понимаете, что вот тут в приложении долго шел ответ от сервера, либо он принес большой кусок данных настолько, что лоадер отображался несколько дольше, чем вы ожидали изначально.
  2. Но бывает так, что вы сходу не можете понять и решить проблему, например, у нас есть кнопка в всплывающем экране, которая видна как на iPhone 5s, так и на iPhone 6 человеческому глазу. Код приложения не меняется, код тестов тоже. Мы просто сменили айфон и ожидаем, что все будет как и прежде, но нет. Увы, я пока что так и не разобрался в чем дело.

Как избежать большого количества проблем?

В процессе написания E2E-тестов с использованием Appium вы будете часто использовать Appium Inspector. Это инструмент, который, как вы поняли из названия, позволяет проинспектировать вьюхи приложения, с которым вы работаете. Он позволяет узнать вам id или xpath элементов текущего экрана. Внутри себя Appium Inspector для получения данных о вьюхе выполняет команду .getSource().

Во время написания тестов для приложений я заметил одну интересную особенность, которая видна в тот момент, когда вы выполните команду .getSource(). Интерес в том, что в Android и iOS эта команда работает одинаково хорошо, но сами OS возвращают несколько отличающийся результат. Пальма первенства отходит в этом случае к гугл. Android всегда вернет по команде .getSource() исключительно исходники видимой части вьюхи, в то время как iOS возвращает кроме видимой части еще исходники, например, главного экрана, а также элементов, которые видит человеческий глаз, но не видит система автоматизации. ПОЭТОМУ! Выключите раз и навсегда чекбокс "Show invisible" в Appium Inspector, чтобы однажды не задаться вопросом, а почему это я кнопку вижу, а мой метод .waitForVisible() все равно падает.

О чем еще стоит знать?

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

  2. Перед запуском теста пройдитесь полностью по нему с помощью симулятора и Appium Inspector.

  3. Смело выставляйте большие таймауты для .waitForVisible() там, где это возможно понадобится. Тут дело вот в чем - .waitForVisible() принципиально лучше, чем использование .pause() ввиду того, что его параметр для времени - это таймаут, а не время на приостановку чего-либо. Метод .pause() не гарантирует вам ничего, в то время, как .waitForVisible() гарантирует вам либо ошибку по истечению таймаута, либо успешное выполнение кода.

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

    try {
        await driver
            .waitForVisible(acceptTwitterAccountsAccess, 2000)
            .click(acceptTwitterAccountsAccess)
    } catch (e) {
        // Do nothing
    }
  5. Весь механизм работы тестов построен на промисах. Каждое действие — это запрос к Selenium Server, который имеет свой апи. Так что по сути, вам ничего не мешает делать запросы хоть из терминала, главное — знать что отправлять.

  6. iPhone Simulator никогда не запустится с первого раза. А если он перезапустился уже как минимум 3-4 раза, то смело останавливайте тест раннер, затем appium, подождите минутку и запускайте снова все - это помогает).

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

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

Планы на будущее

Мы с коллегой хотим все наши наработки выложить в open source в рамках Tipsi на github, обернем все в npm-модуль и выпустим.

e2e-fatigue's People

Contributors

isnifer avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.