Тесты — это хорошо, а когда есть готовая платформа для тестирования с интерфейсом и корпоратичный чеклист, каждый пункт которого содержит до двух литров крови программиста или менеджера, то почему бы не попробовать сделать свои автоматические тесты качества?
[spoiler]
Сначала нам необходимо описать свои тесты и их разделы. Для этого вешаем обработчик на событие main onCheckListGet. Событие вызывается в конструкторе CCheckList с арументом $arCheckList следующего вида:
Нетрудно заметить, что CATEGORIES содержит список разделов чеклиста, которые могут быть вложенными, а POINTS - сами тестпоинты.
Ключ массива CATEGORIES — айди раздела, значение — массив параметров:
Ключом элементов POINTS является символьный идентификатор теста, а значение представляет собой массив следующих параметров:
Обработчик события может возвращать как изменённый $arCheckList, так и новый массив с разделами и тестами - если категория/тест с неким ID уже существует, то он не заменится, т.е. «подкорректировать» системные тесты не получится:-).
Описание тестов сделали - отлично. Теперь необходимо объявить метод для автотеста. Для альфа-версии логика теста будет тривиальна:
По результатам проверки мы должны вернуть массив. Автотест может быть одно- или многошаговым. Если тест многошаговый и текущая итерация не является конечной, необходимо вернуть массив следующего вида:
PERCENT служит лишь для визуализации прогресса на странице и никуда не сохраняется для последующего использования. Промежуточные данные для идентификации прогресса шага надо сохранять самим - в сессию, временный файл, базу (в зависимости от объёма данных и прочих условий).
Если же тест закончен, сообщаем статус массивом, содержащим следующие ключи:
Всё, тест готов. Теперь можно посмотреть в админке, что мы натворили. Наши тесты в мониторе качества:

Справочная информация о тесте:

Тест провален:

Детальная информация о причинах провала:

А теперь — пройден:

И, напоследок, код обработчика и тесты целиком:
[spoiler]
Сначала нам необходимо описать свои тесты и их разделы. Для этого вешаем обработчик на событие main onCheckListGet. Событие вызывается в конструкторе CCheckList с арументом $arCheckList следующего вида:
array(2) { ["CATEGORIES"]=> array(10) { ["QDESIGN"]=> array(0) { } ["DESIGN"]=> array(1) { ["PARENT"]=> string(7) "QDESIGN" } ["MODEL"]=> array(1) { ["PARENT"]=> string(7) "QDESIGN" } ["STANDART"]=> array(1) { ["PARENT"]=> string(7) "QDESIGN" } } ["POINTS"]=> array(65) { ["QD0010"]=> array(2) { ["PARENT"]=> string(6) "DESIGN" ["REQUIRE"]=> string(1) "Y" } ["QD0020"]=> array(5) { ["REQUIRE"]=> string(1) "Y" ["PARENT"]=> string(6) "DESIGN" ["AUTO"]=> string(1) "Y" ["CLASS_NAME"]=> string(10) "CAutoCheck" ["METHOD_NAME"]=> string(14) "CheckTemplates" } ) |
Нетрудно заметить, что CATEGORIES содержит список разделов чеклиста, которые могут быть вложенными, а POINTS - сами тестпоинты.
Ключ массива CATEGORIES — айди раздела, значение — массив параметров:
- NAME - наименование раздела;
- LINKS - не понял, для чего это, хотя глубоко и не копал. На будущее, видимо
$checkList['CATEGORIES']['ITC_QC'] = array( 'NAME' => 'Корпоративный тест качества ITConstruct', 'LINKS' => '' ); |
Ключом элементов POINTS является символьный идентификатор теста, а значение представляет собой массив следующих параметров:
- NAME - наименование теста;
- DESC - краткое описание теста (вкладка «Описание», блок «Описание»);
- HOWTO - длинный текст о том, что будет проверяться (вкладка «Описание», блок «Как тестировать»)
- LINKS - аналогично разделам;
- PARENT - ID раздела, обязательное;
- REQUIRE - флаг обязательности теста ( "Y"/"N" );
- AUTO - "Y", если является автотестом;
- CLASS_NAME - имя класса теста (для автотеста);
- METHOD_NAME - имя метода теста (для автотеста);
- FILE_PATH - подключение файла теста, если оный вынесен в отдельный скрипт (для автотеста). Путь - относительно DOCUMENT_ROOT;
- PARAMS - массив дополнительных параметров, передаваемых первым аргументом при вызове метода автотеста
$checkList['POINTS']['ITC_QC_FAVICON'] = array( 'PARENT' => 'ITC_QC', 'REQUIRE' => 'Y', 'AUTO' => 'Y', 'CLASS_NAME' => __CLASS__, 'METHOD_NAME' => 'checkFavicon', 'NAME' => 'Наличие favicon', 'DESC' => 'Проверка наличия favicon - иконки сайта, отображаемой в заголовке вкладки и поисковых системах', 'HOWTO' => 'Производится проверка главной страницы сайта на наличие соответствующего мета-тэга. Если тэг объявлен - проверяется наличие иконки по указанному урлу. Если не указан - наличие favicon.ico в корне сайта', 'LINKS' => 'links' ); |
Обработчик события может возвращать как изменённый $arCheckList, так и новый массив с разделами и тестами - если категория/тест с неким ID уже существует, то он не заменится, т.е. «подкорректировать» системные тесты не получится:-).
Описание тестов сделали - отлично. Теперь необходимо объявить метод для автотеста. Для альфа-версии логика теста будет тривиальна:
$check = file_exists($_SERVER['DOCUMENT_ROOT'] . '/favicon.ico') |
По результатам проверки мы должны вернуть массив. Автотест может быть одно- или многошаговым. Если тест многошаговый и текущая итерация не является конечной, необходимо вернуть массив следующего вида:
$arResult = array( 'IN_PROGRESS' => 'Y', 'PERCENT' => '42', ); |
PERCENT служит лишь для визуализации прогресса на странице и никуда не сохраняется для последующего использования. Промежуточные данные для идентификации прогресса шага надо сохранять самим - в сессию, временный файл, базу (в зависимости от объёма данных и прочих условий).
Если же тест закончен, сообщаем статус массивом, содержащим следующие ключи:
- STATUS - результат теста. true, если успешно, нечто иное, если тест провалился. Только в коде почему-то проверяется так: «if ($result['STATUS'] == "true") » =)
- MESSAGE - разъяснения результата:
- PREVIEW - краткий текст результата
- DETAIL - расширенное объяснение, открываемое в попапе (см. скриншоты ниже)
- PREVIEW - краткий текст результата
static public function checkFavicon($arParams) { $arResult = array('STATUS' => 'F'); $check = file_exists($_SERVER['DOCUMENT_ROOT'] . '/favicon.ico'); if ($check === true) { $arResult = array( 'STATUS' => true, 'MESSAGE' => array( 'PREVIEW' => 'Favicon найдена - ' . '/favicon.ico', ), ); } else { $arResult = array( 'STATUS' => false, 'MESSAGE' => array( 'PREVIEW' => 'Favicon не найдена', 'DETAIL' => 'Тест очень старался, но так и не смог найти фавыконку. Ну и чёрт с ней', ), ); } return $arResult; } |
Всё, тест готов. Теперь можно посмотреть в админке, что мы натворили. Наши тесты в мониторе качества:

