Тестирование с Сodeception для чайников: 3 вида тестов
Целью данной статьи я ставил показать людям, не знакомым с тестированием, как можно действительно быстро начать тестировать, собрав все в одном месте с минимумом воды и на русском языке. Пусть это будет весьма примитивно. Пусть не очень интересно людям, которые уже живут по TDD, SOLID и другим принципам. Но дочитав до конца, любой желающий сможет сделать свой первый уверенный шаг в мир тестирования.
Мы рассмотрим приемочные (Acceptance), функциональные (Functional) и юнит-тесты или модульные тесты (Unit-Tests).
Установка Composer & CodeceptionЕсли вас ставят в тупик фразы
Для начала работы нам нужен замечательный инструмент Composer. В большинстве проектов он уже будет установлен. Но установить его — также не является проблемой. Все варианты перечислены на его официальной странице: https://getcomposer.org/download/ Наиболее банальным и простым способом является прокрутить вниз страницы и просто скачать *.phar файл в корень вашего проекта.
Лучшие практики вам обязательно скажут, что так делать — плохо. Необходимо разместить его в /etc/bin, дать права на выполнение и переименовать в composer. Прислушайтесь к ним, когда дочитаете статью до конца.
Второй шаг в настройке Composer, а также очень частый ответ, что делать, когда Композер сломался: обновить/установить FXP-плагин. Он "живет" по адресу: https://packagist.org/packages/fxp/composer-asset-plugin И устанавливается часто командой: $ php composer.phar global require "fxp/composer-asset-plugin:
1.4.2" Обратите внимание, что версию надо вписывать ту, которая будет отображена на сайте в момент прочтения этой статьи.
Финальная настройка перед началом работы — установить себе Codeception, с помощью Composer: $ php composer.phar require "codeception/codeception:*"
После чего исполняемый файл Codeception доступен для нас в подкаталоге ./vendor/bin/codecept для Linux и ./vendor/bin/codecept.bat для Windows. Набирать это перед каждым запуском долго. Поэтому делаем сокращения: Для Linux: $ alias cept="./vendor/bin/codecept" Для Windows в корне проекта (откуда будем запускать тесты) создаем новый bat-файл: cept.bat
После чего команда cept, в консоли, должна вернуть help-страницу по Codeception. А если вам хочется запускать cept.bat из любого каталога — посмотрите в сторону директивы PATH.
И пару подсказок на эту тему: Удаление пакета из композера: $ php composer.phar remove codeception/codeception Если Вы столкнетесь с проблемой: "Fatal error: Allowed memory size of 12345678 bytes exhausted" . Composer тут же подскажет ссылку, на которой будет написан немного модифицированный вызов: $ php -d memory_limit=-1 composer.phar
Создание первого теста: приемочный или AcceptanceСейчас мы в шаге от своего первого теста. Проверим банально, что у нашего сайта открывается главная страница и страница About. Что они возвращают корректный код ответа "200" и содержат ключевые слова.
Собственно — это и есть суть приемочных тестов: проверить то, что доступно человеку, далекому от программирования: просмотр содержимого страницы, попытка залогиниться и т.д.
$ cept bootstrap — делаем разовую инициализацию, после первой установки $ cept generate:cept acceptance SmokeTest — создаем первый тестовый сценарий
Открываем tests/acceptance/SmokeTestCept.php и дописываем к имеющимся двум строчкам new AcceptanceTester и wantТo свои. На выходе у нас должно получится:
Как Вы понимаете: запускать рано. Вы получите сообщение о том, что тест не пройден. Т.к. он не совсем в курсе, у какого сайта надо открыть главную страницу. Правим секцию modules.config.PhpBrowser.url в файле tests/acceptance.suite.yml . Например у меня там получилось: url: http://rh.dev/
Также в коде теста, сразу глаза бросается дубляж. Его можно отрефакторить, добавив новый метод в класс tests/_support/AcceptanceTester.php . Либо отнаследовавшись от него — создать себе собственный и добавить метод туда. Но это уже другой разговор не про тесты.
Итак, жмем следующие команды:
$ cept build — после внесения правок в файлы конфигурации всегда необходима пересборка $ cept run acceptance — запускаем тест на выполнение
Вы должны получить сообщение: OK (1 test, 4 assertion)
Собственно — всё! Вы создали первый тест, который за Вас может проверить адекватность страниц по всему сайту. Что особенно полезно, когда этих страниц становится много, а шеф хочет с каждым разом накатывать все быстрее и быстрее. Не забывая раздавать нагоняи, что на сайте что-то сломалось.
В дальнейшем вы можете проверять также формы, аяксы, REST, JavaScript через Selenium и разные другие вещи.
Создание первого теста: функциональные или FunctionalФункциональные тесты немного сходны с приемочными. Но в отличие от последних — не требуется запускать веб-сервер: мы вызываем наш framework, с эмуляцией переменных запроса (get, post). Официальная документация рекомендует тестировать нестабильные части приложения с помощью функциональных тестов, а стабильные с помощью приемочных. Это обусловлено тем, что функциональные тесты не требуют использования веб сервера и порой, могут предложить более подробный отладочный вывод.
Первое, с чего нам надо начать: правим файл конфигурации в tests/functional.suite.yml , указав в нем модуль своего фреймворка, вместо фразы "# add a framework module here". А все тонкости настройки — придется прочесть в официальной документации.
Я покажу на примере не шаблонного Yii2 (если у вас установлен шаблон Basic или Advanced, то вверху этой страницы есть описание и такого варианта): http://codeception.com/for/yii#Manual-Setup--Configuration
- В файле tests/_bootstrap.php добавляем константу: defined('YII_ENV') or define('YII_ENV', 'test'); . Если файла нет — создаем и добавляем в корневой codeception.yml settings.bootstrap:_bootstrap.php. Такие файлы необходимо будет вкладывать во все папки с тестами. Если забудете — Codeception вам об этом напомнит.
- В папке config yii-приложения, рядом с main.php кладем test.php , который заполняем из мануала
- Экспертным путем обнаружил, что модуль не видит мои vendors и испытывает проблемы с пониманием, где он находится в файловой системе. Поэтому дополнил test.php еще парой строк:
$ cept generate:cept functional myFirstFunctional — создаем первый тестовый сценарий Созданный файл tests/functional/myFirstFunctionalCept.php заполняем сходно с прошлым файлом теста. С одним лишь отличием в первой строке: $I = new FunctionalTester($scenario);
И дальше по пройденному выше материалу:
$ cept build — после внесения правок в файлы конфигурации всегда необходима пересборка $ cept run functional — запускаем тест на выполнение
Вы должны получить сообщение: OK (1 test, 4 assertion)
Создание первого теста: юнит-тесты или Unit-TetsЕсли предыдущие тесты смотрели на ваше приложение в целом: от точки входа, до точки выхода. То модульные тесты — помогают разложить все по полочкам, дав возможность тестировать каждый кирпичик, ака модуль, приложения.
Что тестировать и на сколько углубленно — на хабре довольно много статей. В каких-то ситуациях вам скажут, что обязательно тестировать полностью все методы и классы. В иных — разговор будет немного иным. Например, мне бросилась в глаза эта статья: Трагедия стопроцентного покрытия кода post-link
У себя я протестирую класс, который работает по патерну ActiveRecord: загружу данные из массива и запущу валидацию. Если впоследствии добавится какое-либо обязательное поле и, как везде водится, про это все забудут: тест сразу выскажет свое возражение.
Вторым этапом я буду тестировать один из своих хелперов. Идея больше показательная, чем полезная.
Начало уже привычно:
tests/unit.suite.yml — правим согласно своего фреймворка(если вы его используете). $ cept build — после внесения правок в файлы конфигурации всегда необходима пересборка. $ cept generate:test unit SmokeUnit — создаем пустышку, для будущего теста.
$ cept run unit — запускаем тест на выполнение. Видим OK (2 tests, 5 assertions)
Немного поясню: $this->assertTrue($clan->validate()); — как следует из названия: ожидает, что в переменной или результате метода содержится логическое TRUE. Противовес: $this->assertFalse() $this->assertEquals(1, count($myArray)); — ожидает равенство двух параметров
Т.е. парой проверок можно сделать какие-то базовые вещи. Подстелить себе соломинку, так сказать. А на досуге почитать про остальные выражения проверок: http://www.phpunit.de/manual/3.4/en/api.html#api.assert
В заключениеКонечно в этой статье все упрощено и написано поверхностно. Но, сами понимаете, что данная тема — это не одна статья. Уже не говоря про те самые Best-Practices, которые или набиваются своими шишками, или ты успеешь про них прочесть заранее.
Поэтому давайте попробуем начать в данном формате и посмотреть, что из этого выйдет.
Если искомая аудитория будет найдена — я обязательно постараюсь рассказать об опущенных мной Mock-обьектах, Fixtures, тестовых БД с дампами и еще много интересного, что используется в этом направлении.