Programación con Yii2 Pruebas automatizadas con codecepción

Lo que vas a crear

Si estás preguntando, "¿Qué es Yii?" echa un vistazo a mi tutorial anterior, Introducción al marco Yii, que revisa los beneficios de Yii e incluye una descripción general de las novedades de Yii 2.0, lanzada en octubre de 2014.

En esta serie de Programación con Yii2, guío a los lectores en el uso del Marco de trabajo de Yii2 para PHP. En este tutorial, exploraré las pruebas automatizadas utilizando Codeception, que se integra con el marco de desarrollo Yii2.

Es cierto que mi experiencia en escribir pruebas con mi código es escasa. A menudo he sido parte de proyectos individuales o pequeños con recursos limitados. Durante mi tiempo en Microsoft, tuvimos distintos equipos de prueba que hicieron esto. Pero, francamente, esto también es típico de ti, ¿verdad? A los programadores les gusta codificar, no escriben pruebas, al menos los programadores de la vieja escuela no escribieron pruebas..

Codeception es una biblioteca innovadora que, literalmente, tiene como objetivo hacer que las pruebas de escritura sean fáciles y divertidas. Y, diría que han tenido éxito en un grado razonable. Cuando metí mi dedo en el agua de "Lake Codeception", fue fácil y divertido. Sin embargo, cuando comencé a profundizar, tuve problemas de configuración con Yii y los módulos específicos utilizados en esta serie. Definitivamente hubo desafíos. Sin embargo, en general, estoy impresionado y veo el beneficio de aprender más.

En pocas palabras, Codeception y su integración con Yii me dan ganas de escribir más pruebas, por primera vez para mí. Sospecho que tendrás una experiencia similar.. 

Un pequeño recordatorio antes de comenzar, participo en los hilos de comentarios a continuación. Estoy especialmente interesado si tiene ideas adicionales o desea sugerir temas para futuros tutoriales. Si tiene alguna pregunta o sugerencia de tema, por favor publique a continuación. También puedes contactarme en Twitter @reifman directamente.

Empezando

Instalacion de codecepcion

Para guiarme, utilicé la documentación de configuración del entorno de prueba de Yii. Comencé con una instalación global de codecepción para poder usarla desde cualquier proyecto..

$ composer global require "codeception / codeception = 2.1. *" Se modificó el directorio actual a /Users/Jeff/.composer ./composer.json se ha actualizado. Carga de los repositorios del compositor con información del paquete. Dependencias de actualización (incluido require-dev) - Instalación de Symfony / yaml (v3.1.1) Cargando desde caché ... codeception / codeception sugiere instalar symfony / phpunit-bridge (para soporte de phpunit-bridge) Escribir archivo de bloqueo Generar archivos de carga automática

Usted también necesita requerir codecepción / especificar:

$ composer global require "codeception / specic = *" Se cambió el directorio actual a /Users/Jeff/.composer ./composer.json se ha actualizado. Carga de los repositorios del compositor con información del paquete. Dependencias de actualización (incluyendo require-dev) el compositor requiere "codecepción / verificación = * "- Instalación de codecepción / especificar (0.4.3) Descarga: 100% Escritura de archivo de bloqueo Generación de archivos de carga automática

codecepción / verificar:

$ composer require "codeception / verify = *" ./composer.json ha sido actualizado. Cargando repositorios de compositor con información del paquete. Dependencias de actualización (incluyendo require-dev) - Instalación de codeception / verify (0.3.0) Descarga: 100% Escritura de un archivo de bloqueo Generando archivos de carga automática

A continuación, ayuda a configurar un alias para codecepto usando su directorio compositor global:

$ composer global status Se cambió el directorio actual a /Users/Jeff/.composer No hay cambios locales 

Esto establece el alias:

$ alias codecept = "/ Users / Jeff / .composer / vendor / bin / codecept"

Yii también requiere que instales Faker, que genera datos de prueba falsos para tu aplicación:

