لنتحدث عن كيفية إيقاف النسخ واللصق بين المشاريع ونقل الشفرة إلى حزمة مكون إضافي symfony 5. يمكن إعادة استخدامها. ستؤدي سلسلة من المقالات التي تلخص تجربتي مع الحزم عمليًا إلى إنشاء الحد الأدنى من الحزم وإعادة صياغة التطبيق التجريبي إلى الاختبارات ودورة إصدار الحزمة.
في الجزء السابق ، أنشأنا تكوين الحزمة . في هذه المقالة ، سنقوم بتحليل كيفية اختبار حزمة ، وكتابة بعض الاختبارات وإنشاء تطبيق صغير داخل الحزمة لتشغيلها.
إذا كنت لا تكمل البرنامج التعليمي بالتسلسل ، فقم بتنزيل التطبيق من المستودع وانتقل إلى فرع التكوين 5 .
تعليمات تثبيت وبدء المشروع في ملف README.md
. ستجد النسخة النهائية من التعليمات البرمجية لهذه المقالة في فرع الاختبار 6 .
اختبارات النقل لحزمة
قبل إعادة الهيكلة ، تم بالفعل كتابة اختبارين: اختبار وحدة لإحدى الخدمات واختبار وظيفي لجهاز التحكم.
لدينا تطبيق بدائي لا يتم فيه فصل طبقة البنية التحتية (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 باعتبارها تبعية مطورة composer.json
للحزمة ، وكذلك إنشاء ملف 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. الاختبار ، التطبيق الجزئي داخل الحزمة
الجزء 7 دورة الإصدار والتثبيت والتحديث