...

суббота, 25 ноября 2017 г.

[Из песочницы] Быстрый старт с NRF51822

Мир блокчейна и криптовалют глазами космополита

История создания второй игры на Unity (или как я нашел силы после первого провала)

Моя компания не взлетела, 6 уроков ценою в 4 года жизни и $150 000

Как обманывают трейдеров на биржах криптовалют: расследование Business Insider

Загружайте аудио с YouTube в Telegram. @YouAutist_bot

Видео докладов с конференции Agile Kitchen в «М.Видео»

Готовимся к релизу в Appstore. Инструкция для новичков и лайфхаки

пятница, 24 ноября 2017 г.

[Перевод] [Опрос] Ваш самый нелегальный/неэтичный проект

Flussonic Watcher для интернет провайдера

От Александра Белла до «большой тройки»: краткая история развития биллинговых систем

Черная пятница 2017 — VDS в Москве и Амстердаме

Digital Transformation: Блокчейн в банке

Черная пятница айтишника, или Сказ о потере данных

Новая многообещающая методология разработки, которую уже назвали «убийцей Agile»*

OpenGL и Parallels Desktop 13

[Перевод] Лучшие VPN-решения для пользователей Linux

FPConf 2017. Интервью с Александром Вершиловым

[Перевод] Развитие стратегий устойчивости

Путь ASP.NET → PHP

[Перевод] Трёхмерная графика с нуля. Часть 2: растеризация

[Из песочницы]  «Угнать за 60 секунд» на примере одного каршеринга

Данные из Google Таблиц на вашем сайте

HPE ProLiant for Microsoft Azure Stack: частичка облака Azure под вашим полным контролем

[Перевод] Выпуск Rust 1.22 (и 1.22.1)

Работа мечты и поступление в вуз без экзаменов. Олимпиада «Я — профессионал» трек «Компьютерные науки»

четверг, 23 ноября 2017 г.

Intel устранила найденную экспертами Positive Technologies уязвимость в подсистеме Management Engine

Эта чёрная-чёрная пятница

Обзор программы Heisenbug 2017 Moscow

Первый HighLoad Cup: как мы это пережили

6 вопросов по проектированию IT-инфраструктуры: онлайн-инструменты лучше, чем суровый админ

БДСЛ-2017: Таня Бибикова о визуализации данных

Russian AI Cup: инструментарий участника

Версионирование и деплой кода PostgreSQL

Космическая съёмка Земли

Оптимизация фронтенда. Часть 2. Чиним tree-shaking в проекте на webpack

[Перевод] Как я получил 365K загрузок в App Store за две недели (и почему после этого ушёл из геймдева)

BPM в компании: пусть решают процессы

10 очевидных шагов для подготовки инфраструктуры интернет-магазина к Чёрной пятнице

Диагностика промышленных электродвигателей и генераторов по спектру потребляемого тока и предотвращение аварий

[Из песочницы] Психология восприятия формы в логотипах

RNN: может ли нейронная сеть писать как Лев Толстой? (Спойлер: нет)

среда, 22 ноября 2017 г.

TgGram — сервис создания сайтов для/из телеграм каналов

Exonum 0.3 — что мы улучшили в новой версии фреймворка для разработки блокчейнов

Какие правила английского нарушают наши иностранные коллеги. Часть 2

Вышла DuerOS — новая ОС с элементами ИИ

Обзор программы HolyJS 2017 Moscow: от WebAssembly до Yarn

Особенности ручного тестирования в ALM Works и Одноклассниках

Приглашаем на Atlassian Meetup 12 декабря

Разбор задач второго этапа Школы программистов HeadHunter 2017

Ещё один шажок к C++20. Встреча в Альбукерке

[Перевод] Десять лучших антивирусов для Linux

Визуализация процесса обучения нейронной сети средствами TensorFlowKit

Ежики на колесах: как мы поддерживаем качество связи в Москве

Как сделать простую трехмерную игрушку на Unity за два дня

Vivaldi 1.13 – всё под рукой

Программирование под ARM TrustZone. Часть 1: Secure Monitor

[Перевод] 6 строк глубокого обучения

Тройка, семерка, джокер — разбор решения задач из буклета GridGain на конференции Joker 2017

Отчет c мини-конференции Использование визуальных моделей в ИТ. Проверено опытом

[Перевод] Чем отличаются JavaScript и ECMAScript?

Задачи планирования и программирование в ограничениях

Apache Kafka и миллионы сообщений в секунду

[Перевод] Шум Перлина

fiber — легковесные процессы для Arduino

[recovery mode] redux-refine — простая радость перфекциониста

вторник, 21 ноября 2017 г.

GitHub предупредит разработчиков об уязвимостях в их проектах

Адаптивная вёрстка

Внутреннее устройство и оптимизация бандла webpack

Почему у вас нет будущего без стратегии?

Avito iOS Meetup: Winter Edition

Оно само упало, или следствие ведут колобки

Drone CI в облаке AWS для DevExtreme

Перформанс во всех смыслах: как прошёл DotNext 2017 Moscow

