Тестируем CSS в Selenium IDE

от автора

css

Я все больше в своей практике пытаюсь использовать автоматизированное тестирование. Стараюсь при этом не плодить инструменты и библиотеки, обходиться простыми подходами. Не так давно, я задумался о том, как протестировать CSS-файлы. Поиск по Интернету выявил следующие точки зрения на этот вопрос:

  1. Тестирование CSS не имеет смысла, так как это декларативный язык, а его результатом является сверстанное изображение страницы, которое можно оценить лишь визуально.
  2. Протестировать CSS можно с помощью снятия битмапов с сгенерированной страницы и сверка ее с эталонным изображением. Для этого даже есть некоторые инструменты.
  3. Нашлась некоторая библиотека CSS-Unit.

Должен сказать, что все варианты мне не понравились. В конечном итоге мне удалось протестировать CSS используя текстовый редактор, Firefox + Selenium IDE и… и больше ничего.

Немного теории

Наиболее конструктивные идеи мне принесла длительная медитация над вкладкой Firebag «Cкомпилированный стиль».

По содержимому этого окна стало ясно, что браузер генерирует страницу как минимум в два этапа.

  1. Определение всех параметров всех элементов, на основе CSS
  2. Верстка страницы, на основе полученных значений

Если второй этап никак не протестировать, кроме как битмапами, то первый, скорее всего, вполне поддается автоматизированному тестированию. А ведь именно на первом этапе возникают почти все ошибки в написании CSS. Больше половины жизни WEB-верстальщик проводит, рассматривая зачеркнутые и подсвеченные строчки в отладочном окне стилей, пытаясь понять, что от чего унаследовалось, и что к чему применилось. Если удастся это протестировать, мы снимем большинство проблем с CSS-файлами в нашем проекте.

Все, что нам нужно – это получить доступ к значениям, показывающимся в закладке Firebag «Cкомпилированный стиль». Недолгое рыскание по Интернету привело к обнаружению функции:

var style = window.getComputedStyle(element[, pseudoElt]); 

Название, говорит само за себя. Единственное, что можно пояснить – это второй параметр. Он может быть полезен, если мы захотим, например, узнать, какого цвета будет ссылка, если на нее наведут курсор. Осталось только вспомнить, что в Selenium IDE есть замечательное семейство функций xxxEval, которые могут вычислить любое JavaScript выражение. Теперь можно опробовать все это на практике.

Немного практики

Проводим небольшую подготовительную работу. Создаем структуру папок:

project – корень проекта  project/css – место для css  project/tests – место для тестовой инфраструктуры  project/tests/html-examples – место для тестовых примеров html-кода  project/tests/selenium-tests – место для Selenium-тестов 

Отдаем папку project под управление нашему любимому http-серверу, и настраиваем к нему доступ по адресу http://project.localhost.

В корне, по давно сложившейся привычке, заводим файл index.html, который делает наш проект похожим на реальный, а также символизирует исходный код проекта, безжалостно изменямый программистами независимо от нашей воли и желания. Одновременно заводим файл styles.css, который содержит css-код который мы будем разрабатывать и тестировать.

Предположим, в нашем проекте нам нужно выводить уведомляющие сообщения. Они должны выводится зеленым шрифтом. Сообщение состоит из заголовка <h1> и основного текста <p>. Шрифт заголовка 20px, основного текста 14px. Для размещения сообщений программисты зарезервировали контейнер <div class="notify-message">. В соответствии с этой ситуацией наши файлы index.html и styles.css на момент начала тестирования имеют следующий вид:

http://project.localhost/index.html

<html> <head>  <link rel="stylesheet" type="text/css" href="/css/styles.css">  </head>  <body>       <h1>Super project</h1>     <p>It's really very big and complex project !</p>      <div class="notify-message">         <h1>Hi,Guest</h1>         <p>Welcome to our beautiful world!</p>      </div>  </body>  </html> 

http://project.localhost/css/styles.css

div.notify-message h1 {    color:green;    font-size: 20px;  }   div.notify-message p {    color:green;    font-size: 14px;  } 

