В Magento 2 используется 6 видов тестов для улучшения процесса разработки, поддержки и QA, охватывающих каждый аспект разработки сайта (frontend, backend и user experience):
- Static Tests
- Javascript Tests
- Unit Tests
- Integration Tests
- Web-API Functional Tests
- Functional Tests
В этой статье мы рассмотрим, что из себя представляет каждый вид тестирования, какие направления разработки затрагивает и как добавить собственный модуль к тестированию.
Static Tests
Статические тесты предназначены анализировать сам код без его выполнения.
К таким тестам относятся:
- проверки синтаксиса PHP, JS, Less, XSS,
- Integrity тесты: целостность модуля, его возможность корректно быть подцепленным системой
- Legacy тесты: полезны при портировании модуля из Magento 1 в Magento 2, отслеживает использование старых методов, например Mage::getSingelton, Mage::getModel, подсказывает аналоги.
Расположение:
dev/tests/static
Настройки:
Особых настроек не требует.
Файлы конфигураций: dev/tests/static/phpunit.xml.dist
Запуск:
php bin/magento dev:tests:run static Запускает тесты по группам заданным в dev/tests/static/phpunit.xml.dist
php bin/magento dev:tests:run static-all Запускает все тесты в dev/tests/static/testsuite/Magento/Test одним пакетом
Добавление своего модуля для тестирования:
Сильно зависит от типа теста.
Данный тест является набором инструментов, у некоторых из них есть black list и white list папок и файлов для проверки. Настройки в dev/tests/static/phpunit.xml.dist подцепляют лишь сами инструменты.
Примечания:
Некоторые модули данного тестирования (например, phpcpd - PHP Copy-Paste Detector) ведут отдельные логи по результатам запуска тестов. Они находятся в dev/tests/static/report/
Javascript Tests
JS Unit тесты на своем фреймворке (доступны jasmine и jsTestDriver).
Официальная документация: (источник 1)
Расположение:
dev/tests/js
Настройки:
Требуют настроек:
- dev/tests/js/JsTestDriver/jsTestDriver.php.dist
- dev/tests/js/JsTestDriver/jsTestDriverOrder.php
Требует внешние иструменты
- java библиотека jsTestDriver: https://code.google.com/archive/p/js-test-driver/
- На Linux требует lsof и xvfb утиллиты. На Ubuntu-like системах lsof установлена по-умолчанию. xvfb ставится через apt-get install xvfb.
Запуск:
Запускаются из своей папки: php run_js_tests.php
Примечание:
Если браузер (Browser) не задан в настройках, ищет по-умолчанию в:
- C:\Program Files (x86)\Mozilla Firefox\firefox.exe Firefox для Windows систем. Может не работать, если диск/место установки отличаются (32х система, например)
- "which firefox" Firefox для Linux систем. Скорее всего, будет работать всегда, если firefox установлен.
У меня на системе генирирует shell скрипт с неверным путем к lsof утиллите (путь жестко задан в php скрипте-генераторе). Поправить только вручную в run_js_tests.php скрипте.
Браузер должет быть закрыт перед запуском.
Результаты выводятся в dev/tests/js/JsTestDriver/test-output
Unit Tests
Юнит тесты предназначены для тестирования одного "юнита", т.е. одного объекта. В рамках PHP - это, как правило, один файл или объект.
Юнит тесты должны быть абстрагированы от любой внешней логики. Все необходимые дополнительные объекты заменяются на Mock объекты, которые имитируют логику и данные существующих или еще не созданных классов. Это позволяет протестировать вашу логику независимо от состояния и возможностей системы.
Как правило, класс Unit теста находится в том же пространстве имен (namespace), что и тестируемый класс. Для integration тестов логика такая же, поэтому рекомендуется в суффиксе unit тест класса добавлять Unit, чтобы избежать дубликата класса с integration тестами.
Официальная документация: (источник 2)
Расположение:
dev/tests/unit
Настройки:
Особых настроек не требует.
Настройки находятся dev/tests/unit/phpunit.xml.dist
Необходимо переименовать файл в phpunit.xml, и там уже вносить изменения. Т.к. оригинальный phpunit.xml.dist может быть заменен обновлением.
Запуск:
php bin/magento dev:tests:run unit
Добавление своего модуля для тестирования:
По умолчанию, конфигурация юнит тестов задана таким образом, что проверяет следующие директории:
- app/code/*/*/Test/Unit
- dev/tools/*/*/Test/Unit
- dev/tools/*/*/*/Test/Unit
- lib/internal/*/*/Test/Unit
- lib/internal/*/*/*/Test/Unit
- setup/src/*/*/Test/Unit
- vendor/*/module-*/Test/Unit
- vendor/*/framework/Test/Unit
- vendor/*/framework/*/Test/Unit
И ищет в них файлы с суффиксом Test.php.
Если в своем модуле сделать следующий файл:
app/code/Astrio/Core/Test/Unit/Helper/DataTest.php
Он автоматически подцепится при следующем запуске Unit тестов
Примечание:
При добавлении своего testsuite в настройках, есть возможность запустить его отдельно. Консольная команда dev:tests:run такой функционал не поддерживает, поэтому запускать нужно вручную.
Рабочая директория должна быть dev/tests/unit. Из неё выполнять команду php ../../../vendor/phpunit/phpunit/phpunit --testsuite "Astrio Unit Tests". Где "Astrio Unit Tests" - название тест suite'а.
В Magento 2 всего 1 testsuite. Чтобы свой добавить, нужно обернуть существующий в тег <testsuites> и добавить на том же уровне, что и существующий <testsuite> свой
<testsuite name="Astrio Unit Tests"> <directory suffix="Test.php">../../../app/code/Astrio/*/Test/Unit</directory> <directory suffix="Test.php">vendor/astrio/module-*/Test/Unit</directory> </testsuite>
Подобная настройка позволит запустить тесты в директориях app/code/Astrio/* и vendor/astrio/module-* по пути Test/Unit все php файлы с суффиксом Test.php.
Например, app/code/Astrio/Core/Test/Unit/Helper/DataTest.php
Integration Tests
Служат для проверки функционала и логики так или иначе связанных с магентой. У вас есть доступ ко всем возможностям di, ко всем конфигам и базе данных.
Использует отдельную базу.
При запуске создается отдельный "sandbox" magento 2 с различными временными файлами и кешем. Находится он по пути dev/tests/integration/tmp/sandbox-*{{HASH}} - где {{HASH}} рандомно сгенирированный хеш.
Если константа TESTS_CLEANUP задана в enabled (по-умолчанию так), после каждого запуска данная папка будет очищаться автоматически, и при следующем запуске создастся новый sandbox.
Если константа TESTS_CLEANUP задана в disabled, тесты будут проводиться быстрее, но необходимо помнить, что кеш в этой папке нужно очищать вручную в этом случае.
Официальная документация: (источник 3)
Расположение:
dev/tests/integration
Настройки:
Требует дополнительных настроек.
Настройки базы данных:
- dev/tests/integration/etc/install-config-mysql.php.dist или dev/tests/integration/etc/install-config-mysql.travis.php.dist
Для изменения настроек необходимо скопировать install-config-mysql.php.dist в install-config-mysql.php и внести необходимые данные. Файл install-config-mysql.php.dist изменять нельзя, т.к. он может быть переписан при обновлении.
Настройки phpunit dev/tests/integration/phpunit.xml.dist. Так же необходимо скопировать в phpunit.xml для внесения изменений
Запуск:
php bin/magento dev:tests:run integration
Добавление своего модуля для тестирования:
По умолчанию проводит запуск только своих тестов и не подцепляет никакие сторонние.
Чтобы добавить все сторонние модули, к примеру, в dev/tests/integration/phpunit.xml нужно добавить следующую запись
<testsuite name="Third Party Integration Tests"> <directory>../../../app/code/*/*/Test/Integration</directory> <directory>../../../vendor/*/module-*/Test/Integration</directory> <exclude>../../../app/code/Magento</exclude> <exclude>../../../vendor/magento</exclude> </testsuite>
По аналогии можно добавить только определенного vendor'а или даже модуль.
При добавлении своего testsuite в настройках, есть возможность запустить его отдельно. Консольная команда dev:tests:run такой функционал не поддерживает, поэтому запускать нужно вручную. Рабочая директория должна быть dev/tests/integration. Из неё выполнять команду php ../../../vendor/phpunit/phpunit/phpunit --testsuite "Astrio Integration Tests" Где "Astrio Integration Tests" - название test suite'а.
Web API Functional Tests
Подтип integration тестов. Служат для проверки работы api. Поддерживают rest и soap.
Официальная документация: (источник 4)
Расположение:
Находятся в dev/tests/api-functional
Настройка:
Требуют доп настроек:
- dev/tests/api-functional/phpunit.xml.dist для backend конфигурации Magento 2, выбора протокола
- dev/tests/api-functional/config/install-config-mysql.php.dist для настроек базы
- dev/tests/api-functional/config/config-global.php.dist дополнительный конфиг глобальных переменных
Запуск:
Через dev:tests:run запустить невозможно. Нужно запускать вручную из папки dev/tests/api-functional
> php ../../../vendor/phpunit/phpunit/phpunit
Примечания:
То, что возможности запуска этих тестов нет через консольную команду, а также некоторые расхождения в настройках (путь до code/Magento в whitelist в phpunit.xml.dist имеет 2 уровня вложенности вместо 3 реальных, т.е. это настройка в принципе не корректна, даже несмотря на то, что app/code/Magento в принципе уже нет - всё лежит в vendor) подразумевает, что данные тесты, по крайней мере, на данный момент очень сильно устарели.
Functional Tests
Selenium тесты для проверки функционала сайта со стороны конечного пользователя. Magento 2 рассматривается как черный ящик со стороны драйвера функциональных тестов.
Есть свой гитхаб (источник 5)
Есть детальная инструкция с необходимыми настройками среды (источник 6)
Расположение:
dev/tests/functional
Установка:
Требует своей установки из dev/tests/functional: composer install
Соответственно, обновляться они тоже могут отдельно, как composer'ом, так и через github.
Настройки:
Требует доп настроек:
- dev/tests/functional/etc/config.xml.dist настройки selenium, доступов к базе данных.
- dev/tests/functional/phpunit.xml.dist настройки phpunit и различные backend настройки окружения
- dev/tests/functional/credentials.xml.dist настройки доступов для различных сервисов (shipping, payment методов и т.д.).
Также требует дополнительных настроек в конфигурации Magento 2: http://devdocs.magento.com/guides/v2.0/mtf/mtf_quickstart/mtf_quickstart_magento.html
Дополнительно к этому советую включить shared админ сессию. Без этого часто выкидывает из сессии на панели администратора в процессе тестирования
Внешние инструменты
Требует внешние инструменты, если тесты запускаются на локальной машине:
- java библиотека Selenium standalone server. http://www.seleniumhq.org/download/
- webdriver браузера, под которым будет проводиться тест.
Запуск:
Запускаются из своей папки.
Для компиляции тестов перед первым запуском / после внесения изменений: php utils/generate.php
Selenium сервер и webdriver должны быть запущены и доступны по портам, указанным в файлах конфигурации.
Запуск тестирования:
- php vendor/bin/phpunit все тесты
- php vendor/bin/phpunit --filter CreateCategoryEntityTest определенный тест
Примечания:
Как вариант, есть альтернативный facebook webdriver. На данный момент работает хуже драйвера по-умолчанию и заваливает почти все тесты.
Есть возможность подцепить к функциональным тестам различные сервисы тестирования, например Browserstack'а настолько, насколько их поддерживает используемая версия phpunit. Позволяет более гибко подбирать версию и тип браузера.
Заключение
Покрытие тестами осуществлялось с самого начала разработки Magento 2. Используя встроенные возможности Magento 2 Framework можно значительно улучшить качество, минимизировать возможность возникновения ошибок в собственном коде, обнаруживать конфликты с Magento 2 и сторонними модулями на раннем этапе разработки, подготовить существующий модуль Magento 1 к миграции на Magento 2, а также сделать его более устойчивым к последующим обновлениям.
В следующей части мы рассмотрим на практическом примере основные отличия двух похожих видов тестирования, которые позволяют тестировать иногда одну и ту же логику с разных сторон: Unit и Integration тесты.
Источники
1. JavaScript testing with JsTestDriver
2. Running Unit Tests
3. Running Integration Tests
4. Web API functional testing
5. Magento 2 MTF Github
6. Magento 2 MTF