proklung/phpunit-testing-tools
Composer 安装命令:
composer require proklung/phpunit-testing-tools
包简介
PHPUNIT testing tools.
README 文档
README
INTERNAL
Установка
composer require --dev proklung/phpunit-testing-tools
Всякое
Как построить тестовый контейнер
Создать класс:
use Prokl\TestingTools\Base\BaseTestCase; use Prokl\TestingTools\Tools\Container\BuildContainer; class ContainerAwareBaseTestCase extends BaseTestCase { /** * @inheritDoc * @throws Exception */ protected function setUp(): void { $this->container = static::$testContainer = BuildContainer::getTestContainer( [ 'dev/test_container.yaml', 'dev/local.yaml' ], '/Resources/config', [new SampleCompilerPass()], // Опциональный параметр - кастомные compiler passes, 'dev', // Окружение. По умолчанию - dev true // Debug. По умолчанию - true, ['service_to_mock'] // Сервисы, подлежащие мокингу (см. подраздел Моки сервисов) ); parent::setUp(); } }
Отнаследовать от него тест.
Подгрузятся конфиги сервисов из указанных файлов по указанному пути (относительно DOCUMENT_ROOT тестов).
Мокинг сервисов для функциональных тестов
Механизм (на базе создания прокси-сервисов по заданному списку) взят из бандла и адаптирован под локальные нужды.
use Prokl\TestingTools\Tools\ServiceMocker; use Prokl\TestingTools\Base\BaseTestCase; class MyTest extends BaseTestCase { use RestoreServiceContainer; protected function setUp(): void { parent::setUp(); $this->container = BuildContainer::getTestContainer( [ 'test_container.yaml' ], '/../../../../tests/Standalone/Resource/config', [], 'dev', true, ['filesystem.local.adapter'] // Сервис, который будет заменен моком. ); } public function testFoo() { // For all calls ServiceMock::all($this->container->get('filesystem.local.adapter'), 'getAdapter', function () { return new Local( $_SERVER['DOCUMENT_ROOT'] . '/test/'); }); $result = $this->container->get('filesystem.local.adapter'); // For only the next call ServiceMock::next($this->container->get('filesystem.local.adapter'), 'getAdapter', function () { return new Local( $_SERVER['DOCUMENT_ROOT'] . '/test/'); }); // This will queue a new callable ServiceMock::next($this->container->get('filesystem.local.adapter'), 'getAdapter', function () { throw new \InvalidArgument('getAdapter can call once time!'); }); $mock = // create a PHPUnit mock or any other mock you want. ServiceMocker::swap($this->container->get('filesystem.local.adapter'), $mock); // ... $service = $this->container->get('filesystem.local.adapter'); $result = $service->getAdapter(); // Метод сервиса (или сервис целиком) подменен. } protected function tearDown(): void { // To make sure we don't affect other tests ServiceMock::resetAll(); // You can include the RestoreServiceContainer trait to automatically reset services } }
BootTestKernelTrait
use Prokl\TestingTools\Traits\BootTestKernelTrait; class ExampleTest extends \Prokl\TestingTools\Base\BaseTestCase { use BootTestKernelTrait; protected function setUp(): void { parent::setUp(); $container = new ContainerBuilder(); // ... Наполнение тестового контейнера. self::$kernel = $this->bootTestKernel($container); } }
CommandTestCase
Базовый класс для тестирования консольных команд.
Методы:
executeCommand(Command $commandInstance, string $commandName, array $params = [])- вернет то, что команда вывела на экран.runCommand(Command $command, $input = [])- вернет результат выполнения методаexecuteкоманды.
Трэйт DefaultDataProviders
Несколько общих дата-провайдеров
provideEmptyValue- пустые значения.provideEmptyScalarValue- пустые скалярные значенияprovideBooleanValue- булевы значенияprovideDateTimeInstance- инстанц DateTimeprovideNotExistingFilePath- путь к несуществующему файлу
Мокер функций
Обертка над.
Пример (в тесте, унаследованном от BaseTestCase):
// Замокается полностью (т.е. не важно с какими параметрами пройдет вызов) функция in_the_loop $this->mockerFunctions->setNamespace('\Tests\API') ->full('in_the_loop', true) ->mock();
Namespace - пространство имен, в котором мокается функция.
Или частичное моканье (в зависимости от аргументов):
// При вызове get_cat_name с аргументом $this->idCategory вернет Mocked category $this->mockerFunctions->setNamespace('Test\API\Entity') ->partial('get_cat_name', 'Mocked category', $this->idCategory) ->partial('category_description', 'Mocked category description', $this->idCategory) ->mock();
При использовании этой фичи рекомендуется (во избежании проблем) на тест ставить аннотации:
/** * data() * * @runInSeparateProcess * @preserveGlobalState disabled */
Трэйт ServiceLocatorConstructorTrait
Конструктор сервис-локаторов Symfony для тестов.
Метод:
constructServiceLocator(array $config)- где$configмассив вида:
$object = new ClassName(); $config = [ 'service_key' => ClassName::class, 'service_key2' => $object, ];
Если передать название класса в конфиге, то внутри метода класс будет инстанцирован.
Console test
Форк пакета
use App\Command\CreateUserCommand; use Prokl\TestingTools\Base\BaseTestCase; use Prokl\TestingTools\Tools\Console\InteractsWithConsole; use Prokl\TestingTools\Traits\BootTestKernelTrait; class CreateUserCommandTest extends BaseTestCase { use InteractsWithConsole; use BootTestKernelTrait; protected function setUp(): void { parent::setUp(); $container = new ContainerBuilder(); $container->setDefinition( IntegrityCheck::class, new Definition(IntegrityCheck::class, []) )->setTags(['console.command' => ['command' => 'module:еуые']])->setPublic(true); self::$kernel = $this->bootTestKernel($container); $this->cliApplication = new \Symfony\Bundle\FrameworkBundle\Console\Application(self::$kernel); $this->cliApplication->add($container->get(IntegrityCheck::class)); } public function test_can_create_user(): void { $this->executeConsoleCommand('create:user kbond --admin --role=ROLE_EMPLOYEE --role=ROLE_MANAGER') ->assertSuccessful() // command exit code is 0 ->assertOutputContains('Creating admin user "kbond"') ->assertOutputContains('with roles: ROLE_EMPLOYEE, ROLE_MANAGER') ->assertOutputNotContains('regular user') ; // advanced usage $this->consoleCommand(CreateUserCommand::class) // can use the command class or "name" ->splitOutputStreams() // by default stdout/stderr are combined, this options splits them ->addArgument('kbond') ->addOption('--admin') // with or without "--" prefix ->addOption('role', ['ROLE_EMPLOYEE', 'ROLE_MANAGER']) ->addOption('-R') // shortcut options require the "-" prefix ->addOption('-vv') // by default, output has normal verbosity, use the standard options to change (-q, -v, -vv, -vvv) ->addOption('--ansi') // by default, output is undecorated, use this option to decorate ->execute() // run the command ->assertSuccessful() ->assertStatusCode(0) // equivalent to ->assertSuccessful() ->assertOutputContains('Creating admin user "kbond"') ->assertErrorOutputContains('this is in stderr') // used in conjunction with ->splitOutputStreams() ->assertErrorOutputNotContains('admin user') // used in conjunction with ->splitOutputStreams() ->dump() // dump() the status code/outputs and continue ->dd() // dd() the status code/outputs ; // testing interactive commands $this->executeConsoleCommand('create:user', ['kbond']) ->assertSuccessful() ->assertOutputContains('Creating regular user "kbond"') ; // advanced testing interactive commands $this->consoleCommand(CreateUserCommand::class) ->addInput('kbond') ->addOption('--no-interaction') // commands are run interactively if input is provided, use this option to disable ->execute() ->assertSuccessful() ->assertOutputContains('Creating regular user "kbond"') ; // access result $result = $this->executeConsoleCommand('create:user'); $result->statusCode(); $result->output(); $result->errorOutput(); } }
Или:
use App\Command\CreateUserCommand; use PHPUnit\Framework\TestCase; use Prokl\TestingTools\Tools\Console\TestCommand; class CreateUserCommandTest extends TestCase { public function test_can_create_user(): void { TestCommand::for(new CreateUserCommand(/** args... */)) ->splitOutputStreams() // by default stdout/stderr are combined, this options splits them ->addArgument('kbond') ->addOption('--admin') // with or without "--" prefix ->addOption('role', ['ROLE_EMPLOYEE', 'ROLE_MANAGER']) ->addOption('-R') // shortcut options require the "-" prefix ->addOption('-vv') // by default, output has normal verbosity, use the standard options to change (-q, -v, -vv, -vvv) ->addOption('--ansi') // by default, output is undecorated, use this option to decorate ->execute() ->assertSuccessful() ->assertStatusCode(0) // equivalent to ->assertSuccessful() ->assertOutputContains('Creating admin user "kbond"') ->assertErrorOutputContains('this is in stderr') // used in conjunction with ->splitOutputStreams() ->assertErrorOutputNotContains('admin user') // used in conjunction with ->splitOutputStreams() ->dump() // dump() the status code/outputs and continue ->dd() // dd() the status code/outputs ; // testing interactive commands TestCommand::for(new CreateUserCommand(/** args... */)) ->addInput('kbond') ->addOption('--no-interaction') // commands are run interactively if input is provided, use this option to disable ->execute() ->assertSuccessful() ->assertOutputContains('Creating regular user "kbond"') ; // access result $result = TestCommand::for(new CreateUserCommand(/** args... */))->execute(); $result->statusCode(); $result->output(); $result->errorOutput(); } }
Прочее
Invader (из пакета)
class MyClass { private string $privateProperty = 'private value'; private function privateMethod(): string { return 'private return value'; } } $myClass = new Myclass();
This is how you can get the value of the private property using the invade function.
invade($myClass)->privateProperty; // returns 'private value'
The invade function also allows you to change private values.
invade($myClass)->privateProperty = 'changed value'; invade($myClass)->privateProperty; // returns 'changed value
Using invade you can also call private functions.
invade($myClass)->privateMethod(); // returns 'private return value'
proklung/phpunit-testing-tools 适用场景与选型建议
proklung/phpunit-testing-tools 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 349 次下载、GitHub Stars 达 3, 最近一次更新时间为 2021 年 04 月 22 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 proklung/phpunit-testing-tools 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 proklung/phpunit-testing-tools 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 349
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 3
- 点击次数: 0
- 依赖项目数: 32
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2021-04-22