Нам нужно протестировать styles.css. Велик соблазн написать тест сразу с использованием index.html. Но мы помним, что он может меняться (а может и вообще исчезнуть при очередной смене тим-лидера). Поэтому воспроизводим требуемую ситуацию в файле notify-message-example.html

http://project.localhost/tests/html-examples/notify-message-example.html

<html>   <head>     <link rel="stylesheet" type="text/css" href="/css/styles.css">   </head>   <body>     <div class="notify-message">        <h1 id="h1-test">Notify message</h1>        <p id="p-test">It's notify message</p>      </div>   </body> </html> 

Для целевых объектов мы назначили id, чтобы быстрее их отыскать в DOM-структуре. Постфикс -test призван обозначить, что id предназначен лишь для целей тестирования. Открываем наш любимый Firefox с Selenium IDE и вводим следующий тест (исходники тестов, которые Selenium IDE сохраняет в HTML-формате, приводятся без тегов, чтобы улучшить читаемость):

http://project.localhost/tests/selenium-tests/notify-message-test.html

open    /tests/html-examples/notify-message-example.html verifyEval   window.getComputedStyle(window.document.getElementById('h1-test'),null).getPropertyValue('color');   green verifyEval   window.getComputedStyle(window.document.getElementById('p-test'),null).getPropertyValue('color');   green verifyEval   window.getComputedStyle(window.document.getElementById('h1-test'),null).getPropertyValue('font-size');   20px verifyEval   window.getComputedStyle(window.document.getElementById('p-test'),null).getPropertyValue('font-size');   14px 

Запускаем


[error] Actual value 'rgb(0, 128, 0)' did not match 'green'
[error] Actual value 'rgb(0, 128, 0)' did not match 'green

Оказывается getComputedStyle() возвращает цвета в виде rgb(r,g,b). Наверное, это правильно. В тестах не будет путаницы, если верстальщик будет использовать разные обозначения для одного и того же цвета. Корректируем тест.

http://project.localhost/tests/selenium-tests/notify-message-test.html v2

open    /tests/html-examples/notify-message-example.html verifyEval   window.getComputedStyle(window.document.getElementById('h1-test'),null).getPropertyValue('color');   rgb(0, 128, 0) verifyEval   window.getComputedStyle(window.document.getElementById('p-test'),null).getPropertyValue('color');   rgb(0, 128, 0) verifyEval   window.getComputedStyle(window.document.getElementById('h1-test'),null).getPropertyValue('font-size');   20px verifyEval   window.getComputedStyle(window.document.getElementById('p-test'),null).getPropertyValue('font-size');   14px 

Включаем режим паранойи

Естественно, к этому тесту наиболее въедливые тестировщики найдут что добавить. В частности, можно сделать проверку, что наши стили не затрагивают чистых <h1> и <p>.

http://project.localhost/tests/html-examples/clear-example.html

<html>   <head>     <link rel="stylesheet" type="text/css" href="/css/styles.css">   </head>   <body>     <h1 id="h1-test">Not message</h1>     <p id="p-test">It is not message</p>   </body> </html> 

http://project.localhost/tests/selenium-tests/clear-test.html

open   /tests/html-examples/clear-example.html verifyEval   window.getComputedStyle(window.document.getElementById('h1-test'),null).getPropertyValue('color');   rgb(0, 0, 0) verifyEval   window.getComputedStyle(window.document.getElementById('p-test'),null).getPropertyValue('color');   rgb(0, 0, 0) verifyEval   window.getComputedStyle(window.document.getElementById('h1-test'),null).getPropertyValue('font-size');   32px verifyEval   window.getComputedStyle(window.document.getElementById('p-test'),null).getPropertyValue('font-size');   16px 

Запускаем.

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

Делаем рефакторинг

Тесты написаны, что дальше? Дальше – все преимущества разработки с применением автоматизированного тестирования. Например, рефакторинг. Посмотрев на наш CSS файл, мы видим, что две строчки, касающиеся зеленого цвета повторяются. Попробуем это исправить. Пусть мы не совсем уверены в знании правил CSS, которые запомнить еще труднее, чем понять. Теперь нас это не остановит. Ведь наш код под защитой тестов.

http://project.localhost/css/styles.css v2

