Como reutilizar código com pacotes symfony 5? Parte 6. Teste

Vamos falar sobre como parar a copiar e colar entre projetos e transferir o código para um pacote reutilizável de plug-in Symfony 5. Uma série de artigos resumindo minha experiência com pacotes configuráveis, na prática, criará um pacote mínimo e refatorará um aplicativo de demonstração para testes e o ciclo de lançamento de pacotes.


Na parte anterior, criamos a configuração do pacote . Neste artigo, analisaremos como testar um pacote configurável, escrever alguns testes e criar um micro aplicativo dentro do pacote configurável para executá-los.


Conteúdo da série

Se você não estiver concluindo consistentemente o tutorial, faça o download do aplicativo no repositório e alterne para a ramificação de 5 configurações .


Instruções para instalar e iniciar o projeto em um arquivo README.md. Você encontrará a versão final do código para este artigo na ramificação de 6 testes .


Portando testes para um pacote configurável


Antes da refatoração, dois testes já foram gravados: um teste de unidade de um dos serviços e um teste funcional do controlador.


Temos um aplicativo primitivo no qual a camada de infraestrutura (DB) não é separada da lógica do domínio: os testes usam um banco de dados sqlite temporário.


Verifique se os testes funcionam:


./vendor/bin/simple-phpunit

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

Os testes deixaram os nomes de namespace App\restantes do código até que ele fosse transferido para o pacote.


Nos dois testes, fixamos o espaço para nome bravik\CalendarBundlee o executamos novamente.
Os testes devem passar com sucesso.


Na raiz do pacote configurável, crie uma pasta tests( bundles/CalendarBundle/tests) e mova a pasta de tests/Serviceteste de unidade para . ControllerTransferimos o teste funcional na pasta um pouco mais tarde.


Executando testes de unidade de um pacote


Para executar o teste, precisamos instalar o PHPUnit dentro do pacote:


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

Isso adicionará a unidade PHP como uma dependência do desenvolvedor ao composer.jsonpacote e também criará um arquivo composer.lock. Não precisamos dele em pacotes: crie um .gitignorearquivo e adicione-o lá.


Unidade PHP pronta para uso não funcionará. Você precisa configurá-lo: especifique onde estão os testes e conecte o carregador automático do 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 - .


Você encontrará a versão final do código para este artigo na ramificação de 6 testes .


No próximo artigo, falaremos sobre como liberar novas liberações de pacotes configuráveis ​​sem sofrimento e sofrimento, como organizar o processo de instalação inicial e atualização do pacote configurável.


Outros artigos da série:


Parte 1. O pacote mínimo
Parte 2. Retiramos o código e os modelos no pacote
Parte 3. Integração do pacote com o host: modelos, estilos, JS
Parte 4. Interface para expandir o pacote
Parte 5. Parâmetros e configuração
Parte 6. Teste, microaplicação dentro do pacote
Parte 7 Ciclo de lançamento, instalação e atualização


All Articles