Тестирование с PHPUnit и Codeception
Самая объёмная тема среди предложенных завершена. Выкладываю исправленную и дополненную запись вебинара-скринкаста о тестировании c PHPUnit и Codeception. Добавлены и доработаны примеры кода, пункты про аннотации, фикстуры, анализ покрытия, Faker, про установку всего через composer и другие нюансы:
Открыть на YouTube
Коды примеров
Код проекта с тестами
Статья про запуск в проекте
Статья про применение моков и TDD
Ещё в тему доклад по обновлённым тестам в Yii2:
Структура вебинара-скринкаста (кликабельно):
Кто ещё не подписался на остальные вебинары, тот сам себе Буратино:
И задавайте вопросы в комментариях. Заранее спасибо и до встречи в эфире!

kenОгромное спасибо за проделанный труд! )
ДаниилОгромная работа!!! Смотрю пока оригинал, очень ценная информация. Спасибо большое! Задонатил.
kenСкажите в чем делали mindmap о тестировании. Спасибо
Дмитрий ЕлисеевВ XMind.
Web design Dubai – betterweb.aeСпасибо огромное, все руки не доходили до тестирования :)
Ramil Z.Спасибо за видео. Давно хотел изучить вопрос тестирования.
Написал в консоли:
composer global require "phpunit/phpunit:~4.8"
Но в итоге почему-то устанавливается: PHPUnit 3.7.21 by Sebastian Bergmann.
В чем может быть проблема?
Дмитрий ЕлисеевВозможно, что ставили что-то в global раньше.
Ramil Z.Ставил только composer global require "fxp/composer-asset-plugin:~1.0.3"
EvgeniiЭто phpunit вместе с xampp (или другим сервером локальным) установлен из pear
Сергей СероедОчень полезная информация, собранная мастером и занесена в самое ядро мозга.
Вдохновлен и впечатлен.
Спасибо!
ArtemДобрый день.
Такая проблема возникает:
Установил глобально Specify и Verify, сейчас эти компоненты лежат в папке vendor глубоко на диске "С", сайт же у меня развернут на другом диске, при попытке запустить тест "codecept run unit SomeTest" в консоль вываливается ошибка: "Call to undefined function expect()". Я добавил в Include Path в шторме путь к vendor на диске C, IDE начала подсвечивать пути к подключаемым файлам, шторм распознает путь "\Codeception\Specify" но вылетает ошибка при выполнении.
Потому вопрос: я должен эти компоненты устанавливать в папку vendor в которой находятся компоненты сайта? То есть, чтобы использовать Specify я должен еще установить 10МБ зависимостей?
Спасибо!
Дмитрий ЕлисеевНу если не получится разобраться, то можно установить всё себе в require-dev. А на продакшене устанавливайте composer install --no-dev, чтобы их туда не подтягивать.
ArtemСпасибо за подсказку Установил компоненты в секцию require-dev. Теперь все работает.
Мастер Ремонт – master-remont.kharkov.uaСпасибо Дмитрий. Вы действительно профи.
Хотелось бы спросить не по теме. Будет ли обзор или статья про кэширование в Yii2?
Программист – mobiappsystems.ruОтличный вебинар, вы только разбивайте следующий раз на логические части, а то 6 часов через чур
ЕвгенийОгромное спасибо за те знания, которыми Вы делитесь, Дмитрий. Это бесценно.
У меня вопрос: я пробовал делать тест модели с поведением Timestamp и модель не заполнялась. Т.е. поведения не работают в тестах?
И еще интересно - как добиться в консоли такого же вывода codeception как у Вас? У меня наполовину из такого: ←[1mUnit Tests (1) ←[22m---. Пробовал другие моноширинные шрифты - безуспешно. Кодировка проекта UTF-8.
Дмитрий ЕлисеевПоведение работает и в тестах по $model->save().
А лишние символы - это спецсимволы указания цвета. Для отключения вписывайте run --no-colors.
ЕвгенийНо хотелось бы видеть в цвете! У меня Win7, PphStorm9. Как это сделать? В консоли были сообщения про установку значений always, never, auto ( Argument #3 (No Value) of PHPUnit_TextUI_ResultPrinter::__construct() must be a value from "never", "auto" or "always"). Если в codeception.yml в setting/colors выставить одно из этих значений, то появляются эти спецсимволы, а если выставить true или false то выходит ошибка. Можно как-то сделать это в цвете?
ЕвгенийЗабыл добавить, что с --no-colors выходит ошибка: Argument #3 (No Value) of PHPUnit_TextUI_ResultPrinter::__construct() must be a value from "never", "auto" or "always"
Дмитрий ЕлисеевЭто для Codeception:
А так это просто в PHPStorm отбычная консоль цветная, а тестовая - чёрно-белая. Я на Windows раньше ставил эмулятор линуксового терминала Cygwin, и он как раз цветным был.
Arthur MrДмитрий, спасибо большое за видео!
По поводу цветной консоли в шторме можно подробнее? У меня никак не хочет отображать цвета. В настройках есть цвета (в примере), а в самой консоли весь вывод одного цвета... не очень читабельно. Win 8 + PhpStorm 10.
Поставил ConEmu, там все ок. Пробовал заменить консоль шторма на ConEmu, но оно открывается отдельно, не очень удобно. Хотелось бы именно встроенную в шторм консоль сделать нормальной на винде.
И что Вы имели в виду под "обычная консоль" и "тестовая консоль"?
Дмитрий ЕлисеевОбычная - которая во вкладке "Terminal" и в которой мы команды пишем, тестовая - в которой результаты тестов выводятся при запуске кнопкой "Run".
Arthur MrУ меня и в той и в другой весь вывод одним цветом :(
Дмитрий ЕлисеевWindows уже три года не пользуюсь. Так что запускайте в своей цветной ConEmu или терпите так :)
андрейда спасибо большое, а то думал вы общественную деятельность забросили. буду знакомится на выходных.
андрейа следующий вебинар не хотите посвятить теме, правильного написания кода для высоких нагрузок, что то типа лучшие практики корифеев на yii2 ?
Дмитрий ЕлисеевЗа эту тему не так много было голосов. А так это общие принципы, касаемые любого языка в общем и PHP с Yii2 в частности.
Мастер Ремонт – master-remont.kharkov.uaА планируется ли еще какой-либо вебинар и на какую тему?
Дмитрий ЕлисеевДа, планирую.
maxycВопрос один. Если вебинар посвящен тестам ЗАЧЕМ обьяснять как работать с Yii? Как создавать приложение, как работать с моделями. Вам не кажется это выходит за рамки?
Дмитрий ЕлисеевОткрою Вам страшную тайну: там есть перемотка клавишами влево-вправо.
maxycЯ это понимаю, но зачем рассказывать то, что не относится к теме?
ИгрА вот мне нужно, чтобы вот так вот разжевывали. А Вы можете перемотать или поставить ускоренное воспроизведение.
maxycА видели структуру тестов yii2/app-advanced? я пока досмотрел до 1:24 и не знаю занимались ли вы этим вопросом в видео (7 часов таки почти). Но полез я туда и понял, что надолго там засяду, прежде чем смогу начать полноценно работать с тестами в проекте.
Дмитрий ЕлисеевВидел. Там разложено по подпапкам common, backend и frontend. В видео об этом нету.
АлександрСпасибо за урок. Не могли бы Вы сделать текстовую версию данного урока? Т.к. смотреть все 6 часов не всегда у всех есть возможность. Да и текст на телефоне можно прочитать. Заранее спасибо.
Дмитрий ЕлисеевЕсли есть желание, то можете под диктовку транскрибировать из речи в текст. Мы Вам дружно скажем спасибо :)
Если слово в слово и без исходного кода, то здесь выйдет примерно 100 вордовских страниц. Потом можно будет расставить листинги из репозитория. Думаю, что с вычиткой и речевыми правками успеете сделать всего за 70 часов.
Alex – betterweb.aeМожно поменьше воды, побольше дела.
Дмитрий ЕлисеевМожно. Разрешаю.
СергейОтличный материал, Дмитрий, спасибо большое.
ЕвгенийЗдравствуйте. Судя по отладке кода FixtureHelper при использовании в acceptance тестах не получится задавать различные фикстуры для различных cept. Например 2 фикстуры для LoginCept, и 5 фикстур для UserCept. Как решить эту проблему на ваш взгляд?
Дмитрий ЕлисеевДа, менять не получится. И между тестами они не перезагружаются. Просто добавляем все 7 пользователей в общую фикстуру и прогоняем разные тесты по ним.
Евгенийспасибо!
xsaweвидео на 3:51:00 о статических переменных - статические переменные не перезаписываются при создании класса. Не вводите в заблуждение незнающих.
<?php class Foo { public static $var; } $foo1 = new Foo; var_dump($foo1::$var); $foo1::$var = 'newVar'; var_dump($foo1::$var); $foo2 = new Foo; var_dump($foo2::$var);; var_dump(Foo::$var);;
Дмитрий ЕлисеевВсе методы в этих объектах будут это поле менять, как статическое Yii::$app перезаписывается при создании new Application. Там перезапись производится именно в конструкторе Application.
xsaweок, сорри, не допоняли друг друга ;)
nikosidСпасибо ещё раз за видео.
Хочу предложить небольшую помощь тем, кто смотрит всё это и пересматривает отдельные части - можно на youtube в описании добавить таймкоды. Я об этом немного поздно задумался, но пока вот, что набросал:
Может немного кривые комментарии, но всё равно это очень поможет многим. Мне даже самому уже удобно.
Постараюсь чуть позже скинуть ещё коды остального времени, ну или может ещё кто-то поможет.
СергейСтранно, сделал все по образу и подобию, а в итоге в консоль все равно валит html верстку
ИгрБлин все повторял до 27 минуты. И вылезла ошибка
Дмитрий Елисеев$config = [ 'id' => 'app', 'language'=>'ru-RU', ... ];
Денис ЖурбаДякую за гарний матеріал, причому не перший! Спочатку теж думав. що багато розжовується, але в цьому матеріалі стільки інформації для тих, хто не мав справу із тестуванням взагалі (як я), що за один раз все важко сприйняти та розжовування не зайві! Товариш підказав - можна ставити швидкість відтворення відео, наприклад 1,25 або 1,5) Ще раз дякую!
Денис ЖурбаІд прописав, ніби все перевірив, але така сама помилка -
Ось архів, якщо не важко гляньте в чому причина:
http://www.ex.ua/400575346514
Дякую)
Дмитрий Елисеев$config = [ 'id' => 'app', 'language'=>'ru-RU', ... ];
Денис Журбав тому то і річ - там прописано)
І тест ніби запускається, але потім помилку пише:
http://prntscr.com/cldhrp
http://prntscr.com/cldinx
Денис ЖурбаРозібрався) потрібно уважно імпортувати класи. В моєму випадку в класі Тесту потрібно було:
use tests\codeception\backend\unit\DbTestCase;
замість
use yii\codeception\DbTestCase;
Дякую Дмитру, ще раз, за гарний матеріал.
Денис ЖурбаПоборов Unit тести. Тепер питання по функціональним)
LoginCept.php:
namespace tests\codeception\backend\functional; use tests\codeception\backend\FunctionalTester; use tests\codeception\common\_pages\LoginPage; /* @var $scenario \Codeception\Scenario */ $I = new FunctionalTester($scenario); $I->wantTo('ensure login page works'); $I->amOnPage('/user/login');Результат:
Tests\codeception\backend.functional Tests (1) ------------- E LoginCept: Ensure login page works ------------------------------------------------------------ 1) LoginCept: Ensure login page works Test .\functional\\LoginCept.php [yii\base\InvalidConfigException] Unable to determine the path info of the current request. Scenario Steps: 2. $I->amOnPage("/user/login") at functional\LoginCept.php:17 1. $I->amOnPage("/backend/web/index-test.php/user/login") at ption\BasePage.php:77 #1 \vendor\yiisoft\yii2\web\Request.php:677 #2 \vendor\yiisoft\yii2\web\UrlManager.php:237 #3 \vendor\yiisoft\yii2\web\Request.php:179 #4 \vendor\yiisoft\yii2\web\Application.php:78 #5 \Users\AdminD\AppData\Roaming\Composer\vendor\symfony\browser-kit\Client.php:315 #6 Codeception\Module\Yii2->amOnPage #7 \tests\codeception\backend\_support\_generated\FunctionalTesterActions.php:554 #8 \tests\codeception\backend\functional\LoginCept.php:17 Time: 1.02 seconds, Memory: 14.00MBВ чому може бути проблема?
Дякую)
ИванПомогите, выполнял все по видео и столкнулся с проблемой после установки PHPUnit, запускаю тест - вылетает ошибка:
что я сделал не так? :(
Дмитрий ЕлисеевВ правиле валидации [..., 'match', 'pattern' => '...'] ключ 'pattern' забыли.
ИванБлин, мелочь такая, из-за невнимательности всю голову сломал.
ПашаЗдравствуйте, отличный вебинар, то что надо.
У меня возникла небольшая проблема, при запуске команды phpunit --coverage-html ./report
у меня выводится ошибка - No whitelist is configured, no code coverage will be generated.
И понять что он хочет я немогу. Подскажите пожалуйста что я не так делаю.
Дмитрий ЕлисеевПропишите whitelist вместо blacklist.
ПавелЗдравствуйте! Подскажите пожалуйста, как быть если сайт на виртуалке, но мне нужно запускать selenium-server не на виртуалке, а на самом компьютере?
Т.е. чтобы браузер запускался на компьютере, а код находится на виртуальной машине.
АлександрЗдравствуйте, Дмитрий!
Не могу запустить тесты с момента после установки PHPUnit, у вас класс наследуется от PHPUnit_Framework_TestCase но такого не находит у меня (устанавливал как глобально, так и в проект), помогает только так: PHPUnit\Framework\TestCase.
Не совсем понимаю почему так.
Работабю из OpenServer, уже подумываю на vagrant перейти, может из ubuntu будет работать, но не уверен, что это поможет, думаю что чего-то не хватает, что бы был такой класс PHPUnit_Framework_TestCase
Дмитрий Елисеев> Не совсем понимаю почему так.
В феврале вышел PHPUnit 6.0, где PHPUnit_Framework_TestCase переделали в PHPUnit\Framework\TestCase. Это нормально.
АлександрДа, я уже понял, у меня в зависимостях что-то не так было, не поставилась версия из видеоурока, потому поставил 6ю. Спасибо за ответ.
АлександрНужна помощь, помоги плз. Прошел вебинар, инетересовало unit-тестирование. Все вродебы получилось, все стало понятно. Пытаюсь теперь запустить юнит тесты на своем проекте, advanced шаблон. Сгенерировал codeception тесты, прописал бутстрап настройки, как в уроке. Для проверки взял из урока EmailValidatorTest и не завелось. При запуске тестов пишет [Error] Class 'Yii' not found
Гуглил, не особо помогло, из того, что я нашел по советам, так это то, что надо подключать автолоад и сам Yii.php, но в бутрстрап он у меня подключен, как и в бутстрапе из урока, пути указаны правильно, помоги плз, если есть мыли, что может быть
Александрвопрос снимаю предыдущий. я починил. но не совсем понимаю, почему так. В _bootstrap.php есть строка: Yii::setAlias('@tests', dirname(__DIR__).'/tests'); Вот именно из-за нее ругалось. Не пойму почему...
ВикторЯ парился много времени с тестами, гуглил и прочее, потом спросил у знакомого, который их делал и говорит что тоже пытался долго просто стандартные запустить и ничего не выходило, а на линуксе летает, так вот хотелось спросить почему на винде не получается запустить? Ошибку точно не помню, но может известно почему, может что-то включить нужно или поставить расширение какое? Если нужно, могу скинуть ошибку, с чем работаю и что сделал для запуска?
Это не срочно или обязательно, а просто интересно, да и для других может будет полезно) Потому что я гуглил опять же этот вопрос, по поводу того, чего же на винде не запускаются, а на линуксе работает норм и ничего не нашел, никаких объяснений и прочей инфы.
Проблемы с переходом на линукс нет, или поднять сервер под виртуальной машиной, Vagrant'ом, но все же интересно что такое с виндой и в чем у нее проблема?
Дмитрий Елисеев> Ошибку точно не помню
Оттуда и надо копать.
Виктор ЧистяковУже решил проблему, на OpenServer 5.2.2, PHP7, раньше просто ставил не те расширения которые нужно было (точнее не те версии), в итоге в composer.json (для глобальных расширений) вот такой код выходит:
{ "require": { "fxp/composer-asset-plugin": "^1.2.0", "codeception/specify": "*", "codeception/verify": "~0.3.1", "se/selenium-server-standalone": "^3.5", "codeception/codeception": "^2.3", "codeception/base": "^2.3" } }
ИгорьПока смотрел набросал по темам еще материала
https://github.com/kopyrin/doc-codeception
СергейСпасибо огромное. Но я был бы не я если бы не возникало вопросов. Остановился на 3:17:39 в чем запара
вот модель
class ScienceDegree extends \yii\db\ActiveRecord { public static function tableName() { return 'science_degree'; } public function rules() { return [ [['name'],'required'], [['comment'], 'string'], [['name'], 'string', 'max' => 255], ]; } }вот тест
class ScienceDegreeTest extends \Codeception\TestCase\Test { use Specify; protected $tester; private $scienceDegree; protected function _before() { Yii::$app->db->createCommand()->insert(ScienceDegree::tableName(), [ 'name' => 'doctor' ]); $this->scienceDegree = new ScienceDegree(); } public function validationTest() { $this->specify('fields are required', function () { $this->scienceDegree->name = null; expect('model is not valid', $this->scienceDegree->validate())->false(); expect('name has error', $this->scienceDegree->getErrors())->hasKey('name'); }); $this->specify('fields are wrong value', function () { $this->scienceDegree->name = 123; expect('model is not valid', $this->scienceDegree->validate())->false(); expect('name error', $this->scienceDegree->getErrors())->hasKey('name'); }); $this->specify('fields are unique value', function () { $this->scienceDegree->name = 'doctor'; expect('model is not valid', $this->scienceDegree->validate())->false(); expect('name error', $this->scienceDegree->getErrors())->hasKey('name'); }); $this->specify('fieldds are correct value', function () { $this->scienceDegree->name = 'Profesor'; expect('model is valid', $this->scienceDegree->validate())->true(); }); } public function testSaveIntoDatabase() { $this->scienceDegree->name = 'Title'; expect('model is saved', $this->scienceDegree->save())->true(); } }набираю в терминале
codecept unit run
получаю
и пока не просмотрел все, вы таблица со внешними ключами рассматриваете?
Дмитрий ЕлисеевПереименуйте validationTest в testValidation.
СергейДа спасибо огромное очень важное замечание.
Валера ДорохольскийДмитрий, добрый день. При запуске unit тестов codeception не находит класс User. Не подскажете где мне искать ошибку?
Дмитрий ЕлисеевПроверить bootstrap.php файлы.
Валера ДорохольскийСпасибо. Не заметил.
АлексейСкажите пожалуйста, а почему в PHPStotm может отсутствовать такой интерфейс для Unit тестов как у вас? У меня лишь какой-то странный и простой: https://i.stack.imgur.com/wJxfU.png причем версия шторма 2018.3