让我们谈谈如何停止项目之间的复制粘贴并将代码转移到可重用的symfony 5插件包中。一系列总结我对包的经验的文章将在实践中引导您创建最小的包,并将演示应用程序重构为测试和包发布周期。
在上一部分中,我们创建了bundle配置。在本文中,我们将分析如何测试包,编写一些测试以及在包内创建一个微型应用程序以运行它们。
如果您没有按顺序完成本教程,请从存储库下载应用程序,然后切换到5配置分支。
有关在文件中安装和启动项目的说明README.md。您可以在6测试分支中找到本文代码的最终版本。
将测试移植到套件
在重构之前,已经编写了2个测试:一个服务的单元测试和控制器的功能测试。
我们有一个原始应用程序,其中基础结构层(DB)没有与域逻辑分开:测试使用临时的sqlite数据库。
检查测试是否有效:
./vendor/bin/simple-phpunit
Error: Class 'App\Service\EventExporter\Exporters\GoogleCalendarExporter' not found
测试将名称空间名称App\保留在代码中,直到将其转移到包中为止。
在这两个测试中,将名称空间固定在上bravik\CalendarBundle并再次运行。
测试必须成功通过。
在包的根目录中,创建一个文件夹tests(bundles/CalendarBundle/tests),然后将tests/Service单元测试文件夹移动到该文件夹中。我们稍后Controller再将功能测试转移到该文件夹中。
从捆绑包运行单元测试
要运行测试,我们需要在捆绑软件中安装PHPUnit:
cd bundles/CalendarBundle
composer require symfony/phpunit-bridge --dev
这会将PHP Unit作为dev依赖项添加到该composer.json包中,并创建一个file composer.lock。我们不需要捆绑销售:创建.gitignore文件并将其添加到其中。
开箱即用的PHP单元将无法使用。您需要配置它:指定测试所在的位置并连接作曲家自动加载器。
- phpunit.xml.dist.
, Symfony-, 1 bootstrap:
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="bin/.phpunit/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="./vendor/autoload.php"
>
bootstrap composer, PHPUnit .
:
./vendor/bin/simple-phpunit
!
: - .
… ?
.
, 2 .
, — , — -.
.
, ,
-.
- Symfony — Kernel symfony/http-kernel.
, , .
. , , Symfony DI-, . symfony/framework-bundle, http-kernel.
composer require symfony/framework-bundle
tests/App TestingKernel .
Symfony\Component\HttpKernel\Kernel , :
<?php
namespace bravik\CalendarBundle\Tests\App;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Kernel;
class TestingKernel extends Kernel
{
public function __construct()
{
parent::__construct('test', false);
}
public function registerBundles()
{
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
}
}
composer bravik\CalendarBundle\Tests\App.
: 'test', . , .
registerBundles() . :
public function registerBundles()
{
return [
new CalendarBundle()
];
}
registerContainerConfiguration() DI-.
.
symfony/router. , .
. src/Kernel -:
class Kernel extends BaseKernel
{
use MicroKernelTrait;
protected function configureRoutes(RouteCollectionBuilder $routes): void
{
$routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob');
}
}
, Symfony- «» MicroKernelTrait.
registerContainerConfiguration(),
-:
configureContainer()configureRoutes(), .
:
TestingKernel registerContainerConfiguration(),use MicroKernelTrait;- .
configureRoutes() config/routes.yaml :
protected function configureRoutes(RouteCollectionBuilder $routes)
{
$routes->import(__DIR__.'/../../config/routes.yaml');
}
yaml, :
composer require symfony/yaml
.
?
tests/Controller/EventControllerTest.
HTTP . HTTP-. , .
Symfony Request, . index.php:
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
, .
, Symfony HttpKernelBrowser :
composer require symfony/browser-kit --dev
:
public static function createClient()
{
$kernel = new TestingKernel();
return new HttpKernelBrowser($kernel);
}
public function testSomeAction()
{
$client = static::createClient();
$response = $client->request("/some/action");
}
HttpKernelBrowser. $client->request() .
, , WebTestCase, Symfony. createClient(), , createKernel(), .
, , — . KERNEL_CLASS phpunit.xml.dist:
<php>
<server name="APP_ENV" value="test" force="true" />
<server name="KERNEL_CLASS" value="bravik\CalendarBundle\Tests\App\TestingKernel"
force="true" />
</php>
:
./vendor/bin/simple-phpunit tests/Controller/EventControllerTest.php
...
LogicException: Container extension "framework" is not registered
MicroKernelTrait. DI- «-», framework.
FrameworkBundle. :
public function registerBundles()
{
return [
new FrameworkBundle(),
new CalendarBundle()
];
}
:
InvalidArgumentException: Cannot determine controller argument for "bravik\CalendarBundle\Controller\EditorController::new()": the $entityManager argument is type-hinted with the non-existent class or interface: "Doctrine\ORM\EntityManagerInterface".
- ? EditorController?
new CalendarBundle() TestingKernel, services.yaml, .
autowiring Symfony . typehints , Symfony typehints .
, , TestingKernel.
:
composer require doctrine/orm doctrine/doctrine-bundle symfony/twig-bundle
composer require doctrine/doctrine-fixtures-bundle liip/test-fixtures-bundle --dev
TestingKernel:
public function registerBundles()
{
return [
new DoctrineBundle(),
new DoctrineFixturesBundle(),
new LiipTestFixturesBundle(),
new TwigBundle(),
];
}
: tests/App/config/config.yaml:
#
# @see https://symfony.com/doc/current/reference/configuration/framework.html#test
framework:
test: true
doctrine:
# SQLITE var/test.db
dbal:
driver: pdo_sqlite
path: "%kernel.cache_dir%/test.db"
# ORM-
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
calendar:
enable_soft_delete: true
services:
# Twig, mock- webpack encore,
#
bravik\CalendarBundle\Tests\App\TwigWebpackSuppressor:
tags: ['twig.extension']
#
bravik\CalendarBundle\Tests\Fixtures\:
resource: '../../Fixtures'
tags: ['doctrine.fixture.orm']
, packages, . Framework, Doctrine, .
TestingKernel:
protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
{
$loader->load(__DIR__.'/config/config.yaml', 'yaml');
}
(!) , , var Symfony . .gitignore.
, dev . - , — !
, - !
, , .
, Symfony - .
您可以在6测试分支中找到本文代码的最终版本。
在接下来的文章中,我们将讨论如何释放新的软件包版本,而不会疼痛和痛苦,如何组织初始安装和捆绑的更新的过程。
该系列的其他文章:
1.部分最小包
2的一部分,我们拿出包中的代码和模板
第3部分集成与主机捆绑的:模板,样式,JS
第4部分接口扩展包
第5部分参数及配置
部分6.测试,该包内microapplication
第7发布周期,安装和更新