div.notify-message h1{   color:green; }  div.notify-message h1 {   font-size: 20px; }  div.notify-message p {   font-size: 14px; } 


[error] Actual value 'rgb(0, 0, 0)' did not match 'rgb(0, 128, 0)'

Ах, да!!! Забыли при копировании подправить селектор.

div.notify-message h1 {
color:green;
}

Тест пройден.

Разработка CSS в стиле TDD

Теперь мы можем полностью применять концепции Test Driven Development. Предположим, что поздно вечером (как обычно, перед деадлайном) к web-верстальщику приходит web-программист и начинает что-то невнятно бормотать и делать руками неопределенные жесты. (Прошу программистов не обижаться – это камень и в мой огород, так как мне приходится быть и тем и тем). Из спутанного рассказа становится ясно, что нужно еще и выводить сообщения об ошибке, которые должны быть красного цвета. При просмотре файлов проекта оказывается, что теперь файл index.html имеет следующий, никем не предугаданный, вид:

http://project.localhost/index.html v2

<html>   <head>     <link rel="stylesheet" type="text/css" href="/css/styles.css">   </head>   <body>     <h1>Super project</h1>     <p>It's really very big and complex project !</p>     <div class="notify-message">        <h1>Hi,Guest !</h1>        <p>Welcome to our beautiful word!</p>      </div>     <div class="error-message">        <h1>You are not authorized.</h1>        <p>Please login or register now.</p>      </div>   </body> </html> 

Оторвавшись от просмотра телесериала “Бэтмен навсегда”, засучив рукава, сохраняя по возможности хладнокровие, в соответствии с концепцией «сначала тесты», web–верстальщик создает файл:

http://project.localhost/tests/html-examples/error-message-example.html

<html>   <head>     <link rel="stylesheet" type="text/css" href="/css/styles.css">   </head>   <body>     <div class="error-message">        <h1 id="h1-test">Error message</h1>        <p id="p-test">It's error message</p>      </div>   </body> </html> 

И добавляет в Selenium IDE еще один тест:

http://project.localhost/tests/selenium-tests/error-message-test.html

open   /tests/html-examples/error-message-example.html verifyEval   window.getComputedStyle(window.document.getElementById('h1-test'),null).getPropertyValue('color');   rgb(255, 0, 0) verifyEval   window.getComputedStyle(window.document.getElementById('p-test'),null).getPropertyValue('color');   rgb(255, 0, 0) verifyEval   window.getComputedStyle(window.document.getElementById('h1-test'),null).getPropertyValue('font-size');   32px verifyEval   window.getComputedStyle(window.document.getElementById('p-test'),null).getPropertyValue('font-size');   16px  


[error] Actual value 'rgb(0, 0, 0)' did not match 'rgb(255, 0, 0)'
[error] Actual value 'rgb(0, 0, 0)' did not match 'rgb(255, 0, 0)'
[error] Actual value '32px' did not match '20px'
[error] Actual value '16px' did not match '14px'

В соответствии с классикой TDD тест не проходит. Дорабатываем CSS.

http://project.localhost/css/styles.css v3

div.error-message {   color:red; }  div.notify-message {   color:green; }  div.notify-message h1,  div.error-message h1  {   font-size: 20px; }  div.notify-message p,  div.error-message p {   font-size: 14px; } 

Тесты пройдены.

Развитие без препятствий

Приведенный пример элементарный, но думаю, что его можно масштабировать на большие проекты. Кроме очевидных выгод от автоматизированного тестирования есть еще положительные моменты. Постепенно в каталоге html-examples начнут накапливаться тестовые html-файлы. Их пользу трудно переоценить. Это — запротоколированные прецеденты использования html в проекте. Этими файлами можно пользоваться в спорных ситуациях, когда неясно кто прав – программист или верстальщик. Когда в команду придет новый человек, эти файлы здорово помогут войти в курс дела и в правила разработки.

В заключение приведу девиз TDD-разработчиков, который мне очень нравится:

Желаю Вам успешных проектов, красивых CSS-файлов и спокойного сна по ночам.

ссылка на оригинал статьи http://habrahabr.ru/post/190358/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *