Pull to refresh

Погружение в ACID3

Reading time13 min
Views3.8K
(Это первая статья из серии статей, посвященных обзору различных тестов браузеров.)

Что такое Acid3? Кто его придумал? Как он устроен и как он работает? Что он измеряет на самом деле? Этими и другими вопросами мы зададимся в данной статье и попробуем найти ответы.

Что такое Acid3?


Acid3 — это третий из серии специальных тестов (до этого были Acid1 и Acid2), написанных «в помощь производителям браузеров, чтобы те могли проверить поддержку стандартов в своих продуктах». Конкретно ACID3 нацелен на тестирование спецификаций, связаных с разработкой динамичных «Web 2.0»-приложений.



Acid3 включает 100 специальных тестов, проверяющих 19 различных спецификаций.

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

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



(Интересно, кстати, и то, что, согласно Google Trends, Россия в последние три года упорно входит в тройку стран, где про Acid3 говорят больше всего.)

Acid3 в плане использования в качестве мерилки “качества” браузера, пожалуй, стал самым ярким и широко используемым не только в сообществе и среди журналистов, но и иногда отдельными компаниями :)



В маркетинговом смысле дополнительное обманчивое впечатление создает “магия чисел” и привычный ассоциативный ряд 100 ~ 100%, что, конечно, с точки зрения поддержки стандартов, абсолютно не соответствует действительности.

В качестве примера – вот ролик с Вести.Net от 20 ноября 2010 г.:
…Вообще проверку Acid3 на поддержку всех веб-стандартов оба устройства проходят успешно, получая 100 очков из 100…

А вот за полгода до этого Компьюлента пинает предварительную версию IE9:
Медленно, но верно браузер учится адекватному пониманию основных веб-стандартов. Так, если первая редакция в тестах Acid3 «выбивала» 55 очков из ста возможных, то второй выпуск шасси уже набирает 68 пунктов.

А вот как в позапрошлом году про Safari 4 писали на iXBT:
Safari 4 — первый в индустрии веб-браузер, финальная версия которого полностью проходит тест на совместимость с веб-стандартами Acid3.

И последний пример, примерно в то же время cNews про Firefox Mobile (Fennec):
Тест Acid3 представляет собой тестовую страницу Web Standards Project, которая определяет, насколько движок браузера соответствует общепринятым стандартам, насколько правильно обрабатывает новые спецификации HTML и CSS и способен ли корректно отображать веб-страницы.

В данном контексте, как пишет Eric Meyer:
«Здесь важен тот факт, что реально Acid3 не является тестом, проверяющим широкий спектр стандартов. Это всего лишь маленький экспонат, что-то вроде потемкинской деревни. Это досадно, потому что если что и нужно сейчас, так это исчерпывающие наборы тестов для спецификаций – XHTML, CSS, DOM, SVG.»


Где же правда? И что там на самом деле внутри? С этим и будем разбираться.

Авторы


Основным разработчиком Acid3 является Ян Хиксон (Ian Hickson), ранее разработавший набор тестов Acid2. Хиксон входит в группу разработки стандартов CSS и, в частности, был соредактором спецификации CSS 2.1, а также вносит большой вклад в подготовку спецификации HTML5, являясь редактором этой и других связанных спецификаций.

Ян успел поработать в Mozilla Foundation, Netscape и Opera Software, сейчас работает в Google.

Говоря, что Ян является основным разработчиком, нельзя не упомянуть его коллег, также внесших свой вклад:
  • Sylvain Pasche. Тесты 66–67 (DOM)
  • David Chan. Тест 68 (UTF-16/UCS-2)
  • Simon Pieters (Opera) и Anne van Kesteren (Opera). Тест 71: парсинг HTML
  • Jonas Sicking (Mozilla) и Garrett Smith. Тест 72: динамическое изменение стилей текстовых блоков
  • Jonas Sicking (Mozilla). Тест 73: Вложенные события
  • Erik Dahlström (Opera). Тесты 74–78: SVG и SMIL.
  • Cameron McCormack (Batik SVG library). Тест 79: шрифты в SVG.

