Тестирование с PHPUnit и Codeception

Самая объёмная тема среди предложенных завершена. Выкладываю исправленную и дополненную запись вебинара-скринкаста о тестировании c PHPUnit и Codeception. Добавлены и доработаны примеры кода, пункты про аннотации, фикстуры, анализ покрытия, Faker, про установку всего через composer и другие нюансы:

Открыть на YouTube
Коды примеров
Код проекта с тестами

Статья про запуск в проекте
Статья про применение моков и TDD

Ещё в тему доклад по обновлённым тестам в Yii2:

Структура вебинара-скринкаста (кликабельно):

testing.png

Кто ещё не подписался на остальные вебинары, тот сам себе Буратино:

И задавайте вопросы в комментариях. Заранее спасибо и до встречи в эфире!

Комментарии

 

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:

codecept run --no-colors

А так это просто в 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 в описании добавить таймкоды. Я об этом немного поздно задумался, но пока вот, что набросал:

https://youtu.be/gRmEpUYaS20?t=3h37m32s - codeception
https://youtu.be/gRmEpUYaS20?t=3h00m38s - Verify
https://youtu.be/gRmEpUYaS20?t=3h10m35s - Specify
https://youtu.be/gRmEpUYaS20?t=3h20m7s - Фикстуры
https://youtu.be/gRmEpUYaS20?t=3h26m42s - Аннотации
https://youtu.be/gRmEpUYaS20?t=3h32m27s - Тесты на будущее/пустые тесты (Incomplete)
https://youtu.be/gRmEpUYaS20?t=3h35m5s - Пропущенные тесты (Skipped)
https://youtu.be/gRmEpUYaS20?t=3h38m6s - Группы тестов (@group)
https://youtu.be/gRmEpUYaS20?t=3h40m36s - (@expectedExeption)
https://youtu.be/gRmEpUYaS20?t=3h55m18s - Приёмочные и функциональные тесты

Может немного кривые комментарии, но всё равно это очень поможет многим. Мне даже самому уже удобно.
Постараюсь чуть позже скинуть ещё коды остального времени, ну или может ещё кто-то поможет.

Ответить

 

Сергей

Странно, сделал все по образу и подобию, а в итоге в консоль все равно валит html верстку

Ответить

 

Игр

Блин все повторял до 27 минуты. И вылезла ошибка

Fatal error: Uncaught exception 'yii\base\InvalidConfigException'
with message 'The "id" configuration for the Application is required.'
Ответить

 

Дмитрий Елисеев
$config = [
    'id' => 'app',
    'language'=>'ru-RU',
    ...
];
Ответить

 

Денис Журба

Дякую за гарний матеріал, причому не перший! Спочатку теж думав. що багато розжовується, але в цьому матеріалі стільки інформації для тих, хто не мав справу із тестуванням взагалі (як я), що за один раз все важко сприйняти та розжовування не зайві! Товариш підказав - можна ставити швидкість відтворення відео, наприклад 1,25 або 1,5) Ще раз дякую!

Ответить

 

Денис Журба

Ід прописав, ніби все перевірив, але така сама помилка -

[yii\base\InvalidConfigException] The "id" configuration for the Application is required.

Ось архів, якщо не важко гляньте в чому причина:
http://www.ex.ua/400575346514

Дякую)

Ответить

 

Дмитрий Елисеев
$config = [
    'id' => 'app',
    'language'=>'ru-RU',
    ...
];
Ответить

 

Денис Журба

Розібрався) потрібно уважно імпортувати класи. В моєму випадку в класі Тесту потрібно було:

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, запускаю тест - вылетает ошибка:

1) MyUserTest::testValue
yii\base\UnknownPropertyException:
Setting unknown property: yii\validators\RegularExpressionValidator::0

vendor\yiisoft\yii2\base\Component.php:197
vendor\yiisoft\yii2\BaseYii.php:521
vendor\yiisoft\yii2\base\Object.php:105
vendor\yiisoft\yii2\di\Container.php:379
vendor\yiisoft\yii2\di\Container.php:154
vendor\yiisoft\yii2\BaseYii.php:344
vendor\yiisoft\yii2\validators\Validator.php:222
vendor\yiisoft\yii2\base\Model.php:445
vendor\yiisoft\yii2\base\Model.php:409
vendor\yiisoft\yii2\base\Model.php:185
vendor\yiisoft\yii2\base\Model.php:345
vendor\yiisoft\yii2\db\ActiveRecord.php:421
vendor\yiisoft\yii2\db\BaseActiveRecord.php:632
unit\MyUserTest.php:14

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.

что я сделал не так? :(

Ответить

 

Дмитрий Елисеев

В правиле валидации [..., '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"
    }
}
Ответить

 

Сергей

Спасибо огромное. Но я был бы не я если бы не возникало вопросов. Остановился на 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

получаю

==== Redirecting to Composer-installed version in vendor/codeception ====
Codeception PHP Testing Framework v2.1.11
Powered by PHPUnit 5.3.5 by Sebastian Bergmann and contributors.

Unit Tests (1) ---------------------------------------------------------------------------------------------
Test save into database (ScienceDegreeTest::testSaveIntoDatabase)                                     Ok
------------------------------------------------------------------------------------------------------------


Time: 106 ms, Memory: 12.00MB

OK (1 test, 1 assertion)

и пока не просмотрел все, вы таблица со внешними ключами рассматриваете?

Ответить

 

Дмитрий Елисеев

Переименуйте validationTest в testValidation.

Ответить

 

Сергей

Да спасибо огромное очень важное замечание.

Ответить

 

Валера Дорохольский

Дмитрий, добрый день. При запуске unit тестов codeception не находит класс User. Не подскажете где мне искать ошибку?

Ответить

 

Дмитрий Елисеев

Проверить bootstrap.php файлы.

Ответить

 

Валера Дорохольский

Спасибо. Не заметил.

Ответить

 

Алексей

Скажите пожалуйста, а почему в PHPStotm может отсутствовать такой интерфейс для Unit тестов как у вас? У меня лишь какой-то странный и простой: https://i.stack.imgur.com/wJxfU.png причем версия шторма 2018.3

Ответить

Оставить комментарий

Войти | Завести аккаунт | Войти через


(никто не увидит)





Можно использовать теги <p> <ul> <li> <b> <i> <a> <pre>