В Vue Fes Japan 2018 я нашел очень интересную презентацию, посвященную тестированию компонентов Vue и, в частности, визуальному тестированию. Я впервые узнал о рег-визе / рег-костюме. Это отличный инструмент для повышения скорости визуального тестирования.
TL;TR
Разве не будет здорово, если вы сможете получать визуальные различия, подобные приведенным ниже, при каждой загрузке в репозиторий? Вот что может reg-suit
.
reg-suit
подробно объясняется в их репозитории README. Кроме того, у них есть демонстрационный репозиторий для тестирования визуального тестирования с помощью GitHub, AWS S3, CircleCI здесь. Одна вещь, которую я хотел избежать, - это использовать облачного провайдера для тестирования этой функциональности (я хочу по возможности избегать использования кредитной карты). Вот почему я использовал Minio вместо AWS S3 - частное облачное хранилище, совместимое с S3 API, - и я собираюсь объяснить, как вы можете протестировать его самостоятельно, ниже.
Требования
Прежде всего, вам нужно подготовиться и получить базовые знания о следующем, чтобы все работало:
- Node.js
Основная среда выполнения, используемаяreg-suit
и связанными с ней инструментами. - Докер
Чтобы легко запускать Minio и передавать содержимое через Nginx - учетная запись ngrok и двоичный файл
Чтобы легко опубликовать Minio и Nginx с помощью HTTPS - Учетная запись GitHub
Для интеграцииreg-suit
с репозиторием GitHub - Учетная запись CircleCI
Для запускаreg-suit
с CI
Создать проект
$ mkdir reg-puppeteer-demo-with-minio $ cd reg-puppeteer-demo-with-minio $ git init $ npm init
Создать страницу
Давайте создадим демонстрационную страницу.
$ touch index.html
Откройте файл index.html
в редакторе и вставьте следующее содержимое (не обращайте внимания на подробности здесь):
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.css" /> <style> body { background: #d7d8d9; margin: 0 auto; } .cards { margin: 0 auto; padding: 60px 0; width: 480px; } .ui.card.large { width: 100%; } </style> </head> <body> <div class="cards"> <div class="ui raised card large"> <div class="content"> <div class="header">It's a real "Robot Guitar"</div> </div> <div class="image"> <img src="https://github.com/reg-viz/reg-puppeteer-demo/blob/master/assets/photo.jpg?raw=true" /> </div> <div class="content"> <span class="right floated"> <i class="heart outline like icon"></i> 25 likes </span> <i class="comment icon"></i> 3 comments </div> <div class="extra content"> <div class="ui large transparent left icon input"> <i class="heart outline icon"></i> <input type="text" placeholder="Add Comment..." /> </div> </div> </div> </div> </body> </html>
Вы должны увидеть что-то подобное, когда откроете index.html
.
Создайте сценарий для создания снимков экрана
Чтобы reg-suit
зафиксировал визуальные различия, нам нужно создать снимки экрана index.html
. Reg-puppeteer-demo использует Puppeteer для достижения этой цели, поэтому давайте установим его и напишем простой скрипт.
$ npm install -D puppeteer mkdirp $ touch capture.js
Откройте capture.js
и вставьте следующее содержимое:
const puppeteer = require('puppeteer'); const mkdirp = require('mkdirp'); async function main() { const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] }); let page = await browser.newPage(); page.setViewport({ width: 640, height: 680 }); await page.goto(`file://${__dirname}/index.html`); await new Promise(res => setTimeout(() => res(), 300)); await page.screenshot({ path: 'screenshot/index.png' }); await page.close(); await browser.close(); } mkdirp.sync('screenshot'); main();
Подготовьте Minio
А теперь приготовим Минио. Простая архитектура выглядит следующим образом:
Поскольку это тестовая среда, мы собираемся использовать ngrok, чтобы открыть соединение TSL с нашей локальной средой. Убедитесь, что у вас есть учетная запись и двоичный файл ngrok
. Поскольку reg-suit загружает отчет в Minio, нам нужно просмотреть и этот отчет. S3 может размещать веб-сайты из коробки, но Minio не может. Вот почему мы также готовим контейнер Nginx для просмотра содержимого внутри Minio.
Сначала создадим docker-compose.yml
файл и вставим его содержимое:
version: '3' services: minio: image: minio/minio ports: - '9000:9000' env_file: - .env volumes: - ./.tmp_data:/data command: ['server', '/data'] web: image: nginx volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf ports: - '8080:80' command: "nginx -g 'daemon off;'"
Создайте .env
файл
Давайте создадим .env
файл, чтобы хранить учетные данные Minio внутри переменных среды. (Несмотря на то, что это тестовая среда, давайте не будем фиксировать учетные данные.)
MINIO_ACCESS_KEY=SUPERAWESOMEACCESSKEY MINIO_SECRET_KEY=SuPeRaWeSoMeSeCrEtKeY
Создайте каталог данных
Давайте также сохраним данные minio вне контейнера. Создайте каталог .tmp_data
, чтобы подключить его к контейнеру minio.
$ mkdir .tmp_data
Создать конфигурацию Nginx
Создайте файл с именем nginx.conf
со следующим содержимым:
server { listen 80; server_name localhost; location / { rewrite ^/$ /static/index.html break; proxy_set_header Host $http_host; proxy_pass http://minio:9000/static/; } }
Nginx будет обратным прокси-сервером, указывающим на сегмент Minio под названием static
. Сюда reg-suit
загрузит отчеты.
Запустите контейнеры
Теперь, когда мы подготовили контейнеры, приступим к ним!
$ docker-compose up -d # Check the logs $ docker-compose logs -f
Интеграция с ngrok
Теперь мы можем запустить ngrok, чтобы службы могли получить доступ к Minio из Интернета.
# Open Minio $ ngrok http 9000 # Open Nginx to serve Minio files $ ngrok http 8080
Линии, на которых вы должны сосредоточить внимание, следующие:
# Minio https://0880c053.ngrok.io -> localhost:9000 # Nginx https://c8a8fd88.ngrok.io -> localhost:8080
Доступ к Minio
Как видите, мы можем получить доступ к Minio из Интернета.
Доступ к Nginx
Похоже на страницу с ошибкой, но это от Minio. Вы также можете подтвердить, что Nginx доступен через ngrok.
Настроить Minio
Мы собираемся настроить сегмент Minio и разрешения с помощью Minio Client mc
. Выполните следующие команды через контейнер докера:
# Spin up an interactive docker container $ docker run -it --entrypoint=/bin/sh minio/mc # Add a host (be sure to set the ngrok address for Minio) $ mc config host add myminio https://0880c053.ngrok.io SUPERAWESOMEACCESSKEY SuPeRaWeSoMeSeCrEtKeY Added `myminio` successfully. # Create a bucket named `static` $ mc mb myminio/static Bucket created successfully `myminio/static`. # Add a policy so Nginx can reference the files $ mc policy download myminio/static Access permission for `myminio/static` is set to `download`
Подготовьте репозиторий GitHub
Создайте репозиторий под названием reg-puppeteer-demo-with-minio
на GitHub.
Затем давайте переместим наш локальный репозиторий на GitHub. Но перед этим давайте создадим .gitignore
файл со следующим содержанием:
node_modules .tmp_data/ .env
Теперь давайте зафиксируем и отправим на GitHub:
git add --all git commit -m "initial commit" # Be sure to change the repo to your own git remote add origin https://github.com/<YOUR_GITHUB_USERNAME>/reg-puppeteer-demo-with-minio.git git push -u origin master
Добавить и настроить приложение reg-suit GitHub
Затем давайте добавим приложение reg-suit GitHub для интеграции с нашим репозиторием. Щелкните ссылку ниже:
Https://github.com/apps/reg-suit
Вы должны увидеть такую страницу:
Продолжайте и установите приложение. Я выбрал только этот конкретный репозиторий (reg-puppeteer-demo-with-minio), но выбрал то, что подходит.
Теперь вы должны увидеть страницу рег-костюма, как показано ниже:
Подготовить библиотеку reg-suit
Добавим в наш проект reg-suit
:
$ npm install -D reg-suit
После этого давайте инициализируем его. Вот как это выглядит:
$ npx reg-suit init [reg-suit] info version: 0.7.17 ? Plugin(s) to install (bold: recommended) (Press <space> to select, <a> to toggle all, <i> to inverse selection) ❯◉ reg-keygen-git-hash-plugin : Detect the snapshot key to be compare with using Git hash. ◉ reg-notify-github-plugin : Notify reg-suit result to GitHub repository ◉ reg-publish-s3-plugin : Fetch and publish snapshot images to AWS S3. ◯ reg-notify-gitlab-plugin : Notify reg-suit result to GitLab repository ◯ reg-notify-slack-plugin : Notify reg-suit result to Slack channel. ◯ reg-publish-gcs-plugin : Fetch and publish snapshot images to Google Cloud Storage. ◯ reg-simple-keygen-plugin : Determine snapshot key with given values ? Working directory of reg-suit. .reg ? Append ".reg" entry to your .gitignore file. Yes ? Directory contains actual images. screenshot ? Threshold, ranges from 0 to 1. Smaller value makes the comparison more sensitive. 0 [reg-suit] info Set up reg-notify-github-plugin: ? notify-github plugin requires a client ID of reg-suit GitHub app. Open installation window in your browser Yes ? This repositoriy's client ID of reg-suit GitHub app MzS1MLcwMDay1C9KTdctKC0oSC1JTS3STUnNzdctzyzJ0M3NzMvM1zcxNzQ2ttDPTs1LS0ktAwA= [reg-suit] info Set up reg-publish-s3-plugin: ? Create a new S3 bucket No ? Existing bucket name static
Примечание: открыть окно установки в вашем браузере Да
Когда вы ответите на вопрос выше, вы должны увидеть страницу рег-костюма, которую вы видели ранее. Вы можете нажать Get client ID
и скопировать Client ID
, чтобы ответить на следующий вопрос:
Ваш regconfig.json
должен выглядеть следующим образом:
{ "core": { "workingDir": ".reg", "actualDir": "screenshot", "thresholdRate": 0, "addIgnore": true, "ximgdiff": { "invocationType": "client" } }, "plugins": { "reg-keygen-git-hash-plugin": true, "reg-notify-github-plugin": { "clientId": "MzS1MLcwMDay1C9KTdctKC0oSC1JTS3STUnNzdctzyzJ0M3NzMvM1zcxNzQ2ttDPTs1LS0ktAwA=" }, "reg-publish-s3-plugin": { "bucketName": "static" } } }
Кроме того, нам нужно настроить reg-publish-s3-plugin
так, чтобы он указывал на Minio, а не на AWS. Отредактируйте его, как показано ниже:
"reg-publish-s3-plugin": { "bucketName": "static", "customDomain": "c8a8fd88.ngrok.io", <- Your Nginx Domain "sdkOptions": { "endpoint": "https://0880c053.ngrok.io", <- Your Minio Endpoint "s3ForcePathStyle": true, "signatureVersion": "v4" } }
Теперь давайте добавим несколько скриптов npm для запуска тестов. Отредактируйте свои скрипты package.json
:
"scripts": { "test": "node capture.js", "reg-suit": "reg-suit run" },
Настройка рег-костюма завершена! Обязательно обновите .gitignore
, чтобы он выглядел так, и зафиксируйте / отправьте на GitHub:
node_modules .tmp_data/ .env .reg/ /screenshot/
зафиксировать и нажать:
$ git add --all $ git commit -m "configured reg-suit" $ git push origin master
Настроить CircleCI
Мы почти там! Теперь давайте настроим CircleCI. Давайте сначала создадим файл конфигурации.
$ mkdir .circleci $ touch .circleci/config.yml
Откройте config.yml
и вставьте содержимое ниже:
version: 2 jobs: build: docker: - image: regviz/node-xcb working_directory: ~/repo steps: - checkout # Download and cache dependencies - restore_cache: keys: - v1-dependencies-{{ checksum "package.json" }} # fallback to using the latest cache if no exact match is found - v1-dependencies- - run: npm install - save_cache: paths: - node_modules key: v1-dependencies-{{ checksum "package.json" }} # run tests! - run: npm test - run: npm run reg-suit
Я не буду вдаваться в подробности, но это npm install
модули и run the test
для создания захватов с помощью кукловода, а затем run reg-suit
для создания визуальных отчетов о тестах. Давайте также отправим это на GitHub:
$ git add --all $ git commit -m "add circleci" $ git push origin master
Настроить через Личный кабинет
Теперь перейдите на панель управления CircleCI (при условии, что у вас уже есть учетная запись). Давайте настроим наш проект.
У нас уже есть config.yml
, поэтому нажмите кнопку Start building
:
Это запустит вашу первую CI, но не удастся, потому что мы не установили учетные данные для Minio. Щелкните Gear Icon
в правом верхнем углу.
Ищите AWS Permissions
в разделе Permissions
. Теперь установите клавиши Minio, как показано ниже, и Save AWS keys
:
Теперь вернитесь к неудачному тесту и нажмитеRerun workflow
. Теперь вы должны увидеть, что ваши тесты проходят успешно!
Испытайте силу визуального тестирования
Наконец-то все готово. Давайте посмотрим, как cool reg-suit интегрируется с GitHub.
Представьте, что в какой-то момент какой-то сумасшедший добавил в ваш проект следующий класс css:
.extra.content { opacity: 0; }
Добавьте вышеуказанное в index.html
. Раздел style
теперь должен выглядеть так:
<style> body { background: #d7d8d9; margin: 0 auto; } .cards { margin: 0 auto; padding: 60px 0; width: 480px; } .ui.card.large { width: 100%; } .extra.content { opacity: 0; } </style>
Создадим для этого пиар:
$ git checkout -b adjust-css $ git add --all $ git commit -m "adjusted the css" $ git push origin adjust-css
Теперь после того, как вы нажмете Create pull request
, вы должны увидеть следующую страницу:
Видишь этого reg-suit
бота?
Этот бот просто потрясающий. Он говорит, что обнаружил визуальную разницу. Посмотрим на отчет.
Обратите внимание, что загрузка этой страницы может занять некоторое время, потому что между ними используется ngrok.
Не запуская эту среду для просмотра PR, вы можете увидеть, какие изменения были внесены визуально. Я почти уверен, что вы не одобрит этот пиар (кроме случаев, когда он преднамерен). Это сэкономит кучу времени при рассмотрении визуальных изменений, и это одна из тех революций, которые я пережил недавно.
Вы можете либо запросить изменения для этого PR, либо утвердить / объединить PR, чтобы reg-suit
использовал более новую версию для следующего сравнения. Так интуитивно понятно, не правда ли?
Заключение
Я почти уверен, что я не единственный, кто подумал: «Думаю, это изменение в порядке. Но позвольте мне проверить свою местную среду, чтобы убедиться ». при просмотре PR и обнаружил, что это действительно нормально. Напротив, я пропустил много регрессов, потому что я не знал (всех возможных) изменений, когда просматривал их. Это не то, в чем умеет большинство людей. Это то, что я хотел автоматизировать в течение долгого времени, и DX (опыт разработчика) reg-suit кажется действительно хорошим в этом.
Это был PoC, чтобы увидеть, легко ли он работает с Minio. Так оно и было! Так что теоретически, если вы объедините его с GitLab, этот рабочий процесс также должен работать локально.
GitLab + GitLab CI + Minio
Вау, это звучит довольно интересно, не так ли?
Если вы считаете, что рег-иск был интересным, давайте продемонстрируем нашу поддержку, выделив репо в главной роли!