Анонс Java-конференции JBreak 2018: Соединяем точки

[Перевод] Использование SVG в качестве Placeholder’a

Как не положить тысячи серверов с помощью системы централизованного управления конфигурацией на примере CFEngine

[Перевод] Операционные системы Linux под разные задачи

[Перевод] Что происходит в Kubernetes при запуске kubectl run? Часть 1

Как мы построили программно-определяемый дата-центр в ящике стола

[Перевод] Используйте DevOps, чтобы превратить ИТ в стратегическое оружие

Short-линч приложения Райффайзен-Онлайн

Пример реализации общего индикатора производительности MS SQL Server

Протоколы распространения ключей на симметричных шифрах

Анализаторы Roslyn: повадки и места обитания

Ковыряем криптолокер, назовём его — «nekema»

понедельник, 20 ноября 2017 г.

Драконье Стекло или рассказ о игровом редакторе Larian Studios

Объединённая компания «Яндекс.Такси» и Uber планирует провести IPO в 2019 году

[Из песочницы] 10 инструментов для создания крутых презентаций

Когда стоит переходить к автоматизации тестирования

Pygest #18. Релизы, статьи, интересные проекты, пакеты и библиотеки из мира Python [5 ноября 2017 — 15 ноября 2017]

Hello Logify, или мониторим ошибки на установленных приложениях

[DotNetBook] Особенности выбора class/struct. Свой boxing, превращение Int в структуру, реализующую интерфейс

Russian Startups Go Global 2017 — новые глобальные возможности для российских IT-предпринимателей

Как PacketZoom Mobile Expresslane увеличивает производительность приложений

Что делать, если не знаешь, как работает ПО

Куда катится техничка с полторашкой: хакатоны в Avito

[Перевод] Jest и Puppeteer: автоматизация тестирования веб-интерфейсов

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

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

О некоторых особенностях рассматриваемых тестов


Недавно я писал тесты интерфейсов и в это время наткнулся на пост Кента С. Доддса, посвящённый повышению стабильности тестов за счёт использования атрибута data-*. Это, если в двух словах, пользовательские атрибуты, которые можно задавать для практически любых HTML-элементов. Они особенно полезны при организации обмена данными с JavaScript-программами.

Материал Кента попался мне очень вовремя, так как я тогда пользовался примерно такими конструкциями:

await page.waitForSelector("#contact-form");
await page.click("#name");
await page.type("#name", user.name);

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

Тестирование формы обратной связи


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

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

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

Настройка проекта


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

Jest — фреймворк для тестирования, разработанный Facebook. Jest даёт платформу для автоматизированного тестирования, а также базовую библиотеку, позволяющую строить утверждения (Expect).

Puppeteer —  библиотека для Node.js, которая позволяет управлять браузером Chromium без пользовательского интерфейса. Инструмент это довольно новый, поэтому самое время его опробовать и подумать над тем, нужен ли он в конкретном проекте, и если нужен — о том, как встроить его в существующую экосистему.

Faker — библиотека для Node.js, которая умеет генерировать случайные данные. Среди них — имена, телефоны, адреса. Это, кстати, нечто вроде Faker для PHP.

Если у вас уже есть проект, на котором вы хотите поэкспериментировать, установить необходимые библиотеки можно такой командой:

npm i jest puppeteer faker --save-dev

Установка Puppeteer займёт некоторое время, так как, кроме прочего, в ходе установки библиотеки устанавливается и браузер Chromium.

Chromium — это веб-браузер с открытым исходным кодом, который является основой Google Chrome. Chromium и Chrome имеют практически одинаковые возможности, основные отличия заключаются в особенностях лицензирования.

После того, как всё необходимое будет установлено, настроим Jest в package.json. Команда test должна указывать на исполняемый файл Jest:

"scripts": {
  "test": "jest"
}

Кроме того, в Jest я предпочитаю пользоваться такой конструкцией:
import puppeteer from "puppeteer";

Поэтому тут нам понадобится Babel для Jest:
npm i babel-core babel-jest babel-preset-env --save-dev

После установки Babel создадим в папке проекта файл .babelrc со следующим содержимым:
{
  "presets": ["env"]
}

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

Пишем тесты


Создадим новую директорию в папке проекта. Назвать её можно test или spec. Затем, в этой директории, надо создать файл form.spec.js.

Теперь предлагаю рассмотреть код тестов по частям, начав с секции импорта. Ниже я приведу весь этот код целиком.

Сначала импортируем Faker и Puppeteer:

import faker from "faker";
import puppeteer from "puppeteer";

Теперь зададим URL формы. Возможно, вы решите протестировать версию формы, которая находится в разработке и доступна локально, вместо того, чтобы подключаться к рабочему сайту:
const APP = "http://ift.tt/2AWAIcU"

Теперь, с помощью Faker, создаём фиктивного пользователя:
const lead = {
  name: faker.name.firstName(),
  email: faker.internet.email(),
  phone: faker.phone.phoneNumber(),
  message: faker.random.words()
};