$ composer require --dev yiisoft / yii2-faker: * ./composer.json se ha actualizado. Carga de repositorios de compositor con información del paquete. Dependencias de actualización (incluido require-dev) No hay nada que instalar ni actualizar. Generar archivos de carga automática

Configurando Codeception Con Su Aplicación

Codecept bootstrapInicializa la codecepción para tu aplicación Yii, creando una variedad de archivos de configuración para construir y ejecutar pruebas contra tu aplicación. Estamos utilizando la aplicación Hello de esta serie para este tutorial. Vea el enlace de GitHub en esta página para obtener el código.

$ codecept bootstrap Inicializando Codeception en / Users / Jeff / Sites / hello File codeception.yml created <- global configuration tests/unit created <- unit tests tests/unit.suite.yml written <- unit tests suite configuration tests/functional created <- functional tests tests/functional.suite.yml written <- functional tests suite configuration tests/acceptance created <- acceptance tests tests/acceptance.suite.yml written <- acceptance tests suite configuration tests/_output was added to .gitignore --- tests/_bootstrap.php written <- global bootstrap file Building initial Tester classes Building Actor classes for suites: acceptance, functional, unit -> AcceptanceTesterActions.php generó con éxito. 0 métodos agregados \ AcceptanceTester incluye módulos: PhpBrowser, \ Helper \ Acceptance AcceptanceTester.php creado. -> FunctionalTesterActions.php generado con éxito. 0 métodos agregados \ FunctionalTester incluye módulos: \ Helper \ Functional FunctionalTester.php creado. -> UnitTesterActions.php generado con éxito. 0 métodos agregados \ UnitTester incluye módulos: Asserts, \ Helper \ Unit UnitTester.php creados. Bootstrap está hecho. Echa un vistazo a / Users / Jeff / Sites / hello / tests directory

Por alguna razón, también terminé con directorios de prueba duplicados en hello / tests; simplemente borrando hola / pruebas / funcional, hola / pruebas / aceptación, y hola / pruebas / unidad aclaró todo. Todas las pruebas en vivo en hello / tests / codeception / *.

Los diferentes tipos de pruebas

La codecepción se centra en tres tipos de pruebas:

  1. La prueba de unidad verifica que las unidades específicas están funcionando, como una prueba exhaustiva de todos los métodos de su modelo.
  2. Las pruebas funcionales verifican escenarios de aplicaciones comunes como si un usuario los estuviera actuando, pero usando la emulación del navegador web.
  3. Las pruebas de aceptación son idénticas a las pruebas funcionales, pero en realidad las realizan a través de un navegador web.

Y admite tres tipos diferentes de formatos de prueba para su código de prueba:

  1. Cept: es el archivo de prueba de un solo escenario más simple
  2. Cest: un formato orientado a objetos para ejecutar múltiples pruebas dentro de un solo archivo
  3. Prueba: pruebas escritas en PHPUnit, un marco de prueba de PHP

Comencemos con un ejemplo de prueba de aceptacion utilizando formato cept:

Test de aceptación

Usaremos Codeception's Bienvenidoprimer ejemplo de prueba.

$ codecept generar: aceptación aceptada La prueba de bienvenida se creó en /Users/Jeff/Sites/hello/tests/acceptance/WelcomeCept.php

Esto genera pruebas / aceptación / WelcomeCept.php, que editaremos a continuación.

Debido a que las pruebas de aceptación requieren el navegador, tenemos que editar /tests/acceptance.suite.yml en nuestro proyecto para proporcionar nuestra URL de desarrollo, http: // localhost: 8888 / hello:

# Codeception Test Suite Configuration # # Suite para pruebas de aceptación. # Realice pruebas en el navegador usando WebDriver o PhpBrowser. # Si necesita las pruebas de WebDriver y PHPBrowser, cree una suite separada. class_name: AcceptanceTester modules: habilitado: - PhpBrowser: url: http: // localhost: 8888 / hello / - \ Helper \ Acceptance 

Ahora, estamos listos para modificar la prueba inicial en pruebas / aceptación / WelcomeCept.php. Estoy escribiendo una prueba que carga la primera página para asegurarme de que funciona como se espera. 