Изначально Acid3 рассматривался как независимый тест. В настоящее время тесты ACID также продвигаются как одна из активностей WaSP (Web Standards Project). (Иногда это вводит в заблуждение, т.к. организация со словом “веб-стандарты" за спиной иногда является “весомым” аргументом для поднятия статуса.)

Внутреннее устройство


Самое интересное в Acid3 — это как раз внутренее устройство и детали процессов, приводящих к тем или иным циферкам и квадратикам итоговой картинки.

Чтобы понять, что же там внутри, самое время забраться в исходники теста – благо во всех современных браузерах есть средства разработки (и даже почти во всех встроенные).

Тест состоит из 5 основных частей:
  • исходная разметка страницы
  • заготовки стилей для тестирования и отрисовки итогового изображения (с некоторыми комментариями о тонкостях позиционирования и размеров прямоугольников)
  • дополнительные тестовые страницы (файлы), используемые в ряде тестов
  • собственно сами наборы тестов (JavaScript)
  • движок для тестирования (JavaScript)
Весь процесс тестирования происходит динамически и осуществляется средствами JavaScript и именно на этой части мы остановимся подробнее. (Из интересного относительно CSS – для картинок используется data-uri).

Движок тестирования

Код движка для тестирования включает:
  • несколько вспомогательных функций (fail, assert, assertEquals) для общей механики проверок
  • пару функций для работы с iframe и стилями
    • getTestDocument – создает тестовый документ на основании содержания iframe
    • selectorTest – для тестирования заданных css-селекторов в таком тестовом документе
  • функцию update, непосредственно производящую прогон тестов и обновление внешнего вида страницы в соответствии с прохождением тестов (подробнее ниже) и ведущую лог результатов
  • функцию report, выводящую лог результатов в отдельном окне
Оставляя за рамками данного обзора особенности формирования картинки с помощью CSS (в данном случае это не сильно принципиальный момент), давайте посмотрим на то, как работает функция update и как устроен набор тестов.

Набор тестов

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

Все тесты разделены на 6 наборов по 16 тестов:
  • Bucket 1: DOM Traversal, DOM Range, HTTP
  • Bucket 2: DOM2 Core and DOM2 Events
  • Bucket 3: DOM2 Views, DOM2 Style, CSS 3 селекторы и Media Queries
  • Bucket 4: Поведение HTML-таблиц и форм при манипуляциях из кода и через DOM2 HTML
  • Bucket 5: Тесты, созданные внешними участниками (SVG,HTML, SMIL, Unicode, …)
  • Bucket 6: ECMAScript

Плюс отдельные тесты с номерами 0, 97, 98 и 99, формально объединенные в набор 7.

Каждый тест в качестве признака успешности возвращает код того набора, к которому он принадлежит. Например, вот так выглядит тест 87:
function () {
   // test 87: Date tests -- years
   var d1 = new Date(Date.UTC(99.9, 6));
   assertEquals(d1.getUTCFullYear(), 1999, "Date.UTC() didn't do proper 1900 year offsetting");
   var d2 = new Date(98.9, 6);
   assertEquals(d2.getFullYear(), 1998, "new Date() didn't do proper 1900 year offsetting");
   return 6;
  }


* This source code was highlighted with Source Code Highlighter.


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

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

Любая из проверок может вывалиться с ошибкой, что будет отловлено во внешнем цикле (см. ниже).

Сами функции, описывающие тесты, объеденены в общий массив.

update()

Как сказано выше, функция update() занимается непосредственно запуском тестов, сбором результатов и формированием лога и итоговой картинки.

Технически, функция рекурсивна с задержкой по timeout: на каждый следующий тест запускается через 10 миллисекунд, максимум 500 попыток на тесты, требующие сетевого подключения (result == "retry").

Упрощенно схема тестирования выглядит так:
function update() {
  if (index < tests.length) {
   try {
    var result = tests[index]();
    if (result == "retry") {
     retry += 1;
     if (retry < 500) {
      setTimeout(update, delay);
      return;
     }
     fail("timeout -- could be a networking issue");
    } else if (result) {
     // обновление внешнего вида
     }
    } else {
     fail("no error message");
    }
   } catch (e) {
    // ошибка
   };
   retry = 0;
   index += 1;
   setTimeout(update, delay);
  } else {
  // итоги
  }
}


* This source code was highlighted with Source Code Highlighter.


