...

понедельник, 16 января 2017 г.

Доставляем себе в офис чашку горячего кофе одной командой консоли


Друзья, сегодня я расскажу вам историю о том, как просто и изящно решить проблему еnd-to-еnd тестирования web-сервиса доставки кофе с помощью нового open source тестового фреймворка. Мы проведем проверку не только работы сайта, но и менеджеров и даже службы доставки, к тому же потратим на это минимум усилий и времени. А в качестве бонуса за приложенные усилия получим кружечку горячего кофе прямо в руки. Всех любителей приключений прошу под кат…


На сегодняшний день необходимость e2e web-тестирования уже ни для кого не новость. Вопрос о выборе сервиса для тестирования рано или поздно встает ребром для любого web-приложения. Широкой публике известны различные Selenium-производные решения, подавляющее большинство которых построено на использовании WebDriver. Мы же собираемся продемонстрировать работу с новым open source тестовым фреймворком TestCafe, построенным на совершенно ином принципе. Перейдем же, наконец, от разговоров к делу.


Установка TestCafe


Как всегда начинается все с установки продукта. Это конечно совсем скучно, но я вас обрадую, полная установка TestCafe выполняется всего одной командой консоли.


npm install -g testcafe

Если вам приходилось устанавливать Selenium или базирующиеся на нем фреймворки, то вы приятно удивитесь насколько просто и быстро это делать c TestCafe. Как вы могли заметить, TestCafe построен на Node.js, а это значит — никаких Java, никаких плагинов для браузера или привязок к операционной системе. Все, что вам необходимо, это иметь Node.js на своем компьютере.


Теперь создадим файл, в котором будет находиться наш тест, назовем его get-a-cup-of-coffee.js. В файле создадим fixture — набор тестов, укажем адрес страницы и создадим пустой тест.


fixture `Let\'s take a look at the new TestCafe`
   .page `http://www.pitcofe.ru/`;

test(`Get a cup of coffee`, async t => {
// TODO: test
});


Одной из приятных особенностей TestCafe фреймворка является то, что в тесте вы можете использовать ES6 и ES7 синтаксис, независимо от того, поддерживает ли его браузер или ваша версия Node.js. TestСafe, с помощью Babel, транслирует весь код в синтаксис ES5.


Написание теста


Выполнение действий с элементами страницы


Приступим к написанию теста. Перейдем в раздел доставки горячего кофе. Все предельно просто — нажимаем на пункт "Меню" и выбираем пункт "Кофе".
image


test(`Get a cup of coffee`, async t => {
    await t
        .click(Selector('#nav').find('a').withText('меню'))
        .click(Selector('#content').find('#smenu-150'));
});

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


Для указания элементов, с которыми необходимо провести действия, мы воспользовались селекторами. Селекторы в TestCafe позволяют проделывать всю работу, связанную с DOM элементами. Для этого необходимо указать способ получения элемента на клиенте, например, css — селектор или функцию. А также TestCafe предоставляет API для создания составных селекторов, которые позволяют находить элемент по расположению в иерархии страницы или по заданным фильтрам (текст, индекс и любые кастомные фильтры).


После того как мы перешли в необходимое нам меню, добавим в корзину чашечку "классического Латте":
image


await t.click(Selector('.title').withText('Латте классический').sibling('.labels'));

Проверка состояния элементов страницы


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


await t.click('.myShop-cartmini');

Для проверки используем предоставляемые TestCafe встроенные assertion-ы. А чтобы получить значение интересующего нас свойства элемента страницы снова воспользуемся селекторами. Селекторы содержат набор асинхронных свойств и методов, которые можно непосредственно исполнить в тесте или передать в assertion. Во втором случае assertion-ы активируют механизм ожидания. Ведь очень часто необходимо дождаться завершения анимации, или получения ответа на XHR запрос прежде, чем выполнять assertion.


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


Проверим число и наименование товаров в корзине.


image


const items = Selector('.myShop-cart-item');

await t
    .expect(items.count).eql(2)
    .expect(items.nth(0).innerText).contains('Латте классический')
    .expect(items.nth(1).innerText).contains('Доставка');

Выполнение кода на клиенте


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


const getOderCount = ClientFunction(() => document.querySelectorAll('.myShop-cart-item').length);

let orderCount = await getOderCount();

Существует также способ немедленного исполнения кода на клиенте — использование метода t.eval.


orderCount = await t.eval(() => document.querySelectorAll('.myShop-cart-item').length);

Проверим, что полученные данные соответствуют нашим ожиданиям.


await t.expect(orderCount).eql(2);

Завершение и оформление заказа


Вернемся в меню выбора кофе и добавим в корзину чашечку “Флэт Уайт Попкорн”:
image


await t
    .click('.myShop-cartmini')
    .click(Selector('#content').find('#smenu-150'))
    .click(Selector('.title').withText('Флэт уайт попкорн').sibling('.labels'));

Снова перейдем в корзину и проверим, что число и наименование товаров изменилось.


await t
    .click('.myShop-cartmini')
    .expect(Selector('.myShop-cart-item').count).eql(3)
    .expect(Selector('.myShop-cart-item').nth(0).innerText).contains('Латте классический')
    .expect(Selector('.myShop-cart-item').nth(1).innerText).contains('Флэт уайт попкорн')
    .expect(Selector('.myShop-cart-item').nth(2).innerText).contains('Доставка');

Теперь завершим оформление заказа — перейдем на страницу заполнения контактных данных и адреса доставки. Заполнив необходимые поля останется только нажать кнопку "Отправить".


image


await t
    .click('.myShop-button-order')
    .typeText('#ffio', 'Ваше Имя')
    .typeText('#ftel', '+79999999999')
    .click('#fgorod')
    .click(Selector('#fgorod > option').withText('Ростов-на-Дону'))
    .typeText('#fulica', 'Ленина')
    .typeText('#fdom', '1')
    .click('input[type="submit"]');

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


Запуск теста


Запустим тест следующей командой консоли:


testcafe chrome get-a-cup-of-coffee.js

TestCafe найдет установленный на машине браузер, сам запустит его и выполнит тест.


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


Запустим выполнение теста без падения на ошибках страницы следующей командой консоли:


testcafe chrome get-a-cup-of-coffee.js --skip-js-errors 

image
Отчеты о прохождении тестов могут быть представлены в различных форматах, для этого существуют набор соответствующих плагинов. Они позволяют настроить работу с основными системами непрерывной интеграции. Вы можете запускать тесты не только на локальных, но и на удаленных и облачных устройствах (например Sauce Labs). Для окончательной автоматизации нашего сервиса нам осталось интегрировать полученный результат в систему непрерывной интеграции. Кто знает, возможно в будущем нам захочется добавить проверку температуры кофе, времени его доставки или даже его вкуса. Про автоматизации и интеграцию этого процесса мы, пожалуй, напишем отдельную статью :).


Выводы


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


Готовый пример можно найти здесь. Мы использовали методологию PageObject, которая позволяет сделать код теста более читаемым и понятным.


Надеюсь после прочтения вы заглянете к нам в TestCafe на чашечку кофе. Обсудить все интересующие вопросы можно в комментариях или на discuss. Кофейного вам дня!

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

    Let's block ads! (Why?)

    Комментариев нет:

    Отправить комментарий