Desarrollo guiado por pruebas con Laravel y Doctrine

Como desarrollador de PHP, puede utilizar la técnica de desarrollo impulsado por pruebas (TDD) para desarrollar su software escribiendo pruebas. Típicamente, TDD dividirá cada tarea del desarrollo en unidades individuales. Luego se escribe una prueba para garantizar que la unidad se comporta como se espera..

Cada proyecto que utiliza el desarrollo guiado por pruebas sigue tres pasos simples repetidamente:

  • Escriba una prueba para la siguiente parte de la funcionalidad que desea agregar.
  • Escribe el código funcional hasta que la prueba pase..
  • Refactorizar código nuevo y antiguo para hacerlo bien estructurado.

Continúe recorriendo estos tres pasos, una prueba a la vez, desarrollando la funcionalidad del sistema. Las pruebas le ayudarán a refactorizar, lo que le permite mejorar su diseño con el tiempo y hace que algunos problemas de diseño sean más evidentes.

Las pruebas que contienen componentes individuales pequeños se llaman pruebas unitarias. Si bien las pruebas unitarias se pueden realizar de forma independiente, si prueba algunos de los componentes cuando están integrados con otros componentes, lo está haciendo. pruebas de integración. El tercer tipo de prueba es talones de prueba. Los talones de prueba le permiten probar su código sin tener que hacer llamadas reales a una base de datos.

¿Por qué funciona TDD?

Hoy en día, como puede usar la sintaxis moderna de PHP IDE, la retroalimentación no es un gran problema. Uno de los aspectos importantes de su desarrollo es asegurarse de que el código haga lo que usted espera que haga. Como el software es complicado (diferentes componentes integrados entre sí), sería difícil que todas nuestras expectativas se hagan realidad. Especialmente al final del proyecto, debido a su desarrollo, el proyecto se volverá más complejo y, por lo tanto, más difícil de depurar y probar..

TDD verifica que el código hace lo que usted espera que haga. Si algo sale mal, solo hay unas pocas líneas de código para volver a verificar. Los errores son fáciles de encontrar y corregir. En TDD, la prueba se centra en el comportamiento, no en la implementación. TDD proporciona un código probado que ha sido probado, diseñado y codificado.

PHPUnit & Laravel

PHPUnit es el estándar de facto para la prueba unitaria de PHP. Es esencialmente un marco para escribir pruebas y proporcionar las herramientas que necesitará para ejecutar pruebas y analizar los resultados. PHPUnit deriva su estructura y funcionalidad de Kent Beck's SUnit.

Existen varias aserciones diferentes que pueden ayudarlo a probar los resultados de todo tipo de llamadas en sus aplicaciones. A veces tiene que ser un poco más creativo para probar una funcionalidad más compleja, pero las afirmaciones proporcionadas por PHPUnit cubren la mayoría de los casos que desearía probar. Aquí hay una lista de algunos de los más comunes que usará en sus exámenes:

  • AssertTrue: Revise la entrada para verificar que es igual a true.
  • AssertFalse: Compruebe la entrada para verificar que es igual a un valor falso.
  • AssertEquals: Compruebe el resultado contra otra entrada para una coincidencia.
  • AssertArrayHasKey (): Informa de un error si la matriz no tiene la clave.
  • AssertGreaterThan: Verifica el resultado para ver si es más grande que un valor.
  • AssertContains: Compruebe que la entrada contiene un cierto valor.
  • AssertType: Comprobar que una variable es de un tipo determinado.
  • AssertNull: Comprueba que una variable es nula.
  • AssertFileExists: Verificar que exista un archivo.
  • AssertRegExp: Compruebe la entrada contra una expresión regular.

De forma predeterminada, PHPUnit 4.0 se instala en Laravel, y puede ejecutar el siguiente comando para actualizarlo:

bash composer global requiere "phpunit / phpunit = 5.0. *"

los phpunit.xml El archivo en el directorio raíz de Laravel te permitirá hacer algunas configuraciones. En este caso, si desea anular la configuración predeterminada, puede editar el archivo:

"xml

./ pruebas / app /

"

Como se ve en el código anterior, he agregado la configuración de la base de datos de muestra (no utilizada en el artículo).

¿Qué es la Doctrina ORM??

Doctrine es un ORM que implementa el patrón del mapeador de datos y le permite hacer una separación clara de las reglas de negocios de la aplicación de la capa de persistencia de la base de datos. Para configurar Doctrine, hay un puente para permitir la coincidencia con la configuración existente de Laravel 5. Para instalar Doctrine 2 dentro de nuestro proyecto Laravel, ejecutamos el siguiente comando:

bash composer require laravel-doctrine / orm

Como es habitual, el paquete debe ser agregado a la app / config.php, como proveedor de servicios:

php LaravelDoctrine \ ORM \ DoctrineServiceProvider :: class,

El alias también debe estar configurado:

php 'EntityManager' => LaravelDoctrine \ ORM \ Facades \ EntityManager :: class

Finalmente, publicamos la configuración del paquete con:

proveedor artesano de bash php: publish --tag = "config"

Cómo probar los repositorios de Doctrine

Antes que nada, debes saber acerca de los accesorios. Los dispositivos se utilizan para cargar un conjunto controlado de datos en una base de datos, que necesitamos para realizar pruebas. Afortunadamente, Doctrine 2 tiene una biblioteca para ayudarlo a escribir dispositivos para el ORM de Doctrine.

Para instalar el paquete de accesorios en nuestra aplicación Laravel, necesitamos ejecutar el siguiente comando:

el compositor de bash requiere --dev doctrine / doctrine-fixtures-bundle