При обновлении внешнего вида с учетом номера набора, к которому принадлежит тест, к тому или иному прямоугольнику, соответствующему набору тестов, добавляется символ “P” в названии класса. В зависимости от количества букв “P” применяется тот или иной CSS-класс:
<style type="text/css">
 /* colours for them */
.z, .zP, .zPP, .zPPP, .zPPPP, .zPPPPP { background: black; }
 .zPPPPPP, .zPPPPPPP, .zPPPPPPPP, .zPPPPPPPP, .zPPPPPPPPP,
 .zPPPPPPPPPP { background: grey; }
 .zPPPPPPPPPPP, .zPPPPPPPPPPPP, .zPPPPPPPPPPPPP,
 .zPPPPPPPPPPPPPP, .zPPPPPPPPPPPPPPP { background: silver; }
 #bucket1.zPPPPPPPPPPPPPPPP { background: red; }
 #bucket2.zPPPPPPPPPPPPPPPP { background: orange; }
 #bucket3.zPPPPPPPPPPPPPPPP { background: yellow; }
 #bucket4.zPPPPPPPPPPPPPPPP { background: lime; }
 #bucket5.zPPPPPPPPPPPPPPPP { background: blue; }
 #bucket6.zPPPPPPPPPPPPPPPP { background: purple; }
</style>


* This source code was highlighted with Source Code Highlighter.


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

Что тестирует Acid3?


Как сказано выше, Acid3 содержит 100 тестов, которые можно разделить на шесть групп:
  • Bucket 1: DOM Traversal, DOM Range, HTTP
    • DOM Level 2 Traversal (1-6)
      • NodeFilter и исключения
      • Удаление узлов при итерировании
      • Бесконечные итераторы
      • Игнорирование пробельных тестовых узлов при использовании итераторов
      • Игнорирование пробельных тестовых узлов при использовании tree walker
      • Выход за пределы дерева
    • DOM Level 2 Range (7-13)
      • Простые базовые тесты
      • Перемещение границ
      • Использование extractContents() в документе
      • Использование Range и атрибутных узлов
      • Использование Range и комментариев
      • Ranges при изменениях: вставка текстовых узлов
      • Ranges при изменениях: удаление
    • HTTP (14-16)
      • HTTP — Content-Type: image/png (проверка безопасности, внутри js-код)
      • HTTP — Content-Type: text/plain (проверка безопасности, внутри js-код)
      • Обработка <object> и статусов HTTP (если не вываливается исключение, то визуально проверяется корректность рендеринга)
  • Bucket 2: DOM2 Core и DOM2 Events
    • DOM Level 2 Core (17-29)
      • hasAttribute
      • nodeType (и также аккуратность парсинга)
      • Значения констант
      • null-байты в различных местах
      • Базовые вещи с namespace
      • createElement() для неправильных тегов
      • createElementNS() для неправильных тегов
      • Атрибуты-события
      • Наличие проверки namespace в createDocumentType и типа исключений
      • Манипуляции с деревом и доступностью элементов
      • Продолжение предыдущего теста
      • getElementById()
    • DOM Level 2 Events (30-32)
      • dispatchEvent()
      • event.stopPropagation() и захват событий
      • Всплытие событий через узлы документа
  • Bucket 3: DOM2 Views, DOM2 Style (33-48), CSS 3 selectors (33-40, 47) и Media Queries (46)
    • Базовые тесты – классы и атрибуты
    • :lang() и [|=]
    • :first-child
    • :last-child
    • :only-child
    • :empty
    • :nth-child, :nth-last-child
    • :first-of-type, :last-of-type, :only-of-type, :nth-of-type, :nth-last-of-type
    • :root, :not()
    • +, ~, >, и ' ' в динамических примерах
    • :enabled, :disabled, :checked и др.
    • Селекторы без пробелов перед "*"
    • cssFloat и атрибут style
    • Media Queries – различные комбинации
    • 'cursor' и CSS3-значения
    • :link и :visited
  • Bucket 4: Поведение HTML таблиц и форм при манипуляциями с помощью скриптов и DOM2 HTML
    • Tables (49-51)
      • Базовый доступ к таблице, create*, delete*, и *
      • Создание таблицы и проверка, что она соответствует ожиданиям
      • Проверка порядка и создания строк
    • Forms (52-59)
      • <form> и .elements
      • Динамичное изменение <input>
      • Изменение распарсенного <input>
      • Перемещение чекбоксов с проверкой сохранения состояния
      • Клонирование радиокнопок с проверкой сохранения состояния
      • HTMLSelectElement.add()
      • HTMLOptionElement.defaultSelected
      • Атрибуты <button>-элементов
    • Misc DOM 2 HTML (60-64)
      • className — "class" — attribute nodes (поддержка getAttributeNode)
      • className и class-атрибуты: сохранение пробелов
      • проверка, что DOM-атрибуты и content-атрибуты не совпадают
      • атрибуты <area>-элемента
      • еще тесты атрибутов
  • Bucket 5: Тесты из Acid3 Competition (SVG, HTML, SMIL, Unicode, ...)
    • SVG, Подготовка к последующим тестам (65) – динамическая подгрузка SVG и HTML файлов
    • Атрибуты (66-67)
      • localName для текстовых узлов
      • removedNamedItemNS на удаленных узлах
    • Unicode 5.0 UTF-16 (68) – суррогатные пары
    • Подготовка к последующим тестам (69) – проверка, что необходимые файлы подгружены
    • XML Encoding (70)
    • HTML parsing (71)
    • Динамическое изменение <style> (72)
    • Вложенные события (73)
    • SVG (74-79), SMIL (75-76)
      • getSVGDocument()
      • SMIL в SVG (две части)
      • Внешние SVG-шрифты
      • SVG textPath и getRotationOfChar()
      • большой тест <svg:font>
    • Удаление iframe и object
  • Bucket 6: ECMAScript (81-96)
    • Массивы с запятым в конце
    • Массивы с запятыми в середине
    • Методы для массивов (unshift и join)
    • Преобразование чисел в строки
    • Строки и строковые операции (substr с негативными значениями)
    • Даты – методы без параметров
    • Даты – года
    • ES3 section 7.6:3 (экранирование unicode-символов)
    • Регулярные выражения
    • Проверка, что свойства перечислимы по умолчанию
    • Внутренние свойства функций
    • Семантика FunctionExpression
    • Исключения
    • Типы выражений
    • encodeURI, encodeURIComponent и null-байты
  • Отдельной статьей идут еще четыре специальных теста (0, 97, 98, 99)
    • Special (0) – удаление сообщения "JS required" и <script> элемента из <body>
    • Data URI scheme (97)
    • XHTML 1.0 Strict (98)
    • Sanity (99)
