php
LEMP VPS | Guía Completa
Symfony 2 CRUD | Entidades
En este capítulo comenzaremos a preparar nuestra aplicación, para que podamos interactuar con la base de datos através de lo que se conoce en Symfony, como Entidades y Modelo de datos.
Gracias a que hemos optado por utilizar Lando, ver o modificar los detalles de conexión con nuestra base de datos es bastante sencillo, podemos verlo en el archivo de configuración de lando, .lando.yml, donde encontraremos rápidamente la siguiente configuración:
services: phpmyadmin: type: phpmyadmin hosts: - symfony2.symfony2app.internal symfony2: type: mariadb portforward: true creds: user: symfony2 password: symfony2 database: symfony2
Como puedes ver, además del acceso a la herramienta PhpMyAdmin, con la cual podrás manipular tus tablas y base de datos, mediante interfaz gráfica; tienes también el nombre tipo de motor de base de datos mariadb y los detalles para el usuario, clave y base de datos.
Pero si lo prefieres, también podrás ver toda la información relacionada con la base de datos, ejecutando el comando siguiente:
lando info
El resultado será parecido a la siguiente imagen:
Para que podamos conectar nuestra aplicación de Symfony, con esta base de datos, tendremos que modificar el archivo parameters.yml, que se encuentra en la ubicación app/config/parameters.yml
En realidad, este archivo se puede configurar automáticamente, cuando comenzamos con la instalación de nuestra aplicación de Symfony, pero hemos preferido dejarlo para este momento, ya que tendría más sentido mecionarlo, ahora que trabajaremos con las entidades y los datos.
En el caso de que no tuviéramos creada la base de datos para nuestra aplicación, sólo necesitaríamos ejecutar el siguiente comando para que Symfony se encargara de hacerlo por nosotros (Recuerda que trabajamos con Lando, por eso hemos añadido la palabra al principio del comando):
lando php app/console doctrine:database:create
Pero como nosotros ya teníamos la base de datos creada desde el principio, lo que tendremos que hacer es decirle a Symfony que la borre y luego vuelva a configurarla, y así podremos interactuar con ella.
lando php app/console doctrine:database:drop --force
Así, podremos volver a crear nuestra base de datos con el siguiente comando:
lando php app/console doctrine:database:create
Ahora, para trabajar con nuestro modelo de datos (blog de noticias), tendremos que crear algo llamado Entidad. Esta es básicamente una clase de PHP que define toda la información sobre nuestras páginas de noticias. Symfony tiene una ingeniosa herramienta de línea de comandos para esto que usaremos y otra buena para crear las tablas de base de datos reales que coincidan con este modelo de datos.
Para generar nuestra entidad, a la que llamaremos noticia, vamos a ejecutar el siguiente comando de Symfony 2, con la ayuda de Lando:
lando php app/console doctrine:generate:entity
Al igual que nos pasó cuando generamos el Bundle, Symfony nos presentará en pantalla una serie de preguntas relacionadas con nuestra entidad, que debermos ir completando hasta terminar el proceso; sin en algún punto de la generación de la entidad nos equivocamos, podremos hacer clic en la combinación de las teclas Ctrl + C y podremos comenzar nuevamente desde cero.
En nuestro ejemplo, la entidad tendrás los siguientes campos y se guardará dentro de nuestro Bundle, por eso, en la primera pregunda, para el shortcut o atajo, escribiremos el nombre del bundle seguido de dos puntos y luego el nombre para nuestra entidad. Ej.: NewsBundle:News, el resto de la información será la siguiente:
Una vez terminado el proceso, podremos echarle un vistazo a nuestra entidad, ubicada dentro de nuestro bundle, en la carpeta Entity, con el nombre News.php, su aspecto será como la siguiente imagen:
En este momento, ya estamos listos para que Symfony se encargue de generar la tabla equivalente, con los datos de nuestra entidad, para ello, ejecutaremos el siguiente código en la consola:
lando php app/console doctrine:schema:update --force
Como sólo tendremos una entidad, el proceso Symfony tardará muy poco en crear nuestra tabla y mostrarnos en pantalla el mensaje de confirmación, indicándonos el resultado:
Gracias a Lando, podremos verificar los datos de nuestra tabla, accediendo a PhpMyAdmin, para ello, si no recuerdas la url, sólo tendremos que escribir el comando de información de lando:
lando info
Y buscar la url que nos permitirá acceder a la interfaz gráfica de PhpMyAdmin:
Dentro de PhpMyAdmin, podrás comprobar, que han sido generados correctamente, la tabla News y sus respectivos campos, coincidiendo con el modelo que hemos planteado en nuestra Entidad.
Bundle - Creación y personalización
Los datos con los que trabajaremos son páginas de un Blog de noticias. Crearemos una entidad (que sirve como nuestro modelo de datos para las páginas del blog) y aprenderemos a leerla y mostrarla. Durante todo el curso, aprenderemos cómo realizar las otras operaciones, es decir, agregar, actualizar y eliminar las páginas de noticias. Pero primero, necesitaremos crear un Bundle o paquete.
En symfony un Bandle es el equivalente a los conocidos como Plugins en otras aplicaciones. La diferencia principal con respecto a estos, es que dentro de un Bundle de Symfony podremos encontrar, tanto la funcionalidad del propio Framework central, como el código escrito para nuestra aplicación personalizada. Esto le brinda la flexibilidad de usar funciones preconstruidas empaquetadas en paquetes de terceros o para distribuir sus propios paquetes. Hace que sea fácil seleccionar y elegir qué funciones habilitar en su aplicación y optimizarlas de la manera que desee.
Un Bundle o paquete en Symfony, es un directorio donde guardas todos los archivos necesarios, para una funcionalidad específica en tu aplicación. En esta pequeña aplicación donde configuraremos para nuestro Modelo de datos, las operaciones básicas que implican un CRUD (Create, Read, Update, Delete ), necesitaremos crear un Bundle, antes de poder generar las entidades que nos ayudarán con los datos.
Para generar un Bundle, nos colocaremos en la carpeta raiz de nuestra aplicación y ejecutaremos el siguiente código en consola, y dejaremos que Symfony 2 haga el trabajo por nosotros, como estamos trabajando con Lando, añadiremos lando, como parte del comando:
lando php app/console generate:bundle
Entonces veremos en consola, el mensaje de bienvenida de symfony al sistema para generar nuestro Bundle:
En este ejemplo, he decidido añadir los siguientes datos, pero puedes cambiarlos por los tuyos, en cuanto aprendas a trabajar con la generación de un Bundle:
Bundle name: NewsBundle
Target Directory [src/]: yes
Configuration format (annotation, yml, xml, php) [annotation]: yes
Al finalizar, veremos un mensaje de confirmación, y a la vez uno de error, ya que en esta versión de Symfony 2, tendremos que añadir manualemente una línea, dentro de nuestro archivo composer.json y a continuación ejecutar nuevamente el comando de composer update, en este caso utilizando LANDO:
Una vez añadida la línea con el nombre de nuestro NewsBundle, que es el que usamos para el ejercicio, ejecutaremos en pantalla el comando que permitirá a Composer actualizar en Syfmony nuestro Bundle.
lando composer update
Al terminar la actualización de Composer, deberíamos ver un mensaje de confirmación, parecido al siguiente:
Comprobación de que el NewsBundle funciona
En este caso, el NewsBundle, que acabamos de generar, nos permitierá acceder a una página con el mensaje por defecto que viene en el Twig, generada por Symfony 2.
Para comprobarlo, primero abriremos el archivo DefaaultController.php, donde podremos comprobar la URL para nuestra página, en el apartado de las anotaciones, (Los comentarios que se muestran justo encima de la función).
Podemos coprobar que nuestro nuevo NewsBundle funciona correctamente, accediendo a la url de desarrollo:
http://symfony2-app.lndo.site/app_dev.php
Dónde se encuentra esta plantilla que vemos en pantalla?
Para encontrar desde dónde se está imprimiendo este mensaje en pantalla, tendremos que abrir el archivo index.html.twig, que es la plantilla twig, llamada desde el controlador.
Symfony 2 | Instalación con Lando
Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI
A pesar de que en la actualidad, todas las aplicaciones y lenguajes de programación, siguen evolucionado para mejorar sus características y funcionalidades, relacionadas sobretodo, con la seguridad o escalabilidad; facilitándonos cada vez más, las tareas de desarrollo e implementación, en cualquier proyecto o aplicación.
En la vida real, nos encontramos con una gran cantidad de empresas, que se resisten a dicha evolución y pretenden continuar con versiones obsoletas e inseguras, en lugar de invertir tiempo y dinero en su actualización.
Muchos de los casos con los que me he encontrado, a lo largo de estos últimos meses, tienen relación con proyectos desarrollados, utilizando el framework PHP, Symfony, que actualmente ha lanzado la versión 6, pero en lugar de utilizar ésta, la mayoría funciona todavía con la versión Symonfy 2.
Por esta razón, he decidido compartir una guía rápida, para que puedas configurar un entorno local, utilizando Lando, en lugar de hacerlo con Docker puro, que suele ser un poco más complejo, para tus proyectos de Symfony 2.
Instalación de Symfony 2 utilizando Lando
Incompatibilidades:
Lo primero que debes tener en cuenta, son las posibles incompatibilidades con las que te encontrarás, ya que Symfony 2 funciona correctamente, sólo con las versiones PHP 5.3 hasta la 7.2, a partir de entonces experimentarás diversos fallos.
Symfony 2, tampoco funciona con las versiones actuales de Composer, por lo que en caso de que estés tratando de instalar un proyecto de Symfony 2, deberás utilizar versiones anteriores a la 2.0
Paso 1 - Instalar el lando
Si todavía no lo haz instalado, puedes ver el video y leer las instrucciones HAZ CLIC AQUÍ
git clone https://github.com/drupaladicto/symfony2-lando.git
Paso 2 - Descargar las actualizaciones de Symfony
Para ello, nos moveremos dentro de la carpeta del proyecto y ejecutaremos el comando para que comience a funcionar Lando:
lando start
A continuación, ejectuaremos el comando de Composer, para comenzar con la descargas de las dependencias de Symfony 2
lando composer update
Paso 3 - Acceder a la página de bienvenida de Symfony
Para acceder a la página de bienenida de Symfony2, añadiremos a la url /app_dev.php:
http://symfony2-app.lndo.site/app_dev.php
Detalles de la instalación:
El proyecto incluye un archivo de configuración para lando que activará, La versión 1.10.1 de Composer y PHP 7.2, para evitar errores de compatibilidad en esta versión Obsoleta de Symfony, además de PhpMyAdmin con una base de datos completamente configurable:
name: symfony2-app recipe: symfony config: php: 7.2 webroot: web composer_version: '1.10.1' services: phpmyadmin: type: phpmyadmin hosts: - symfony2.symfony2app.internal symfony2: type: mariadb portforward: true creds: user: symfony2 password: symfony2 database: symfony2
Guardaremos los cambios y continuaremos con el siguiente paso.
Descarga de las dependencias
Una vez descargados los archivo del repositorio, necesitarás ejecutar el comando de composer para que terminen de descargarse todas las dependencias de Symfony definida en el archivo composer.json. Para ello el comando que deberás utilizar es el siguiente:
lando composer update
Desactivación de las comprobaciones en el navegador
Cuando realizamso una instalación de Symfony 2, tendremos que realizar un pequeña modificación en dos archivos (app_dev.php y config.php), se trata de un trozo de código que se encarga de comprobar los accesos de las ips en entornos locales, pero que podremos modificar ya que estaremos trabajando en nuestro ordenador.
Antes de realizar ningún cambio más, vamos a comprobarlo. Arrancaremos el proyecto, ejecutando el comando de lando:
lando rebuild
Posibles Fallos
Según la documentaicón oficial de esta versión, podremos comprobar si nos falta algo en la configuración inicial del proyecto, accediendo a la url http://nuestrositio/config.php, pero debido a la comprobación del navegador dentro de este mismo arhivo, es posible que veamos un error en pantalla como el siguiente:
Ahora que estamos seguros de que no funciona, vamos a ejecutar los cambios necesarios para continuar.
Config.php
El primer archivo que deberíamos corregir y ejecutar, tan pronto arranque nuestro proyecto es config.php y nos confirmará si todo ha ido bien en la instalación del proyecto.
Está ubicado en '/web/config.php' y las líneas que tenemos que comentar, para no tener que borrarlas, están al principio del archivo, son las siguientes:
<?php if (!isset($_SERVER['HTTP_HOST'])) { exit('This script cannot be run from the CLI. Run it from a browser.'); } if (!in_array(@$_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1', ))) { header('HTTP/1.0 403 Forbidden'); exit('This script is only accessible from localhost.'); }
Una vez realizado el cambio, si ejecutamos el comando lando rebuild y accedemos a la url http://proyecto.lndo.site/config.php, deberíamos ver que todo funciona correctamente:
app_dev.php
El próximo arhivo está ubicado, al igual que el anterior, dentro de la carpeta '/web/app_dev.php', es el que nos muestra la pantalla de bienvenida de Symfony 2, al acceder a la url http://proyecto.lndo.site/app_dev.php. En este caso, las líneas que tendremos que comentar son las siguientes:
// This check prevents access to debug front controllers that are deployed by accident to production servers. // Feel free to remove this, extend it, or make something more sophisticated. if (isset($_SERVER['HTTP_CLIENT_IP']) || isset($_SERVER['HTTP_X_FORWARDED_FOR']) || !in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1','fe80::1', '::1')) ) { header('HTTP/1.0 403 Forbidden'); exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.'); }
En este caso, la pantalla que deberíamos ver una vez realizados los cambios y ejecutado el comando lando rebuild, sería la siguiente:
Trabajando con un proyecto Symfony 2 existente
En el caso de que necesites trabajar en tu entorno local, con un proyecto desarrollado en Symfony 2, sólo sería necesario que tuvieras instalado lando en tu ordenador y una vez añadido el archivo de configuración .lando.yml, arrancar el servidor y ajustar los detalles de urls.
Si quieres saber más sobre Symfony 2, visita su Documentación Oficial de Symfony 2
Solución de problemas: HAZ CLIC AQUÍ
Symfony 2 CRUD | Introducción
Symfony 2 | Introducción
Symfony es un framework PHP que nos permite muy fácilmente utilizar la arquitectura MVC (Model-View-Controller). Fue escrito desde un origen para ser utilizado sobre la versión 5 de PHP ya que hace ampliamente uso de la orientación a objetos que caracteriza a esta versión y desde la versión 2 de Symfony se necesita mínimamente PHP 5.3.3.
[tipexperto titulo = “Nota”]Esta guía está actualizada para utilizar la versión 2.2 de Symfony ya que desde esta versión se crearon muchas mejoras.[/tipexperto]
Symfony Fue creado por una gran comunidad liderada por Fabien Potencier, quién a la fecha, sigue al frente de este proyecto con una visión muy fuertemente orientada hacia las mejores prácticas que hoy en día forman parte del estándar de desarrollo de software.
Por más que Symfony puede ser utilizado para otros tipos de desarrollos no orientados a la Web, fue diseñado para optimizar el desarrollo de aplicaciones Web, proporcionando herramientas para agilizar aplicaciones complejas y guiando al desarrollador a acostumbrarse al orden y buenas prácticas dentro del proyecto.
El concepto de Symfony es no reinventar la rueda, por lo que reutiliza conceptos y desarrollos exitosos de terceros y los integra como librerías para ser utilizados por nosotros. Entre ellos encontramos que integra plenamente uno de los frameworks ORM más importantes dentro de los existentes para PHP llamado Doctrine, el cual es el encargado de la comunicación con la base de datos, permitiendo un control casi total de los datos sin importar si estamos hablando de MySQL, PostgreSQL, SQL server, Oracle, entre otros motores ya que la mayoría de las setencias SQL no son generadas por el programador sino por el mismo Doctrine.
Fuente: http://www.maestrosdelweb.com/curso-symfony2-introduccion-instalacion/
Symfony 2 | CRUD (Create - Read - Update - Delete)
Contenidos programáticamente | Creación en Drupal 9
Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI
A lo largo de los años, Drupal ha ganado la inmerecida fama de que es un CMS muy complejo y difícil de aprender, pero en realidad, todo dependerá de tu capacidad para experimentar con nuevas herramientas y tu actitud de superar cualquier reto que se te presente; verás que no resulta tan complicado, si dedicas el tiempo necesario y tienes la suficiente paciencia contigo.
Si todavía no lo conoces, te animo a que empieces desde hoy mismo con este curso gratis de Drupal 9 paso a paso en español y en un par de semanas te llevarás la grata sorpresa de lo mucho que puedes lograr si pones verdadero empeño.
LO QUE NECESITAS ANTES DE EMPEZAR CON ESTE EJERCICIO:
- Tener Drupal funcionando ya sea con un servidor local tipo Xampp o con contenedores de Docker.
- Haber instalado al menos estos dos módulos esenciales Backup and Migrate y Admin Toolbar
- (Opcional) Conocimientos básicos sobre Cómo crear un módulo personalizado
Una vez hayas terminado de configurar todo lo anterior y te sientas con todas las ganas para comenzar, el próximo paso sería hacer tu primera copia de seguridad; de esta forma, te asegurarás de que puedes recuperar la última versión estable de tu desarrollo si hubiera cualquier tipo de fallo durante el proceso.
Así que, para crear esta primera copia de nuestra base de datos estable, nos iremos a la ventana del módulo Backup and migrate usando la siguiente ruta en el navegador o mediante los botones del menú superior "/admin/config/development/backup_migrate" y crearemos la primera copia estable.
Tan pronto como veamos el mensaje de confirmación de que se ha realizado la copia correctamente, nos toca continuar con el proceso de creación del tipo de contenido y posteriormente su colocación en un módulo personalizado, para que podamos reutilizarlo en cualquier otro proyecto o que nos sirva de base para contenidos más complejos.
PASO 1 CREACIÓN DEL TIPO DE CONTENIDO:
Empezaremos con el proceso de crear nuestro tipo de contenido, añadiéndole los campos correspondientes, funcionalidades y estructura. Es importante que tengas muy claro si tu contenido tendrá dependencias de otros contenidos como vocabularios, referencias a otros contenidos o formularios, etc. La idea es que tu tipo de contenido, tal y como lo definas esté disponible para cualquier otra web de Drupal 8 o 9 o que te sirva como punto de partida para desarrollar otros contenidos más complejos partiendo de una base predefinida.
En este ejercicio, vamos a crear un tipo de contenido llamado "Servicio", al que añadiremos dos campos ( Imagen servicio y Descripción del servicio ), de esta forma podrás apreciar mejor todos los elementos relacionados según el tipo de campo que prefieras emplear.
PASO 2 CREACIÓN DEL MÓDULO PERSONALIZADO:
Básicamente, vamos a crear una carpeta con el nombre de nuestro módulo, y la colocaremos dentro de la carpeta "modules/custom", para mantener mejor ordenado el desarrollo de nuestra web. Te recomiendo que utilices el mismo nombre que tendrá tu tipo de contenido y luego añadiremos el archivo "TUMODULO.info.yml", que es necesario para que Drupal lo reconozca como módulo, acompañado de dos carpetas adicionales "config" + "install", donde tendremos que colocar todos los demás archivos relacionados con la definición de nuestro contenido.
PASO 3 EXPORTACIÓN Y CREACIÓN DE ARCHIVOS:
Aquí es donde viene la novedad y verdadera ventaja, de utilizar este método para la creación de tus contenidos en un módulo personalizado, en lugar de tener que programar todo desde cero, disminuyendo así considerablemente la generación de errores e investigación de posibles fallos de estructura y ejecución, como en versiones anteriores de Drupal.
La idea consiste en utilizar la exportación de configuración, incluida en la interfaz de usuario a partir de Drupal 8, para no tener que memorizar un montón de líneas de código, tabulaciones específicas y otras características obligatorias. Haciendo que tus desarrollos puedan ponerse en marcha en el menor tiempo posible.
Como en cualquier desarrollo, la clave está en los detalles. Debes prestar mucha atención de no saltarte ningún paso del procedimiento, durante la creación y todo saldrá según lo que esperas.
LO QUE SIEMPRE DEBES VERIFICAR:
1.- El tipo de contenido: El primer archivo que debes añadir a tu módulo, siempre dentro de la carpeta "config/install" es el que define tu tipo de contenido, por ejemplo, el desplegable te mostrará todos los elementos disponibles, si tu contenido a exportar es un nodo, debes elegir "Tipo de contenido" o "Content Type", pero también podrías exportar cualquier otro elemento, por lo tanto, podrás usar "Tipo de parrafo" o "Paragraphs Type", "Bloque personalizado" o "Custom Block", etc.
El proceso siempre debería ser igual, primero creas el archivo con el nombre sugerido en la parte inferior de la ventana de exportación y lo guardas en la dentro de la carpeta "config/install" de tu módulo personalizado.
A continuación, como sugerencia, en la primera línea de cada archivo, pega el nombre sugerido como comentario, o sea, poniéndole una almohadilla delante, de esta forma ayudarás a Drupal a identificar el archivo y a ti de guía para confirmar si haz cambiado el nombre del archivo por error.
Por último, copia todo el código que está justo debajo del UUID en la interfaz y pégalo en cada uno de tus archivos, dejando algo de espacio a partir del comentario que haz pegado al principio.
2.- Todos los contenidos tienen obligatoriamente tres archivos fundamentales:
- - core.entity_form_display.node.servicio.default.yml: Que define el formulario que se utilizará para crear el contenido.
- - core.entity_view_display.node.servicio.default.yml: Que define la forma de presentación del contenido.
- - node.type.servicio.yml: Define el tipo de contenido.
El resto de archivos que formarán tu módulo, serán los campos que vienen por defecto o que han sido creados por ti, como taxonomías, patrones de url, campos referenciados a otros contenidos, etc.
3.- Cada campo tiene dos archivos uno que define sus propiedades específicas, empieza por "field.field", ejemplo "field.field.node.servicio.field_descripcion_del_servicio.yml" y otro que define la manera en que serán guardados los datos, empieza por "field.storage", ejemeplo "field.storage.node.field_descripcion_del_servicio.yml"
Por lo tanto al crear el archivo para cada campo asegúrate de hacerlo con sus correspondencias, antes de pasar a los archivos del siguiente campo, así tendrás más control si quieres modificar los nombres que crea Drupal a los campos por defecto y evitas errores por falta de algún archivo equivalente.
4.- No olvides añadir dependencias. Siempre que vayas a crear contenidos siguiendo este método, añade al menos una dependencia en el archivo info.yml de tu módulo, eso facilitará que te acostumbres mejor a la estructura de creación de este archivo.
PHPUnit en Drupal 8 | Prueba del navegador
En este tutorial abarcaremos los conceptos básicos de las pruebas del navegador PHPUnit en Drupal 9. ¡Al final, deberías poder escribir tu primera prueba del navegador!
Para este ejemplo, usaremos el módulo Rules, ya que podemos incluir algunas pruebas funcionales del navegador. Luego, el tutorial explicará cómo probar la interfaz de usuario de Rules, para asegurarse de que funcione correctamente.
Prerrequisitos:
Una instalación de Drupal 8 funcionando:
- Cómo instalar cualquier versión Drupal 8 usando Composer
- Cómo Instalar LAMP usando WSL2 en Windows 10 (1era Parte)
Composer instalado:
- Cómo instalar Composer 2 en Ubuntu 20.04
Módulos instalados:
Rules, Admin Toolbar, Pathauto
Configuración para el tutorial
Primero, necesitaremos asegurarnos de que el módulo Rules esté instalado (descárguelo y agréguelo a su carpeta de módulos). PHPUnit es parte de las dependencias de Composer del núcleo de Drupal, así que asegúrese de haber ejecutado la instalación de composer en tu Drupal 8. Familiarícese con la ejecución de pruebas PHPUnit y asegúrese de habilitar BROWSERTEST_OUTPUT_DIRECTORY e printerClass en su archivo phpunit.xml como se explica en esa página.
¿Qué debería probar con BrowserTestBase?
BrowserTestBase le ofrece una forma de probar comportamientos e interacciones basados en la web. Por ejemplo, si desea verificar que se requiere un determinado permiso antes de que un usuario pueda visitar una determinada página, debe crear un usuario sin ese permiso e intentar visitar la página, y luego comparar el resultado con otro intento con ese permiso.
BrowserTestBase satisface la necesidad de realizar pruebas de alto nivel basadas en solicitudes de integraciones entre varios subsistemas en Drupal. Por lo general, las pruebas de BrowserTestBase no deberían requerir temas o configuración específicos del sitio, aunque es posible escribir pruebas con esos requisitos. Otras herramientas como Behat podrían usarse para pruebas de comportamiento específicas del sitio.
Finalmente, BrowserTestBase reemplaza el WebTestBase heredado basado en Simpletest. Si está migrando desde Simpletest de Drupal, le resultará relativamente fácil convertir las pruebas de WebTestBase a BrowserTestBase.
Cómo funcionan las pruebas del navegador de Drupal
La mayor parte de Drupal es una funcionalidad orientada a la web, por lo que es importante tener una forma de ejercitar estas funciones. Las pruebas del navegador crean una instalación completa de Drupal y un navegador web virtual y luego usa el navegador web virtual para guiar la instalación de Drupal a través de una serie de pruebas, tal como lo haría si lo estuviera haciendo a mano.
Acerca del escenario de prueba del módulo Rules
El módulo Reglas proporciona una interfaz de usuario para los administradores donde pueden crear reglas. Consiste en múltiples páginas y formularios que queremos probar, los cuales están protegidos con permisos de usuario para que solo los administradores puedan acceder a ellos. El escenario de prueba más simple está en rules/tests/src/Functional/UiPageTest.php.
Descubriendo lo que necesitamos probar
Si instala el módulo Reglas, puede seguir manualmente los pasos y ver lo que cree que debe probarse. Si todavia no haz trabajado con Rules, te enseño todo lo que necesitas asaber en este artículo Cómo crear nuestra primera regla con Rules
Visite Configuración> Flujo de trabajo> Reglas donde debería ver una página que dice "Aún no hay una regla de reacción". en la tabla de reglas. Puede agregar reglas y configurarlas, pero como primer paso, queremos probar que esta página de descripción general del administrador realmente existe y dice que aún no hay reglas.
Escribir un archivo de prueba
Ahora es el momento de crear nuestras pruebas, que haremos en la carpeta rules / tests / src / Functional. PHPUnit encontrará automáticamente los archivos de prueba del navegador en la carpeta tests / src / Functional de un módulo.
Hay cuatro pasos básicos involucrados en la creación de una prueba:
- Crear la estructura (simplemente crear una clase que herede de \ Drupal \ Tests \ BrowserTestBase o una clase de prueba de navegador similar)
- Inicializar el caso de prueba con cualquier creación o configuración de usuario que deba realizarse
- Crear pruebas reales dentro del caso de prueba
- Y, por supuesto, intentar desesperadamente averiguar por qué nuestra prueba no funciona de la manera que esperamos y depurar la prueba (y quizás el módulo)
Para empezar con la creación de nuestro archivo de pruebas, necesitaremos extender la clase BrowserTestBase.
namespace Drupal\Tests\rules\Functional; use Drupal\Tests\BrowserTestBase; /** * Tests that the Rules UI pages are reachable. * * @group rules_ui */ class UiPageTest extends BrowserTestBase {
Como siguiente paso, debemos especificar la lista de módulos que deben habilitarse para la ejecución de prueba. En nuestro caso, esto es, por supuesto, las Rules.
/** * Modules to enable. * * @var array */ protected static $modules = ['node', 'rules'];
Luego viene el setUp() opcional . Aquí es donde debemos hacer todo lo que sea necesario para que esta instancia de Drupal funcione como queremos. Tenemos que pensar: "¿Qué tuve que hacer para pasar de una instalación de Drupal de stock a donde puedo ejecutar esta prueba?". No todos los casos de prueba necesitarán esto, pero aquí hay un ejemplo en el que preparamos un tipo de contenido (tomado de las reglas ConfigureAndExecuteTest):
/** * {@inheritdoc} */ protected function setUp(): void { parent::setUp(); // Create an article content type that we will use for testing. $type = $this->container->get('entity_type.manager')->getStorage('node_type') ->create([ 'type' => 'article', 'name' => 'Article', ]); $type->save(); $this->container->get('router.builder')->rebuild(); }
Tenga en cuenta que si implementa el método setUp(), empiece por ejecutar el método parent::setUp() como en el ejemplo.
Crear prueba específica: la página de reglas de reacción
Ahora necesitamos crear pruebas específicas para ejercitar el módulo. Simplemente creamos métodos de nuestra clase de prueba, cada uno de los cuales realiza una prueba en particular. Todos los métodos deben comenzar con 'prueba' en minúsculas. Cualquier método con visibilidad pública que comience de esta manera será reconocido automáticamente por PHPUnit y se ejecutará cuando se solicite.
Nuestra primera prueba comprobará la página en admin/config/workflow/rules:
/** * Tests that the reaction rule listing page works. */ public function testReactionRulePage() { $account = $this->drupalCreateUser(['administer rules']); $this->drupalLogin($account); $this->drupalGet('admin/config/workflow/rules'); $this->assertSession()->statusCodeEquals(200); // Test that there is an empty reaction rule listing. $this->assertSession()->pageTextContains('There is no Reaction Rule yet.'); }
setUp() y pruebas individuales
Cada función de prueba tendrá una instancia de Drupal completamente nueva para ejecutar pruebas. Esto significa que lo que haya creado en una función de prueba anterior ya no estará disponible en la siguiente.
Considere este ejemplo, tomado de Rules UIPageTest.php -extraction:
namespace Drupal\Tests\rules\Functional; class UiPageTest extends RulesBrowserTestBase { /** * Modules to enable. * * @var array */ protected static $modules = ['rules']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); // .... } public function testReactionRulePage() { $account = $this->drupalCreateUser(['administer rules']); $this->drupalLogin($account); // ..... } public function testCreateReactionRule() { $account = $this->drupalCreateUser(['administer rules']); $this->drupalLogin($account); // ..... } public function testCancelExpressionInRule() { // Setup a rule with one condition. $this->testCreateReactionRule(); // ..... } }
Aqui ambos testReactionRulePage()
y testCreateReactionRule
deben crear su propia $account, porque ambas pruebas se ejecutan en sus propias instancias de Drupal y el Drupal de la última función no tiene cuentas a menos que se cree.
Sin embargo, otras pruebas (posteriores) pueden depender del contenido creado en otras funciones de prueba si ejecutan esas funciones por separado, como lo hace testCancelExpressionInRule ()
.
Por otro lado, la función setUp()
se ejecuta antes de cada función de prueba, por lo que también puede usarlo para preparar el entorno de prueba.
drupalGet() y Assertions
El código anterior hizo una solicitud GET muy simple en la página admin / config / workflow / rules. Carga la página, luego verifica el código de respuesta y afirma que encontramos el texto apropiado en la página.
La mayoría de las pruebas seguirán este patrón:
- Haga un $ this-> drupalGet ('some / path') para ir a una página
- Use $ this-> clickLink (..) para navegar por enlaces en la página
- Use $ this-> getSession () -> getPage () -> fillField (...); para completar los campos del formulario
- Envíe formularios con $ this-> getSession () -> getPage () -> pressButton (...); o use $ this-> submitForm (...); (o use el método obsoleto drupalPostForm ())
- Haga una o más afirmaciones para comprobar que lo que vemos en la página es lo que deberíamos ver.
Rellenar formularios
$page = $this->getSession()->getPage(); $page->fillField('form_element', 'value'); $page->selectFieldOption('form_element', 'value')
Assertions (Afirmaciones)
Hay decenas de posibles assertions. A continuación se muestran algunos ejemplos. Cuando vaya más allá de este tutorial, querrá mirar la clase \ Behat \ Mink \ WebAssert y su hijo de Drupal \ Drupal \ Tests \ WebAssert para leer más sobre ellos.
$this->assertOptionSelected('form_element', 'value'); $this->assertFieldByName('form_element'); $web_assert = $this->assertSession(); $web_assert->addressEquals('node/1'); $web_assert->pageTextContains("Expected text"); $web_assert->pageTextNotContains("Unexpected text");
Ejecutando la prueba
Usaremos la línea de comando para ejecutar la prueba. Esto se documenta con más detalle en la ejecutando la página de pruebas PHPUnit.
Ejecutemos solo el método testReactionRulePage () de UiPageTest:
cd core ../vendor/bin/phpunit --filter testReactionRulePage ../modules/rules/tests/src/Functional/UiPageTest.php PHPUnit 4.8.11 by Sebastian Bergmann and contributors. . Time: 25.14 seconds, Memory: 6.00Mb OK (1 test, 5 assertions) HTML output was generated http://drupal-8.localhost/sites/simpletest/browser_output/Drupal_Tests_rules_Functional_UiPageTest-13-411368.html http://drupal-8.localhost/sites/simpletest/browser_output/Drupal_Tests_rules_Functional_UiPageTest-14-411368.html http://drupal-8.localhost/sites/simpletest/browser_output/Drupal_Tests_rules_Functional_UiPageTest-15-411368.html
¡Sí, nuestra prueba ha pasado! También generó un par de archivos de salida HTML, donde puede ver las páginas que visitó el navegador durante la prueba. Las páginas se escriben en archivos vinculados como, por ejemplo, arriba, por lo que puede inspeccionarlos después de que se haya ejecutado la prueba.
Una prueba de demostración fallida
Realmente no nos enseña mucho tener un examen que tenga éxito. Veamos uno que falla.
Modificaremos la prueba para provocar una falla en la prueba; afirmaremos que la página contiene un texto diferente, que por supuesto no está allí.
/** * Tests that the reaction rule listing page works. */ public function testReactionRulePage() { $account = $this->drupalCreateUser(['administer rules']); $this->drupalLogin($account); $this->drupalGet('admin/config/workflow/rules'); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('some text not actually on the page'); }
Ejecute la prueba y vea el resultado:
../vendor/bin/phpunit --filter testReactionRulePage ../modules/rules/tests/src/Functional/UiPageTest.php PHPUnit 4.8.11 by Sebastian Bergmann and contributors. E Time: 24.38 seconds, Memory: 6.00Mb There was 1 error: 1) Drupal\Tests\rules\Functional\UiPageTest::testReactionRulePage Behat\Mink\Exception\ResponseTextException: The text "some text not actually on the page" was not found anywhere in the text of the current page. /home/klausi/workspace/drupal-8/vendor/behat/mink/src/WebAssert.php:787 /home/klausi/workspace/drupal-8/vendor/behat/mink/src/WebAssert.php:262 /home/klausi/workspace/drupal-8/modules/rules/tests/src/Functional/UiPageTest.php:37 FAILURES! Tests: 1, Assertions: 5, Errors: 1. HTML output was generated http://drupal-8.localhost/sites/simpletest/browser_output/Drupal_Tests_rules_Functional_UiPageTest-16-425496.html http://drupal-8.localhost/sites/simpletest/browser_output/Drupal_Tests_rules_Functional_UiPageTest-17-425496.html http://drupal-8.localhost/sites/simpletest/browser_output/Drupal_Tests_rules_Functional_UiPageTest-18-425496.html
Vaya, algo salió mal y nuestra prueba lo detectó. ¡Hurra!
Cuándo usar t () en las pruebas del navegador
¡Nunca! No, ni en los mensajes de afirmación, ni para las etiquetas de los botones, ni para el texto que afirma en la página. Siempre desea probar la cadena literal en la página, no desea probar el sistema de traducción de Drupal.
Depurar las pruebas del navegador
Como ya se mencionó, es muy importante habilitar la salida de depuración en la prueba del navegador para que pueda ver las páginas visitadas por el navegador. Si una prueba falla, PHPUnit detiene la ejecución de la prueba donde falla, lo que significa que el último de los enlaces de salida HTML es la página donde ocurrió el error.
También puede utilizar la función dump () (proporcionada por el componente Symfony VarDumper), ya sea en su método de prueba o en el código del sitio que se está ejecutando. Esto tiene la ventaja sobre el uso de print o print_r () que su salida no se detecta como un error de prueba.
También puede usar el método ddm () del módulo Devel para generar un archivo de registro. Configure la ubicación del archivo de registro en su código de prueba de esta manera:
$config = $this->config('devel.settings'); $config->set('debug_logfile', '/path/to/file/drupal_debug.txt')->save(); $config->set('debug_pre', FALSE)->save();
Escribir una clase base para ampliarla con otras clases de prueba.
Puede encontrar que algunos de sus códigos de prueba duplican la funcionalidad compartida. En este caso, es posible que desee crear una clase base que luego se amplíe con sus diversas clases de prueba. Al hacer esto, hay 2 cosas importantes a tener en cuenta.
- La clase de prueba base debe ser abstracta
- La clase de prueba base debe terminar con la palabra Base
Ejemplo de Clase de prueba base: my_module/Tests/src/Functional/myModuleTestBase.php
<?php namespace Drupal\Tests\my_module\Functional; /** * To be extended by other test classes. */ abstract class myModuleTestBase extends BrowserTestBase { protected function setUp() { parent::setUp(); // etc } }
Ampliando la clase base: my_module/Tests/src/Functional/myModuleSomethingTest.php
<?php namespace Drupal\Tests\my_module\Functional; /** * Test something about my module. * * @group my_module */ class myModuleSomethingTest extends myModuleTestBase { protected function setUp() { parent::setUp(); } public function testSomething() { // do the test. } }
SQLite
El uso de una base de datos SQLite hace que las pruebas sean más rápidas que con un DBMS como MySQL. Porque la base de datos está contenida en solo 1 archivo. Asegúrese de que Drupal no esté usando su conexión de base de datos predeterminada desde el archivo settings.php.
Una solución sencilla es comprobar el HTTP_USER_AGENT. Ej.:
if ($_SERVER['HTTP_USER_AGENT'] !== 'Drupal command line') { $databases['default']['default'] = [ 'database' => 'MY-DATABASE', 'username' => 'root', 'password' => 'root', 'prefix' => '', 'host' => '127.0.0.1', 'port' => '', 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', 'driver' => 'mysql', 'unix_socket' => '/Applications/MAMP/tmp/mysql/mysql.sock', ]; }
En su archivo phpunit.xml especifique su conexión de base de datos SQLite (el archivo no debe existir antes):
<env name="SIMPLETEST_DB" value="sqlite://localhost/sites/default/files/db.sqlite"/>
De lo contrario, obtendrá errores como este:
Exception: PDOException: SQLSTATE[HY000] [2002] Connection refused
Usar datos de sesión
Puede inspeccionar los datos de la sesión para la solicitud más reciente de la siguiente manera:
$session_data = $this->container->get('session_handler.write_safe')->read($this->getSession()->getCookie($this->getSessionName())); $session_data = unserialize(explode('_sf2_meta|', $session_data)[1]);
Fuente: https://www.drupal.org/docs/automated-testing/phpunit-in-drupal/phpunit-browser-test-tutorial
PHPUnit | Ejecución de pruebas
Configuración para ejecutar pruebas PHPUnit
Antes de entrar en materia sobre el uso de Test Unitarios de Php, en Drupal 8 o 9, tendremos que familiarizarnos con esta actividad, conociendo sus fundamentos y las configuraciones iniciales.
Prerrequisitos:
- Asegúrate de que las dependencias de Composer estén instaladas
Si haz realizado tu instalación de Drupal, utilizando composer desde el repositorio de Drupal.org, y quieres asegurarte de tener además, todas las dependencias necesarias para los test unitarios, puedes hacerlo escogiendo una de las siguientes opciones:
- Instalar Composer y ejecutar composer install (o actualizar tu Drupal 8 ó 9 existente, ejecutando composer update)
- Utilizar una versión de desarrollo (por ejemplo, 9.0.x-dev) en lugar de la que tienes en tu sitio actual.
- Instale las dependencias de desarrollo que necesita manualmente en el directorio de vendor de Drupal o en otro lugar.
Yo voy a realizar una instalación de Drupal 8, nueva, utilizando la plantilla drupal/recommended-project, para eso en mi consola, ejecutaré el siguiente comando:
composer create-project drupal/recommended-project:^8 mi_drupal
Si al instalar tu Drupal, haz utilizado la plantilla de Composer drupal/recommended-project, las dependencias de desarrollo pueden ser instaladas utilizando en tu proyecto una vez instalado, nos colocaremos en la carpeta root de Drupal y ejecutaremos el siguiente comando:
composer require --dev 'drupal/core-dev:^8.9'
Si has instalado Drupal, utilizando git, entonces, instala composer y a continuación ejecuta el siguiente comando para que se descarguen las dependencias:
composer install
Recuerda que las dependencias de desarrollo, nunca deben instalarse en una producción o en un servidor de acceso público, por razones de seguridad. Ver el announcement about our dev dependency packaging changes para más información.
Las pruebas de Javascript tienen dependencias adicionales; consulta Running PHPUnit Javascript tests.
Cómo configurar PHPUnit
PHPUnit almacena la configuración en el archivo llamado phpunit.xml, ubicado dentro de la carpeta raíz de tu Drupal. Drupal viene con una versión de muestra de esto, puedes encontrarlo dentro de la carpeta core/phpunit.xml.dist, así podrías copiar este archivo para comenzar con tus pruebas.
El lugar de tu archivo de configuración dependerá de tu flujo de trabajo:
- El ejecutable PHPUnit espera encontrar el archivo de configuración phpunit.xml, dentro de tu carpeta raíz. Esto se puede anular con la opción -c.
- Si estás utilizando Composer para administrar el núcleo de Drupal, la actualización del núcleo sobrescribirá el núcleo / carpeta y eliminará su archivo phpunit.xml
Una vez hayamos copiado, desde el core/phpunit.xml.dist y renombrado nuestro archivo phpunit.xml, lo abriremos para añadir los siguientes cambios:
- Añadiremos el valor a la variable SIMPLETEST_BASE_URL con la url de nuestro sitio.
- Configuraremos la variable SIMPLETEST_DB para que apunte a la URL de la base de datos de nuestro Drupal.
- Si estas colocando phpunit.xml en algún lugar que no sea core, tendrás que cambiar el valor del atributo 'bootstrap' de la etiqueta phpunit para reflejar la nueva ubicación.
- Para pruebas funcionales y del kernel, establezca el BROWSERTEST_OUTPUT_DIRECTORY
El resultado debería verse así:
<phpunit bootstrap="tests/bootstrap.php" colors="true" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutOutputDuringTests="true" beStrictAboutChangesToGlobalState="true" printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter"> <php> <!-- Set error reporting to E_ALL. --> <ini name="error_reporting" value="32767"/> <!-- Do not limit the amount of memory tests take to run. --> <ini name="memory_limit" value="-1"/> <!-- Example SIMPLETEST_BASE_URL value: http://localhost --> <env name="SIMPLETEST_BASE_URL" value="http://drupal8.localhost"/> <!-- Example SIMPLETEST_DB value: mysql://username:password@localhost/databasename#table_prefix --> <env name="SIMPLETEST_DB" value="mysql://drupal8:drupal8@localhost/drupal8"/> <!-- Example BROWSERTEST_OUTPUT_DIRECTORY value: /path/to/webroot/sites/simpletest/browser_output --> <env name="BROWSERTEST_OUTPUT_DIRECTORY" value="/var/www/sites/simpletest/browser_output"/> </php> </phpunit>
Una vez hecho todo esto, podremos ejecutar cualquier prueba, sin tener que volver a realizar toda esta configuración.
Busque y reemplace rápidamente los valores con sed desde la línea de comando. Los valores de ejemplo son para Lando y se supone que estamos ubicados dentro de la carpeta principal de Drupal, al igual que el archivo de configuración phpunit.xml. Ajústalo para igualarlo a tu configuración:
$ cd core $ cp phpunit.xml.dist phpunit.xml $ sed -i 's|name="SIMPLETEST_BASE_URL" value=""|name="SIMPLETEST_BASE_URL" value="http://d8dev\.lndo\.site"|g' phpunit.xml $ sed -i 's|name="SIMPLETEST_DB" value=""|name="SIMPLETEST_DB" value="mysql://drupal8:drupal8@database/drupal8"|g' phpunit.xml $ sed -i 's|name="BROWSERTEST_OUTPUT_DIRECTORY" value=""|name="BROWSERTEST_OUTPUT_DIRECTORY" value="../sites/simpletest/browser_output"|g' phpunit.xml
Creando un directorio para la salida HTML
Las pruebas funcionales pueden generar las páginas HTML que ve el código de ejecución de la prueba. Estos se generan como archivos HTML sin formato. Para proporcionar una ubicación en la que escribirlos, crearemos un directorio llamado sites/simpletest y nos aseguraremos de que el servidor web pueda escribirlo. Está bien hacer que este directorio sea "world-writable", ej.:
mkdir -p sites/simpletest/browser_output chmod -R 777 sites/simpletest
Locate the PHPUnit binary
La ubicación relativa del binario PHPUnit depende de cómo instale Drupal.
- Si hemos instalado Drupal usando un paquete, ejecutaremos composer update, el directorio vendor está dentro de la raíz de Drupal (adyacente a 'core'). Las instrucciones en esta página asumen que esta es su configuración.
- Si lo hicimos usando composer require drupal/drupal , terminas con un directorio de proveedores fuera de la raíz de Drupal (arriba del 'core'). Es posible que debamos ajustar la ruta a PHPUnit en los comandos que se dan en esta página:
vendor/bin/phpunit se convertirá en ../vendor/bin/phpunit and ../vendor/bin/phpunit se convertirá en ../../vendor/bin/phpunit.
Dependiendo de su flujo de trabajo de desarrollo, puede resultarle útil crear un link simbólico a PHPUnit desde / usr / local / bin ( cd /usr/local/bin; ln -s /var/www/html/vendor/bin/phpunit), o parecido, o añadir vendor/bin a tu PATH.
Comprobando que se verifiquen las aserciones en tiempo de ejecución
Al ejecutar pruebas de phpunit, es importante asegurarnos de que se verifiquen, las declaraciones de aserción en tiempo de ejecución. Consulte la nota sobre la ejecución de pruebas localmente en el change notice about runtime assertions , para más información al respecto.
Ejecutando pruebas
Todos los comandos de ejemplo en este documento asumen que estamos dentro del directorio raíz y nuestro archivo ejecutable de configuración phpunit.xml, se encuentra dentro de la carpeta core.
Al ejecutar \Drupal\Tests\datetime\Unit\Plugin\migrate\field\DateFieldTest, por ejemplo, su comando se vería así:
../vendor/bin/phpunit modules/datetime/tests/src/Unit/Plugin/migrate/field/DateFieldTest.php
Su ruta al ejecutable phpunit puede ser diferente a la anterior.
Ejecute todas las pruebas unitarias de PHPUnit
Para ejecutar las pruebas unitarias en OS X, Linux u otros sistemas * nix:
../vendor/bin/phpunit --testsuite=unit
Nota: Todas las pruebas, incluidas las ubicadas en [drupalroot]/modules o [drupalroot]/sites/*/modules, se ejecutan desde la carpeta principal con el comando:
../vendor/bin/phpunit
Debemos tomar en cuenta, que no necesita tener una instalación de Drupal en funcionamiento, para ejecutar pruebas unitarias basadas en PHPUnit de esta manera. Las pruebas de PHPUnit están aisladas de Drupal y no las necesitan para ejecutarse.
En Windows, el enlace simbólico almacenado en vendor/bin/phpunit no funcionará. Debemos usar la ruta completa al ejecutable PHPUnit:
../vendor/phpunit/phpunit/phpunit
Problemas de permisos
Las pruebas funcionales deben invocarse con un usuario del mismo grupo que el usuario del servidor web. Puede configurar Apache (o Nginx) para que se ejecute como su propio usuario del sistema o ejecutar pruebas como un usuario privilegiado.
Para desarrollar localmente, un enfoque sencillo, pero también menos seguro, es para ejecutar pruebas como su propio usuario del sistema. Para lograrlo, cambie el usuario Apache predeterminado para que se ejecute como su usuario del sistema. Normalmente, necesitaría modificar en Linux `/etc/apache2/envvars` o en Mac el `/etc/apache2/httpd.conf`
Paginación
- Página anterior
- Página 2
- Siguiente página