Las pruebas de codecepción tienen el concepto de actor, en este caso., $ I = nuevo AcceptanceTester ().

Así es como describe a los actores en la documentación de Codeception:

Tenemos un UnitTester, que ejecuta funciones y prueba el código. También tenemos un FunctionalTester, un probador calificado, que prueba la aplicación en su totalidad, con conocimiento de sus componentes internos. Y un AcceptanceTester, un usuario que trabaja con nuestra aplicación a través de una interfaz que proporcionamos.

Puedes comentar tus pruebas con código, como $ I-> wantTo ('realizar una cierta prueba')'Asegurar que la portada funcione'.

En mi prueba, quiero ver $ I-> ver texto para '¡Felicidades!' y 'Yii-powered':

wantTo ('asegurar que la portada funcione'); $ I-> amOnPage ('/'); $ I-> ver ('¡Felicidades!'); $ I-> ver ('Yii-powered'); 

Aquí está la página de inicio actual de Hello:

A continuación, vamos a ejecutar la prueba, simplemente ejecutar codecept:

$ codecept run Codeception PHP Testing Framework v2.1.11 Desarrollado por PHPUnit 5.3.5 por Sebastian Bergmann y colaboradores. Pruebas de aceptación (1) --------------------------------------------- ------------------------------------------ Asegúrese de que la portada funciona (WelcomeCept) Ok -------------------------------------------------- -------------------------------------------------- -------- Pruebas funcionales (0) ------------------------ ------------- -------------------------------- Pruebas unitarias (0) ------------- ----------------- --------------------------------- ------------ Tiempo: 554 ms, Memoria: 10.25MB OK (1 prueba, 2 aserciones)

Como puede ver, nuestra prueba pasó y el código para verificar esta funcionalidad fue bastante fácil de leer y leer..

Notas sobre las pruebas por defecto de Yii

Para ir más lejos, comencé a usar las pruebas predeterminadas de Yii. En este punto, me encontré con una serie de problemas de configuración, la mayoría debido a mi uso del módulo de usuario yii2 personalizado en esta serie. Otros se debieron a pequeños errores con Yii, a los que su equipo ha respondido y solucionado rápidamente cuando se informa sobre GitHub; en algunos casos, los problemas se solucionaron en versiones posteriores del árbol yii2-basic.

Además, debido a que había actualizado el árbol yii2-basic para esta serie, tuve que hacer pequeños cambios en algunas de las pruebas predeterminadas.

Este es un ejemplo del resultado para ejecutar las pruebas de aceptación predeterminadas una vez que hice algunos ajustes menores:

$ codecept run Codeception PHP Testing Framework v2.1.11 Desarrollado por PHPUnit 5.3.5 por Sebastian Bergmann y colaboradores. Pruebas de aceptación (4) --------------------------------------------- -------------------------------------------------- - Asegurarse de que funciona sobre (AboutCept) Ok Asegurarse de que funciona el contacto (ContactCept) Ok Asegurarse de que la página de inicio funciona (HomeCept) Ok Asegurarse de que el inicio de sesión funciona (LoginCept) Ok ----------------------------------------------------------------------------------------------------------------------

Pruebas funcionales

Para que las pruebas funcionales funcionaran, necesitaba ejecutar una instancia del servidor incorporado de Yii. No había sabido sobre este componente hasta que Alex Makarov de Yii lo mencionó en nuestro intercambio de GitHub.

$ ./yii servir

Hice pequeños cambios en las pruebas funcionales en / tests / codeception / function, principalmente para buscar mis cadenas de texto actualizadas específicas, es decir, "inicio de sesión o contraseña no válidos" en lugar de la configuración predeterminada de Yii. Aquí hay un vistazo a LoginCept.php:

wantTo ('asegurar que el inicio de sesión funcione'); $ loginPage = LoginPage :: openBy ($ I); $ I-> ver ('Iniciar sesión'); $ I-> amGoingTo ('intentar iniciar sesión con credenciales vacías'); $ loginPage-> login (","); $ I-> expectTo ('ver errores de validación'); $ I-> ver ('El inicio de sesión no puede estar en blanco'); $ I-> see ('La contraseña no puede estar en blanco'); $ I-> amGoingTo ('intentar iniciar sesión con credenciales incorrectas'); $ loginPage-> login ('admin', 'wrong'); $ I-> expectTo ('ver errores de validación'); $ I-> ver ('Nombre de usuario o contraseña no válido'); $ I-> amGoingTo ('intentar iniciar sesión con las credenciales correctas'); $ loginPage-> login ('admin', 'admin11'); $ I-> expectTo ('ver información del usuario'); $ I-> ver ('Cerrar sesión');

Básicamente, el código accede a la LoginForm Modela y prueba sus diversos métodos utilizando el servidor Yii..

Aquí está el código de prueba /tests/codeception_pages/LoginPage.php que está aprovechando (también tuve que modificarlo por los cambios que hemos realizado en la serie):

la clase LoginPage extiende BasePage public $ route = 'user / login'; / ** * @param string $ username * @param string $ password * / public function login ($ username, $ password) $ this-> actor-> fillField ('input [name = "login-form [login]" ] ', $ nombre de usuario); $ this-> actor-> fillField ('input [nombre = "login-form [contraseña]"]', $ contraseña); $ this-> actor-> click ('button [type = submit]');  

Se puede ver que estamos codificando el actor para campos de rellenohacer clic Botones para nuestros campos de formulario actualizados.. 

Mientras solucionaba problemas en mi integración de Codeception con Yii, encontré útil ejecutar estas pruebas en modo detallado:

$ codecept run -vvv

Aquí está la salida detallada de las pruebas funcionales de inicio de sesión en MacOS Terminal, PASADO y HA FALLADO Están codificados en color rojo o rosa e invertidos para mayor visibilidad:

Pruebas funcionales (4) --------------------------------------------- -------------------------------------------------- - Módulos: Sistema de archivos, Yii2 ... ------------------------------------------ -------------------------------------------------- -------------------------- Asegúrese de que el inicio de sesión funciona (LoginCept) Escenario: * Estoy en la página "/index-test.php/user/ login "[Page] /index-test.php/user/login [Response] 200 [Solicitar cookies] [] [Encabezados de respuesta] " tipo de contenido ": [" text / html; charset = UTF-8 "] * Veo "Iniciar sesión" * Voy a intentar iniciar sesión con las credenciales vacías * Relleno el campo "entrada [nombre =" inicio de sesión [iniciar sesión] "]", "" * Relleno el campo "entrada [nombre =" inicio de sesión -form [contraseña] "]", "" Hago clic en "botón [tipo = enviar]" [Uri] http: //localhost/index-test.php/user/login [Método] POST [Parámetros] "_csrf ":" VEpvcmk3bVgFH1Y9AVsmYWQQDEouTSggYXMFGStdKBEnCyQfBxo8Bw == "," login-form [login] ":" "," login-form [password] ":" " [Page] http: //localhost/test.php.pdf [Respuesta] 200 [Solicitar cookies] "_csrf": "dd395a9e5e3c08 cfb1615dae5fc7b5ba0a2025c003e430ba0139b300f4a917ada: 2: i: 0; s: 5: "_ csrf"; i: 1:: ½ ; charset = UTF-8 "] * Espero ver errores de validación * Veo" El inicio de sesión no puede estar en blanco ". * Veo" La contraseña no puede estar en blanco ". * Voy a intentar iniciar sesión con las credenciales incorrectas * Relleno el campo "input [name =" login-form [login] "]", "admin" * Relleno el campo "input [name =" login-form [password] "]", "incorrecto" * Hago clic en el botón "[type = enviar] "[Uri A M Method http http http Method Method Method Method Method Method Method Method Method Method Method Method Method Method Method Method Method Method POS POS POS POS POS POS POS r r r r r r r r r r r r r r r r r r r r r r r r r r r r r" "," login-form [contraseña] ":" incorrecto " [Página] http: //localhost/index-test.php/user/login [Respuesta] 200 [Peticiones de cookies] " _csrf ":" dd395a9epaciente de las partes de las doscayas de lascuchas de las gavillas en las costillas de los animales. : i: 0; s: 5: "_ csrf"; i: 1; s: 32: "QU9OhlK90Zc8GzEx59jkBjEIsAKmn-Q_"; " [Encabezados de respuesta] " tipo de contenido ": [" text / html; charset = UTF-8 "] * Espero ver errores de validación * Veo" Nombre de usuario o contraseña no válidos "* Voy a intentar iniciar sesión con las credenciales correctas * Relleno el campo" entrada [nombre = "formulario de inicio de sesión [inicio de sesión ] "]", "admin" * Relleno el campo "input [name =" login-form [password] "]", "admin11" * Presiono el botón "[type = submit]" [Uri] http: // localhost /index-test.php/user/login [Método] POST [Parameters] "_csrf": "bG8uMXdPYk49Ohd.HyMpd1w1TQkwNSN2WVZEWjUlJwcfLMVcGWIzEQ = ex. '' '' '' '' '' '' '' '' '' '' '' ":" admin11 " [Headers] " location ": [" http: //localhost/index-test.php "]," content-type ": [" text / html; charset = UTF-8 "] [Page] http: //localhost/index-test.php/user/login [Response] 302 [Cookies de solicitud] " _csrf ":" dd395a9e5e3cpcggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggbb. : 5: "_ csrf"; i: 1; s: 32: "QU9OhlK90Zc8GzEx59jkBjEIsAKmn-Q_"; " [Encabezados de respuesta] " location ": [" http: //localhost/index-test.php "]," tipo de contenido ": [" text / html; charset = UTF-8 "] [Redirigiendo a] http: //localhost/index-test.php [Page] http: //localhost/index-test.php [Response] 200 [Request Cookies] " _csrf ": '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' s '' '' '' '' '' '' '' '' '' '' '' '' '' '' s '' '' html; charset = UTF-8 "] * Espero ver información del usuario * Veo" Cerrar sesión "PASADO 