Набор тестов и состав проверяемых спецификаций, конечно, впечатляют, но возвращаясь к цитатам в начале статьи, к этому составу есть две большие претензии:
  1. Это, откровенно говоря, далеко не все стандарты, которые в идеале должен поддерживать браузер. К примеру, одних модулей CSS3 – порядка 30 штук, а здесь “указаны” только два – CSS3 Selectors и CSS3 Media Queries.
  2. Наборы тестов по каждому из стандартов крайне далеки от того, чтобы показывать реальную картину поддержки того или иного стандарта. Есть только две вещи, которые подобные проверки фиксируют: баги в реализации и полное отсутствие поддержки конкретной тестируемой функциональности (но не всего стандарта).

    Современный подход: большие наборы тестов, разрабатываемые сообществом (производители браузеров, эксперты, веб-разработчики и т.п.), достаточно полно покрывающие конкретные спецификации. Например, набор тестов CSS 2.1 содержит тысячи тестов.
И одна не очень большая претензия — будущее отдельных тестируемых спецификаций (см. раздел “Почему Firefox 4 и IE9 не набирают 100 баллов"?”).

Итоговый вывод по содежанию: Acid3 тестирует не более того, что он тестирует – отдельные элементы отдельных стандартов небольшим количеством тестов. То есть, статистически ничего.

Интересные факты


Acid3 Competition

В процессе работы над тестами Ян Хиксон объявил конкурс на дополнительные тесты (16 штук), чтобы довести количество тестов до круглого числа (100). Среди требований было такое:
Тест должен проваливаться (выкидывать исключение) в свежем билде Firefox или Webkit (в идеале в обоих). (Opera и IE уже проваливают достаточное количество тестов и я не хочу добавлять еще тестов, которые проваливаются только в них. Конечно, если вы найдете что-то, что праваливается в Firefox или Webkit и Opera или IE, будет лучше.)


(К слову, Acid3 был выпущен примерно в то же время, когда Microsoft выпустила публичную бета-версию IE8, основной функционал которой был уже зафиксирован и не подлежал изменению независимо от результатов тестов, подобрых Acid3.)

Баги

Как пишет Ян Хиксон, уже после первичного анонсирования Acid3 (март 2008) отдельные тесты менялись в силу обнаруженных багов и был даже случай, когда тест пришлось менять в силу изменившейся спецификации. В какой-то момент один из вендоров (не будем показывать пальцем) заявил, что проходит полностью Acid3, но оказалось, что в тестах была ошибка :)

