让我们谈谈如何停止项目之间的复制粘贴并将代码转移到可重用的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发布周期,安装和更新