En general, hay un poco que aprender para comenzar a usar Codeception y codificar correctamente sus pruebas. Pero los resultados son impresionantes y útiles..

Examen de la unidad

Básicamente, las pruebas unitarias son pruebas programáticas de nuestra infraestructura y modelos. Lo ideal sería escribir pruebas para cada método y variación de uso de nuestros modelos..

Desafortunadamente, no pude hacer que las pruebas unitarias funcionaran dentro de nuestro árbol debido a los pequeños errores de Yii que aún no se han lanzado o los problemas de configuración entre Codeception y yii2-user, que integramos en Cómo programar con Yii2: Integración del registro de usuarios. 

Pruebas unitarias (3) --------------------------------------------- -------------------------------------------------- ----- Módulos: ------------------------------------------- -------------------------------------------------- ---------------------- Intentando probar el inicio de sesión de ningún usuario (tests \ codeception \ unit \ models \ LoginFormTest :: testLoginNoUser) ... 
Error fatal de PHP 'yii \ base \ ErrorException' con el mensaje 'Llamada a pruebas de función no definidas \ codeception \ unit \ models \ expect ()' 

Me ocuparé de las pruebas de unidad nuevamente en nuestra serie de Inicio, que no usa yii2-user, sino que utiliza la integración de usuarios integrada en el árbol Yii Advanced..

Veamos un par de ejemplos del árbol Yii2-app-basic.

Pruebas de correo electrónico de formulario de contacto

Las pruebas hello / tests / codeception / unit / models / ContactFormTest.php envían un correo electrónico mediante el uso programático de modelos:

