readthedocs - phpunit tutorial español
phpunit-la prueba es dolorosamente lenta (3)
Estoy buceando cada vez más en el mundo de las pruebas unitarias.
Un problema que encontré, y aquí es donde me gustaría recibir comentarios, es cuando uno ejecuta múltiples suites de prueba, tal vez soy solo yo, pero necesito usar el parámetro --process-isolation para pasar las pruebas. Puedo ejecutar cualquiera de mis suites individualmente sin ningún problema, pero ejecutar las 6-7 suites que tengo hasta el momento con 180 aserciones distribuidas entre ellas falla si corro sin --proceso-aislamiento. El problema es que el uso de este parámetro hace que la prueba dure más de 35 minutos, frente a los 2,5 minutos habituales. Esa es una larga espera.
El problema está relacionado con el uso de contenedores de DI simulados para pruebas específicas y los contenedores no se reinicializan correctamente cuando las suites de pruebas se están encadenando. Las propiedades estáticas establecidas en DI-Container para probar las fallas esperadas hacen que las pruebas en el siguiente paquete fallen. El contenedor tiene un parámetro que puede contener el objeto contenido en una var estática, para devolver la misma instancia en cada llamada. Un singleton disfrazado. Y esto funciona bien en el nivel de la aplicación, es solo una molestia para las pruebas.
Podría evitar ese parámetro de contenedor y codificar la aplicación para que no use propiedades estáticas, pero evitar una construcción de lenguaje útil por el bien de una metodología parece exagerado.
Tal vez estoy haciendo algo mal (¡así lo espero!), Pero tengo la impresión de que si uno quiere realizar pruebas con el SUT en un estado limpio para cada prueba, no hay forma de evitar el uso del "proceso de aislamiento". Esto hace que las pruebas consuman mucho tiempo y le quita un poco la alegría. Pasé por alto el problema al ejecutar suites y pruebas individualmente cuando estoy codificando, y ejecutar el conjunto en segundo plano antes de las confirmaciones principales.
Es lo que estoy experimentando normal, y ¿hay alguna forma de contrarrestar esto? ¿Cómo prueban allí que el tiempo de prueba es razonable? ¿Cómo se manejan las estadísticas para no influir en las pruebas?
Cualquier apreciación apreciada / comentario apreciado.
Algunos trucos;
filtrando sus casos de prueba, por ejemplo, si quiere probar un archivo onw, solo necesita
phpunit --filter ''Default_My_Test''
Eliminar la cobertura de código en su archivo phpunit.xml. Si quieres obtener una cobertura de código hazlo:
phpunit --coverage-html ./ report reportTest
Tienes varios problemas
El primero es el aislamiento del proceso. Normalmente, no debería ser necesario y solo quiere usarlo para descubrir qué prueba específica es la que rompe fatalmente sus pruebas. Como te dijiste, es terriblemente lento, que es algo que no puedes arreglar. Sin embargo, es posible que desee deshabilitar la copia de seguridad de los vars globales que ahorran algunos milisegundos por prueba.
El segundo problema, que lleva a su primer problema, es que su código no es comprobable porque los vars estáticos se guardan durante las pruebas, mi problema de singleton más odiado. Puede resolver ese problema proporcionando un método de "limpieza" o "restablecimiento" en sus contenedores de dependencia. Se les llamará desde el método setUp()
en su clase principal de caso de prueba y se restablecerá todo a un estado limpio.
Velocidad
En cuanto al tiempo de ejecución de las pruebas, recientemente escribí una entrada en el blog sobre cómo averiguar qué pruebas eran demasiado lentas. En general, las pruebas son demasiado lentas si no puede ejecutarlas después de guardar el archivo o cada confirmación en su propio recuadro. 10 segundos es apenas aceptable para mí. Cuantas más pruebas tengas, más lento será su funcionamiento.
Si realmente tiene 35 minutos, divida sus pruebas en grupos sensibles para que pueda ejecutar los necesarios en su propia máquina, solo las pruebas que prueban el código que ha cambiado. Pyrus, el instalador de PEAR de próxima generación, tiene la ingeniosa función de detectar y ejecutar automáticamente las pruebas que necesitan ejecutarse , según los archivos que hayas cambiado. PHPUnit no tiene eso, pero puedes emular eso a mano y phpunit --group ..
:)
Siempre ocúpese de burlarse de los servicios web y las bases de datos, o al menos ejecutar la base de datos con solo los datos necesarios para cada prueba individual. Esperar 3 segundos para una respuesta de servicios web en una prueba que verifica si puede guardar al usuario en la base de datos es algo que nunca desea.
Una de las cosas que suelo hacer cuando Hash::setRounds(5);
con MySQL en lugar de la :memory:
de SQLite :memory:
es agregar Hash::setRounds(5);
tests/CreatesApplication.php
internas tests/CreatesApplication.php
Rasgo como este. Experimenté que esto hará que las pruebas especialmente con MySQL sean mucho más rápidas:
public function createApplication()
{
$app = require __DIR__ . ''/../bootstrap/app.php'';
$app->make(Kernel::class)->bootstrap();
// TODO: DON''T FORGET TO IMPORT HASH OBJECT ON TOP
Hash::setRounds(5);
return $app;
}