Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Радости и гадости регрессионного тестирования вёрстки

Радости и гадости регрессионного тестирования вёрстки

Совместно с платформой Открытое образование мы запустили курс, посвященный основам HTML и CSS. Уже на момент регистрации на этот курс записалось более 12 тысяч студентов. Перед нами стояла задача разработать систему, которая будет автоматически проверять итоговые проекты на соответствие заранее подготовленному макету. В качестве основной техники для проверки было выбрано регрессионное тестирование.

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

Alexey Maleykov

April 22, 2016
Tweet

More Decks by Alexey Maleykov

Other Decks in Technology

Transcript

  1. Задача • Курс по основам HTML и CSS • 12

    000 пользователей записались на курс
  2. Задача • Курс по основам HTML и CSS • 12

    000 пользователей записались на курс • Автоматизация проверки
  3. var page = require('webpage').create(); page.open(url, function(status) { if (status ===

    'success') { … } }); Серверная проверка
  4. var page = require('webpage').create(); page.open(url, function(status) { if (status ===

    'success') { var result = page.evaluate(function() { return HtmlacademyTask.runChecks(); }); console.log(result); } }); Серверная проверка
  5. var page = require('webpage').create(); page.onConsoleMessage = function(msg) { console.log(msg); };

    page.onAlert = function(msg) { console.log(msg); }; page.open(url, function(status) { … }); Серверная проверка
  6. var page = require('webpage').create(); page.viewportSize = { width: width, height:

    height }; page.open(url, function(status) { if (status === 'success') { page.render(output); } }); Проверка
  7. Принцип работы • Макет • Образец вёрстки • Проверка пяти

    блоков 1. Разметка 2. Сетка 3. Оформление 1 2 3 4 5
  8. Принцип работы • Макет • Образец вёрстки • Проверка пяти

    блоков 1. Разметка 2. Сетка 3. Оформление • Проверка страницы целиком 1 2 3 4 5
  9. Принцип работы • Макет • Образец вёрстки • Проверка пяти

    блоков 1. Разметка 2. Сетка 3. Оформление • Проверка страницы целиком • Скриншоты (PhantomJS) 1 2 3 4 5
  10. Принцип работы • Макет • Образец вёрстки • Проверка пяти

    блоков 1. Разметка 2. Сетка 3. Оформление • Проверка страницы целиком • Скриншоты (PhantomJS) • Сравнение (ImageMagick) 1 2 3 4 5
  11. Работа с архивами – project.zip — img/ — css/ —

    index.html – Мой Проект.rar — Мой проект/ — img/ — css/ — стили.css — project_index.html
  12. Работа с архивами – project.zip — img/ — css/ —

    index.html – Мой Проект.rar — Мой проект/ — img/ — css/ — стили.css — project_index.html • To zip or not to zip
  13. Работа с архивами – project.zip — img/ — css/ —

    index.html – Мой Проект.rar — Мой проект/ — img/ — css/ — стили.css — project_index.html • To zip or not to zip • Поиск index.html
  14. Чужая вёрстка • Не знаем классов и идентификаторов • Не

    знаем тегов • Знаем только общую структуру
  15. Поиск нужных блоков body > *:nth-child(2) { box-shadow: inset 0

    0 0 6px #000000; } body > *:not(:nth-child(2)) { visibility: hidden; }
  16. Поиск нужных блоков body > *:nth-child(2) { box-shadow: inset 0

    0 0 6px #000000; } body > *:not(:nth-child(2)) { display: none; }
  17. var page = require('webpage').create(); page.open(url, function(status) { if (status ===

    'success') { page.evaluate(function() { … }); page.render(output); } }); Скриншоты блоков
  18. var page = require('webpage').create(); page.onResourceRequested = function(data, request) { if

    ((/.+\.css$/gi).test(data['url'])) { request.abort(); } }; page.open(url, function(status) { … }); Проверка разметки
  19. page.evaluate(function() { var links = document.querySelectorAll('[rel=stylesheet]'); [].forEach.call(links, function(element) { element.parentNode.removeChild(element);

    }); }); Проверка разметки var styles = document.querySelectorAll('style'); [].forEach.call(styles, function(element) { element.parentNode.removeChild(element); });
  20. page.evaluate(function() { var links = document.querySelectorAll('[rel=stylesheet]'); [].forEach.call(links, function(element) { element.parentNode.removeChild(element);

    }); }); Проверка разметки var styles = document.querySelectorAll('style'); [].forEach.call(styles, function(element) { element.parentNode.removeChild(element); }); var attrs = document.querySelectorAll('[style]'); [].forEach.call(attrs, function(element) { element.removeAttribute('style'); });
  21. <table> <tr> <td>Название</td> <td>Длительность</td> <td>Описание</td> </tr> <tr> <td>Дневное обучение</td> <td>4

    года</td> <td>Наиболее интенсивный вариант обучения, для тех, кто не терпит компромиссов ни в чем</td> </tr> </table> Особенности разметки
  22. <table> <thead> <tr> <td>Название</td> <td>Длительность</td> <td>Описание</td> </tr> </thead> <tbody> <tr>

    <td>Дневное обучение</td> <td>4 года</td> <td>Наиболее интенсивный вариант обучения, для тех, кто не терпит компромиссов ни в чем</td> </tr> </tbody> </table> Особенности разметки
  23. // первый уровень body > * { background: #333333; box-shadow:

    inset 0 0 0 4px #cccccc;
 } Поиск сеток
  24. // первый уровень body > * { background: #333333; box-shadow:

    inset 0 0 0 4px #cccccc;
 } body > *::before, body > *::after { visibility: hidden; } Поиск сеток
  25. Поиск сеток // второй уровень body > * > *

    { background: #660000; box-shadow: inset 0 0 0 4px #ff9999;
 }
  26. Поиск сеток // второй уровень body > * > *

    { background: #660000; box-shadow: inset 0 0 0 4px #ff9999;
 } body > * > *::before, body > * > *::after { visibility: hidden; }
  27. Поиск сеток // третий уровень body > * > *

    > * { background: #000066; box-shadow: inset 0 0 0 4px #9999ff;
 }
  28. Поиск сеток // третий уровень body > * > *

    > * { background: #000066; box-shadow: inset 0 0 0 4px #9999ff;
 } body > * > * > *::before, body > * > * > *::after { visibility: hidden; }
  29. Поиск сеток // третий уровень body > * > *

    > * { background: #000066; box-shadow: inset 0 0 0 4px #9999ff;
 } body > * > * > *::before, body > * > * > *::after { visibility: hidden; } // все уровни глубже body > * > * > * > * { visibility: hidden; }
  30. Результаты • 12 000 записались на курс • 5 700

    начали проходить • 1 000 успешно прошли курс • 830 приступили к итоговому испытанию • 520 успешно прошли итоговое испытание • 10 итоговых испытаний на 100%
  31. Регрессионное тестирование • SlimerJS
 slimerjs.org • CasperJS
 casperjs.org • PhantomCSS


    github.com/Huddle/PhantomCSS • BackstopJS
 garris.github.io/BackstopJS/ • Gemini
 gemini-testing.github.io/gemini/