Справочная информация о тесте:

Тест провален:

Детальная информация о причинах провала:

А теперь — пройден:

И, напоследок, код обработчика и тесты целиком:
AddEventHandler('main', 'OnCheckListGet', array('CItcCheckListTests', 'onCheckListGet')); class CItcCheckListTests { static public function onCheckListGet($arCheckList) { $checkList = array('CATEGORIES' => array(), 'POINTS' => array()); $checkList['CATEGORIES']['ITC_QC'] = array( 'NAME' => 'Корпоративный тест качества ITConstruct', 'LINKS' => '' ); $checkList['POINTS']['ITC_QC_FAVICON'] = array( 'PARENT' => 'ITC_QC', 'REQUIRE' => 'Y', 'AUTO' => 'Y', 'CLASS_NAME' => __CLASS__, 'METHOD_NAME' => 'checkFavicon', 'NAME' => 'Наличие favicon', 'DESC' => 'Проверка наличия favicon - иконки сайта, отображаемой в заголовке вкладки и поисковых системах', 'HOWTO' => 'Производится проверка главной страницы сайта на наличие соответствующего мета-тэга. Если тэг объявлен - проверяется наличие иконки по указанному урлу. Если не указан - наличие favicon.ico в корне сайта', 'LINKS' => 'links' ); $checkList['POINTS']['ITC_QC_DENY_DEV'] = array( 'PARENT' => 'ITC_QC', 'REQUIRE' => 'N', 'AUTO' => 'N', 'NAME' => 'Закрытие доступа извне к dev-серверу', 'DESC' => 'Согласовать с менеджером закрытие доступа ко внутреннему серверу разработок из внешнего мира', 'HOWTO' => 'Попинговать с телефона после апдейта днса', ); return $checkList; } static public function checkFavicon($arParams) { $arResult = array('STATUS' => 'F'); $check = file_exists($_SERVER['DOCUMENT_ROOT'] . '/favicon.ico'); if ($check === true) { $arResult = array( 'STATUS' => true, 'MESSAGE' => array( 'PREVIEW' => 'Favicon найдена - ' . '/favicon.ico', ), ); } else { $arResult = array( 'STATUS' => false, 'MESSAGE' => array( 'PREVIEW' => 'Favicon не найдена', 'DETAIL' => 'Тест очень старался, но так и не смог найти фавыконку. Ну и чёрт с ней', ), ); } return $arResult; } } |