¿Cómo reutilizar el código con los paquetes de Symfony 5? Parte 6. Pruebas

Hablemos sobre cómo detener el copiar y pegar entre proyectos y transferir el código a un paquete de plug-in reutilizable Symfony 5. Una serie de artículos que resumen mi experiencia con los paquetes se llevarán a cabo en la práctica desde la creación de un paquete mínimo y la refactorización de una aplicación de demostración para las pruebas y el ciclo de lanzamiento del paquete.


En la parte anterior, creamos la configuración del paquete . En este artículo, analizaremos cómo probar un paquete, escribir algunas pruebas y crear una micro aplicación dentro del paquete para ejecutarlas.


Contenido de la serie

Si no está completando constantemente el tutorial, descargue la aplicación del repositorio y cambie a la rama de 5 configuraciones .


Instrucciones para instalar e iniciar el proyecto en un archivo README.md. Encontrará la versión final del código para este artículo en la rama de 6 pruebas .


Portar pruebas a un paquete


Antes de refactorizar, ya se escribieron 2 pruebas: una prueba unitaria de uno de los servicios y una prueba funcional del controlador.


Tenemos una aplicación primitiva en la que la capa de infraestructura (DB) no está separada de la lógica del dominio: las pruebas usan una base de datos sqlite temporal.


Comprueba si las pruebas funcionan:


./vendor/bin/simple-phpunit

Error: Class 'App\Service\EventExporter\Exporters\GoogleCalendarExporter' not found

Las pruebas dejaron los nombres de espacio de nombres App\restantes del código hasta que se transfirió al paquete.


En ambas pruebas, arregle el espacio de nombres bravik\CalendarBundley ejecútelo nuevamente.
Las pruebas deben pasar con éxito.


En la raíz del paquete, cree una carpeta tests( bundles/CalendarBundle/tests) y mueva la carpeta de tests/Serviceprueba de la unidad allí . ControllerTransferimos la prueba funcional en la carpeta un poco más tarde.


Ejecución de pruebas unitarias desde un paquete


Para ejecutar la prueba, necesitamos instalar PHPUnit dentro del paquete:


cd bundles/CalendarBundle
composer require symfony/phpunit-bridge --dev

Esto agregará la Unidad PHP como una dependencia de desarrollo al composer.jsonpaquete, y también creará un archivo composer.lock. No lo necesitamos en paquetes: cree un .gitignorearchivo y agréguelo allí.


La unidad PHP lista para usar no funcionará. Debe configurarlo: especifique dónde se encuentran las pruebas y conecte el autocargador del compositor.


- 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()
    {
        // TODO: Implement registerBundles() method.
    }

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        // TODO: Implement registerContainerConfiguration() method.
    }
}

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");
    // Assertion on response
    // ...
}

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 - .


Encontrará la versión final del código para este artículo en la rama de 6 pruebas .


En el próximo artículo hablaremos sobre cómo lanzar nuevos lanzamientos de paquetes sin dolor ni sufrimiento, cómo organizar el proceso de instalación inicial y actualización del paquete.


Otros artículos de la serie:


Parte 1. El paquete mínimo
Parte 2. Sacamos el código y las plantillas en el paquete
Parte 3. Integración del paquete con el host: plantillas, estilos, JS
Parte 4. Interfaz para expandir el paquete
Parte 5. Parámetros y configuración
Parte 6. Pruebas, microaplicación dentro del paquete
Parte 7 Ciclo de lanzamiento, instalación y actualización.


All Articles