Mantengo un sitio Magento 1.9 con varios módulos personalizados. Parte de la funcionalidad es crítica para el negocio y necesita urgentemente algunas pruebas unitarias. Por ejemplo, una calculadora de precio unitario.
Normalmente desarrollo en Symfony y realmente preferiría usar PHPUnit (w / Composer) de alguna manera si es posible.
Algunas funciones se basan en datos importados a varias tablas de bases de datos personalizadas, por lo que preferiría cargar de alguna manera los accesorios.
Así que estoy buscando el enfoque de mejores prácticas para escribir algunas pruebas unitarias. Glady aceptaré tutoriales o algo similar. Cualquier ayuda es apreciada.
Instalación
Dado que Magento 1 no usa el compositor de fábrica, no creo que haga una gran diferencia si instala phpunit usando el compositor o simplemente descarga la versión phar .
Si ya usa Composer para administrar otros módulos o bibliotecas de terceros en su sitio, entonces Composer probablemente tenga más sentido. Sin embargo, a menos que use PHP7, estará limitado a una versión anterior de phpunit (es por eso que me vinculé a la versión 4.8 anterior).
Pruebas de integración vs / y / o pruebas unitarias
Dado que Magento 1 es una aplicación tan pesada, tiene sentido separar el arranque de phpunit en uno para integración y otro para pruebas unitarias.
El programa de arranque de prueba de la unidad solo necesita inicializar el autocargador, mientras que el programa de arranque de prueba de integración debe inicializar todo el entorno de la aplicación, incluida la carga de configuración y la conexión db.
Debido a que las pruebas de integración en Magento tienden a ejecutarse mucho más lentamente que las pruebas unitarias (aún más que en otras aplicaciones).
Bootstrapping Magento en phpunit
El cargador automático de Magento no es compatible con PSR-0, ya que arroja una excepción si no puede encontrar el archivo en el que se encuentra una clase. Esto rompe algunos usos de
class_exists
phpunit. Hay varias soluciones posibles (si es hacky):\Varien_Autoload::autoload()
en un decorador, ignorando las excepciones lanzadas dentro, y registre el contenedor como un nuevo cargador automático. Esto tiene pocas posibilidades de conflictos con las bibliotecas de terceros que registran cargadores automáticos y dependen de un orden específico del cargador automático.\Varien_Autoload::autoload()
y no arrojar el error si el archivo no existe. Sin embargo, esto entra en conflicto con varios módulos que también anulan la misma clase. Yo no uso este enfoque yo mismo.Para evitar errores durante el inicio de la sesión durante las pruebas, simplemente configure
$_SESSON = []
en el arranque.Establezca un objeto de respuesta personalizado a través de
Mage::app()->setResponse($testResponse)
que extienda el real pero no envíe salida o encabezados.Para reiniciar Magento entre pruebas de integración que cambian completamente el estado de tiempo de ejecución, use
Mage::reset(); Mage::app()
. Tenga en cuenta que después de eso, el controlador de errores tendrá que volver a decorarse.Accesorios
Para los accesorios DB, tiendo a usar los modelos regulares en los métodos de accesorios para crear accesorios, por ejemplo
createSimpleProduct($sku)
. Como dijo Raphael, usesetUp()
ytearDown()
para ajustar la prueba en una transacción que se revierte después de la prueba (por ejemploMage::getSingleton('core/resource')->getConnection('default_setup')->beginTransaction()
).Para los dispositivos de configuración de la tienda, tiendo a configurar dispositivos solo en memoria usando
Mage::app()->getStore()->setConfig($path, $value)
.La
EcomDev_PHPUnit
extensión también ofrece la opción de crear dispositivos de base de datos utilizando archivos yaml, pero para mí es más difícil de mantener en comparación con los dispositivos creados usando clases de modelos. YMMV.Dobles de prueba
El registro se puede usar para inyectar dobles de prueba para objetos creados mediante
Mage::getSingleton()
,Mage::getResourceSingleton()
yMage::helper()
.Se pueden establecer algunos otros objetos centrales
Mage::app()
(por ejemplo, la solicitud).Para reemplazar las clases creadas mediante
Mage::getModel()
oMage::getResourceModel()
con dobles de prueba, se debe usar un contenedor de objetos de configuración personalizado . Vea este ejemplo en el marco de prueba de Raphael cómo se puede lograr eso.Resumen
Una vez que Magento se inicia, casi todo se puede probar bastante bien. Sin embargo, prepárate para crear simulacros profundos debido a la gran cantidad de métodos que encadena el código central.
Aunque la configuración es hacky, funciona bien y creo que las pruebas me dan mucha confianza y valor, más o menos comparable a un conjunto de pruebas para una aplicación Symphony.
fuente