Vamos a crear nuestro accesorio en pruebas / Fixtures.php:

"Php namespace Test; use Doctrine \ Common \ Persistence \ ObjectManager; use Doctrine \ Common \ DataFixtures \ FixtureInterface; use app \ Entity \ Post;

La clase Fixtures implementa FixtureInterface / ** * Cargar los postes * @param ObjectManager $ manager * @return void * / public function load (ObjectManager $ manager) $ Post = new Post (['title' => 'hello world' , 'cuerpo' => 'esto es cuerpo']); $ manager-> persist ($ Post); $ manager-> flush ();

"

Como ves, tu clase de accesorio debería implementar el FixtureInterface y debería tener el carga (ObjectManager $ manager) método. Los dispositivos Doctrine2 son clases de PHP donde puedes crear objetos y conservarlos en la base de datos. Para cargar automáticamente nuestros dispositivos en Laravel, necesitamos modificar compositor.json en nuestra raíz Laravel:

json ... "autoload-dev": "classmap": ["tests / TestCase.php", "tests / Fixtures.php" // agregado aquí], ...

Entonces corre:

bash compositor dump-autoload

Vamos a crear nuestro archivo de prueba en el directorio de pruebas DoctrineTest.php.

"php namespace Test; use App; use App \ Entity \ Post; use Doctrine \ Common \ DataFixtures \ Executor \ ORMExecutor; use Doctrine \ Common \ DataFixtures \ Purger \ ORMPurger; use Doctrine \ Common \ DataFixtures \ Loader; use App \ Repository \ PostRepo;

class doctrineTest extiende TestCase private $ em; repositorio $ privado; $ loader privado; función pública setUp () parent :: setUp (); $ this-> em = App :: make ('Doctrine \ ORM \ EntityManagerInterface'); $ this-> repository = new PostRepo ($ this-> em); $ this-> executor = new ORMExecutor ($ this-> em, new ORMPurger); $ this-> loader = new Loader; $ this-> loader-> addFixture (nuevos accesorios);

/ ** @test * / public function post () $ purger = new ORMPurger (); $ executor = new ORMExecutor ($ this-> em, $ purger); $ executor-> execute ($ this-> loader-> getFixtures ()); $ user = $ this-> repository-> PostOfTitle ('hola mundo'); $ this-> em-> clear (); $ this-> assertInstanceOf ('App \ Entity \ Post', $ user);  "

En el preparar() método, yo instanciado el ORMExecutor y el cargador. También cargamos el Accesorios clase que acabamos de implementar.

No olvides que el /** @prueba */ La anotación es muy importante, y sin esto, el phpunit devolverá un No se encontraron pruebas en clase error.

Para comenzar a probar en nuestra raíz de proyecto, simplemente ejecute el comando:

bash sudo phpunit

El resultado sería:

"bash PHPUnit 4.6.6 por Sebastian Bergmann y colaboradores.

Lectura de configuración de /var/www/html/laravel/phpunit.xml. Tiempo: 17.06 segundos, Memoria: 16.00M OK (1 prueba, 1 aserción) "

Si desea compartir objetos entre aparatos, es posible agregar fácilmente una referencia a ese objeto por nombre y luego hacer referencia a éste para formar una relación. Aquí hay un ejemplo:

"Php namespace Test; use Doctrine \ Common \ Persistence \ ObjectManager; use Doctrine \ Common \ DataFixtures \ FixtureInterface; use app \ Entity \ Post;

La clase PostFixtures implementa FixtureInterface / ** * Cargar los dispositivos del usuario * * @param ObjectManager $ manager * @return void * / public function load (ObjectManager $ manager) $ postOne = new Post (['title' => 'hello' , 'cuerpo' => 'esto es cuerpo']); $ postTwo = new Post (['title' => 'hello there', 'body' => 'this is body two']); $ manager-> persist ($ postOne); $ manager-> persist ($ postTwo); $ manager-> flush ();

 // almacenar la referencia al rol de administrador para la relación del usuario con el rol $ this-> addReference ('new-post', $ postOne);  "

y el accesorio Comentario:

"Php namespace Test; use Doctrine \ Common \ Persistence \ ObjectManager; use Doctrine \ Common \ DataFixtures \ FixtureInterface; use app \ Entity \ Post;

la clase CommentFixtures implementa FixtureInterface / ** * Cargar los dispositivos del usuario * * @param ObjectManager $ manager * @return void * / public function load (ObjectManager $ manager) $ comment = new Comment (['title' => 'hello' , 'email' => '[email protected]', 'text' => 'nice post']); $ comentario-> setPost ($ this-> getReference ('new-post')); // carga la referencia almacenada $ manager-> persist ($ comentario); $ manager-> flush (); // almacenar la referencia a la nueva publicación para la relación de comentario para publicar $ this-> addReference ('new-post', $ postOne); "

Con dos métodos de getReference () y setReference (), Puedes compartir objeto (s) entre los accesorios.

Si el pedido de accesorios es importante para usted, puede solicitarlos fácilmente con el Obtener orden Método en sus accesorios de la siguiente manera:

php public function getOrder () return 5; // numero en que orden para cargar los aparatos

Observe que el pedido es relevante para la clase Loader.

Una de las cosas importantes acerca de los accesorios es su capacidad para resolver problemas de dependencia. Lo único que necesitas agregar es un método en tu accesorio como lo hice a continuación:

php public function getDependencies () return array ('Test \ CommentFixtures'); // fixture classes fixture depende de

Conclusión

Esta es solo una descripción de Test-Driven Development con Laravel 5 y PHPUnit. Al probar repositorios, es inevitable que vaya a la base de datos. En este caso, los accesorios de Doctrine son importantes..