mailer-> fileTransportCallback = function ($ mailer, $ message) return 'testing_message.eml'; ;  función protegida tearDown () unlink ($ this-> getMessageFile ()); padre :: tearDown ();  función pública testContact () $ model = $ this-> createMock ('app \ models \ ContactForm', ['validate']); $ model-> expects ($ this-> once ()) -> method ('validate') -> will ($ this-> returnValue (true)); $ model-> attributes = ['name' => 'Tester', 'email' => '[email protected]', 'subject' => 'letter letter subject', 'body' => 'body of current mensaje ',]; $ model-> contact ('[email protected] '); $ this-> especificar ('el correo electrónico debería enviarse', función () esperar ('el archivo del correo electrónico debería existir', file_exists ($ this-> getMessageFile ())) -> true ();); $ this-> especificar ('el mensaje debe contener datos correctos', función () use ($ model) $ emailMessage = file_get_contents ($ this-> getMessageFile ()); expect ('email debe contener nombre de usuario', $ emailMessage) -> contiene ($ modelo-> nombre); expect ('el correo electrónico debe contener el correo electrónico del remitente', $ emailMessage) -> contiene ($ modelo-> correo electrónico); expect ((el correo electrónico debe contener el asunto ', $ emailMessage) -> contiene ($ model-> subject); expect ('el correo electrónico debe contener cuerpo', $ emailMessage) -> contiene ($ modelo-> cuerpo););  función privada getMessageFile () return Yii :: getAlias ​​(Yii :: $ app-> mailer-> fileTransportPath). '/testing_message.eml';  

No pude lograr que esta prueba se aprobara debido a un pequeño error en Yii que aún no se ha actualizado (o al menos no pude encontrar el código actualizado). Mi gota de la base de código de Yii fue nombrar correos electrónicos salientes con sellos de fecha y el código de arriba buscaba un nombre de archivo fijo. Por lo tanto, siempre falló. Aún así, es útil ver cómo las pruebas programáticas pueden usar modelos para generar un archivo y luego buscar ese archivo y validar su contenido para verificar que el código funciona..

Ingreso de prueba

Veamos hello / tests / codeception / unit / models / LoginFormTest.php. Nuevamente, mi uso de yii2-user hizo que fuera muy difícil de integrar al momento de escribir este tutorial; Sin embargo, podemos observar el enfoque conceptual de las funciones del modelo de usuario de pruebas unitarias..

Aquí está testLoginCorrect (), que mira para ver si el inicio de sesión se realiza correctamente con una contraseña correcta:

función pública testLoginCorrect () $ model = new LoginForm (['username' => 'admin', 'password' => 'admin11',]); $ this-> especifique ('el usuario debe poder iniciar sesión con las credenciales correctas', función () use ($ model) expect ('el modelo debe iniciar sesión el usuario', $ model-> login ()) -> true (); expect ("el mensaje de error no debe establecerse", $ model-> errors) -> hasntKey ('password'); expect ("el usuario debe estar conectado", Yii :: $ app-> user-> isGuest) -> falso ();); 

Utiliza el LoginForm modelo para iniciar sesión programáticamente en el usuario, y luego busca programáticamente para ver si el usuario actual de Yii ya no es un invitado.

expect ("el usuario debe iniciar sesión", Yii :: $ app-> usuario-> isGuest) -> false ();

Que sigue?

Espero que hayas disfrutado aprendiendo sobre Codeception y su integración con Yii, a pesar de algunos de los obstáculos que encontré. La instalación predeterminada de yii2-basic hoy debería funcionar mejor.

Si desea obtener más información sobre cómo decidir cuándo y qué realizar la prueba y por qué, le recomiendo leer la Descripción general de las pruebas de Yii. Ciertamente hay más para aprender sobre Codeception y escribir pruebas más completas.

Vea los próximos tutoriales en nuestra serie Programming With Yii2 a medida que continuamos explorando diferentes aspectos del marco. Si quieres saber cuándo llegará el próximo tutorial de Yii2, sígueme @reifman en Twitter o visita la página de mi instructor. 

También puede consultar nuestra serie Construyendo su inicio con PHP, que utiliza la plantilla avanzada de Yii2 mientras construimos una aplicación del mundo real. De hecho, puede probar la aplicación de inicio, Meeting Planner, hoy.

enlaces relacionados

  • Codecepción
  • Yii2 Developer Exchange, mi sitio de recursos Yii2
  • Configuración del entorno de prueba Yii2