Дальше — определяем некоторые переменные, необходимые для работы с Puppeteer:
let page;
let browser;
const width = 1920;
const height = 1080;

Теперь настраиваем поведение Puppeteer:
beforeAll(async () => {
  browser = await puppeteer.launch({
    headless: false,
    slowMo: 80,
    args: [`--window-size=${width},${height}`]
  });
  page = await browser.newPage();
  await page.setViewport({ width, height });
});
afterAll(() => {
  browser.close();
});

Здесь мы пользуемся методами Jest beforeAll и afterAll. Первый нам нужен из-за того, что перед выполнением тестов требуется запустить, с помощью Puppeteer, браузер. После запуска браузера мы можем открыть новую страницу. Когда тесты завершатся, браузер должен быть закрыт. Делается это в методе afterAll с помощью команды browser.close().

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

Тут мне хотелось бы сделать некоторые комментарии по поводу вышеприведённого фрагмента кода. А именно, обратите внимание на то, что я запускаю браузер в оконном режиме, используя параметр headless: false. В данном случае так сделано для того, чтобы иметь возможность записать происходящее на экране на видео и показать процесс тестирования. Выполняя реальные тесты с помощью описываемых инструментов обычно незачем наблюдать за тем, что происходит. Для того, чтобы браузер запускался без интерфейса, можно просто убрать параметры, используемые при вызове метода launch().

То же самое касается и команды setViewPort(), которую тоже можно убрать. Или, что даже лучше, можно настроить два разных окружения тестирования. Одно использовать для визуальной отладки (речь об этом пойдёт ниже), второе — для работы с браузером без пользовательского интерфейса.

Теперь пишем код тестов:

describe("Contact form", () => {
  test("lead can submit a contact request", async () => {
    await page.waitForSelector("[data-test=contact-form]");
    await page.click("input[name=name]");
    await page.type("input[name=name]", lead.name);
    await page.click("input[name=email]");
    await page.type("input[name=email]", lead.email);
    await page.click("input[name=tel]");
    await page.type("input[name=tel]", lead.phone);
    await page.click("textarea[name=message]");
    await page.type("textarea[name=message]", lead.message);
    await page.click("input[type=checkbox]");
    await page.click("button[type=submit]");
    await page.waitForSelector(".modal");
  }, 16000);
});

Обратите внимание на возможность использования конструкции async/await с Jest. Тут предполагается, что тестирование проводится с использованием одной из свежих версий Node.js.

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

  • Переход по адресу, заданному в константе APP.
  • Ожидание появления формы обратной связи.
  • Щелчки по полям и заполнение их данными.
  • Установка флажка.
  • Отправка формы.
  • Ожидание появления модального окна.

Обратите внимание на то, что функции Jasmine test(), в качестве второго параметра, передан тайм-аут (16000). Это позволяет наблюдать за тем, как именно браузер работает со страницей.

Если выполнять тестирование с использованием браузера, видимого на экране, и не задать при этом тайм-аут, возникнет следующая ошибка:

Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL

Если выполнять тестирование, запуская браузер без интерфейса, тайм-аут можно убрать.

Теперь всё готово и тестирование можно запустить следующей командой:

npm test

После этого остаётся лишь наблюдать за браузером, который сам работает со страницей.


Если кому интересно, это экранное видео было записано в Fedora с помощью recordmydesktop и такой команды:
recordmydesktop --width 1024 --height 768 -x 450 -y 130 --no-sound

Однако, это ещё не всё.

Тестирование других элементов интерфейса


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

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

describe("Testing the frontend", () => {
  test("assert that 

Let's block ads! (Why?)

[Перевод] Трёхмерная графика с нуля. Часть 1: трассировка лучей

6 вещей в интернете, которые люди понимают неправильно

Туту.ру: Как провести День айтишника своими силами и недорого

Оптимизация скорости визуализации веб-страниц

Давайте поговорим о Plesk с расширением Docker

PHP-Дайджест № 120 (1 – 19 ноября 2017)

Дайджест свежих материалов из мира фронтенда за последнюю неделю №289 (13 — 19 ноября 2017)

воскресенье, 19 ноября 2017 г.

[Из песочницы] Golang, PHP, Кинопоиск и Telegraph — Что их объединяет?

Время Bitcoin банков?

[Из песочницы] Чатбот, который «как Siri, только круче» на наивном Байесовском классификаторе

Сказ про резисторы и неонки

Как у нас устроено AB-тестирование. Лекция Яндекса

Как повысить производительность систем хранения данных в дата-центре

Дайджест интересных материалов для мобильного разработчика #230 (13 ноября — 19 ноября)

IaaS-дайджест: руководства, тренды и кейсы

[Перевод] [Опрос от программиста из Google] Есть ли жизнь после 35-40 лет? (для разработчика софта)

Карьера или наука: почему в Университете ИТМО не нужно выбирать что-то одно

Заборы из стеклянных кирпичей, заговор онлайн-переводчиков, удаленный взлом «Боинга»

Автоколебания и резонанс

[Из песочницы] Опыт выявления одного бага или как не надо оформлять свой код