Последнее обновление набора тестов было произведено около года назад – в начале апреля 2010.

Acid 4 и уроки из Acid3

Спустя какое-то время после выпуска Acid3 появилась предварительная информация об Acid4. Хотя планам к настоящему моменту так и не было суждено сбыться, некоторые интересные моменты в виде уроков, извлеченных из Acid3, думаю, заслуживают внимания:
  • не включать минорные баги;
  • не запрашивать разработку специфических тестов, писать тесты самостоятельно, но запрашивать отзывы с ранних итераций (t=0): публично и у конкретных экспертов;
  • запрашивать пожелания относительно того, что именно тестировать;
  • не показывать сам тест на ранних стадий, чтобы избежать отсылок к нему в то время, как ведется обсуждение, что именно тестировать;
  • не включать измерение производительности как часть тестов (это можно делать отдельно, если все согласятся, что тест честный);
  • сделать хорошо выглядящую картинку;
  • спрашивать у разработчиков браузеров совета по времени анонсирования теста.

Почему Firefox 4 и IE9 не набирают 100 баллов?

Как известно, Firefox 4 и IE9 не набирают 100 баллов в Acid3 – и многие журналисты и люди, не следящие за всеми перепетиями развития событий, продолжают этому удивляться.

Комментарии Alexander Limi (GUI дизайнер в Mozilla) с отсылкой на комментарий Boris Zbarsky (Mozilla engineer):

“Оставшиеся три балла касаются SVG Fonts. Opera и Webkit реализовали небольшое подмножество SVG 1.1 Fonts, достаточное для прохождения Acid3. Мы не хотим внедрять в Gecko даже небольшое подмножество, пока не будем уверены, что это принесет пользу разработчикам или пользователям. При этом реализация полной спецификации – довольно сложная задача, т.к. SVG Fonts проектировались без учета интеграции с HTML.

В настоящий момент SVG WG решила, что SVG Fonts не будет в основной части SVG и переместится в отдельную спецификацию, которая потребует серьезной работы, если кто-то возьмется ее полностью реализовать.”

Предпочтение отдается WOFF.

Аналогичное предпочтение и нестремление в реализации SVG Fonts высказывает Dean Hachamovich (Microsoft) и добавляет про “недостающую” реализацию SMIL:
“Поддержка SMIL-анимаций в SVG в веб-сообществе далека от того, чтобы быть достаточно сильной. Лидер движения стандартизации SVG написал, что неподдержка SMIL в текущем статусе, возможно, наилучшая опция, т. к. SVG WG занимается координацией с CSS WG относительно внесения изменений в анимации и расширения фильтров.”


В вопросе анимаций предпочтение отдается JavaScript и CSS.

Почему Acid3 важен?


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

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

Навряд ли, кто-то из разработчиков браузеров возьмется серьезно рассматривать Acid3, как критерий качества своего продукта. Но вместе с тем, баги, проверка которых заложена во многие тесты Acid3, оказались исправленными вместе с другими улучшениями. В этом смысле Acid3 является неплохим маячком того, что разработчики движутся в правильном направлении (если только они не подгоняют браузер под прохождение конкретных тестов).

В конечном счете и на деле (маркетинговом) Acid3 сыграл и местами продолжает играть достаточно весомую роль. И когда маховик закрутился, навряд ли возможно его полностью игнорировать.

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

Маркетинг такой маркетинг :) Даже если это маркетинг веб-стандартов.
Tags:
Hubs:
+113
Comments31

Articles

Change theme settings