Las pruebas instantáneas son una forma de realizar pruebas sin escribir casos de prueba reales.
Puede obtener más información en este vídeo gratuito de nuestro curso Testing Laravel. No se preocupe, también puede usar este paquete en proyectos que no sean de Laravel.
utilizar SpatieSnapshotsMatchesSnapshots;clase OrderTest {use MatchesSnapshots; función pública test_it_casts_to_json() {$order = new Order(1);$this->assertMatchesJsonSnapshot($order->toJson()); } }
En la primera ejecución, el ejecutor de pruebas creará una nueva instantánea.
> ./vendor/bin/phpunit There was 1 incomplete test: 1) OrderTest::test_it_casts_to_json Snapshot created for OrderTest__test_it_casts_to_json__1 OK, but incomplete, skipped, or risky tests! Tests: 1, Assertions: 0, Incomplete: 1.
En ejecuciones posteriores, la prueba pasará siempre que la instantánea no cambie.
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
Si hay una regresión, ¡la prueba fallará!
$orderId = nuevo pedido(2); // ¡Regresión! Era "1"
> ./vendor/bin/phpunit 1) OrderTest::test_it_casts_to_json Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ Failed asserting that '{"id":2}' matches JSON string "{ "id": 1 } FAILURES! Tests: 1, Assertions: 1, Failures: 1.
Invertimos muchos recursos en la creación de los mejores paquetes de código abierto. Puedes apoyarnos comprando uno de nuestros productos pagos.
Apreciamos mucho que nos envíe una postal desde su ciudad natal, mencionando cuál de nuestros paquetes está utilizando. Encontrarás nuestra dirección en nuestra página de contacto. Publicamos todas las postales recibidas en nuestro muro virtual de postales.
Puede instalar el paquete a través del compositor:
El compositor requiere --dev spatie/phpunit-snapshot-assertions
Para realizar afirmaciones instantáneas, utilice el rasgo SpatieSnapshotsMatchesSnapshots
en su clase de caso de prueba. Esto agrega un conjunto de métodos de aserción a la clase:
assertMatchesSnapshot($actual)
assertMatchesFileHashSnapshot($actual)
assertMatchesFileSnapshot($actual)
assertMatchesHtmlSnapshot($actual)
assertMatchesJsonSnapshot($actual)
assertMatchesObjectSnapshot($actual)
assertMatchesTextSnapshot($actual)
assertMatchesXmlSnapshot($actual)
assertMatchesYamlSnapshot($actual)
assertMatchesImageSnapshot($actual)
Hagamos una afirmación instantánea para una cadena simple, "foo".
función pública test_it_is_foo() {$this->assertMatchesSnapshot('foo'); }
La primera vez que se ejecuta la afirmación, no tiene una instantánea con la que comparar la cadena. El ejecutor de la prueba genera una nueva instantánea y marca la prueba como incompleta.
> ./vendor/bin/phpunit There was 1 incomplete test: 1) ExampleTest::test_it_matches_a_string Snapshot created for ExampleTest__test_it_matches_a_string__1 OK, but incomplete, skipped, or risky tests! Tests: 1, Assertions: 0, Incomplete: 1.
Los identificadores de instantáneas se generan en función de los nombres de la prueba y del caso de prueba. Las instantáneas básicas devuelven una representación de texto sin formato o YAML del valor real.
foo
Volvamos a ejecutar la prueba. El ejecutor de la prueba verá que ya existe una instantánea de la afirmación y hará una comparación.
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
Si cambiamos el valor real a "bar", la prueba fallará porque la instantánea aún devuelve "foo".
función pública test_it_is_foo() {$this->assertMatchesSnapshot('bar'); }
> ./vendor/bin/phpunit 1) ExampleTest::test_it_matches_a_string Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'foo' +'bar' FAILURES! Tests: 1, Assertions: 1, Failures: 1.
Cuando esperamos un valor modificado, debemos decirle al ejecutor de la prueba que actualice las instantáneas existentes en lugar de fallar la prueba. Esto es posible agregando un indicador -d --update-snapshots
al comando phpunit
o configurando la var env UPDATE_SNAPSHOTS
en true
.
> ./vendor/bin/phpunit -d --update-snapshots OK (1 test, 1 assertion)
Como resultado, nuestro archivo de instantánea devuelve "bar" en lugar de "foo".
bar
El rasgo MatchesSnapshots
ofrece dos formas de afirmar que un archivo es idéntico a la instantánea que se realizó la primera vez que se ejecutó la prueba:
La aserción assertMatchesFileHashSnapshot($filePath)
afirma que el hash del archivo pasado a la función y el hash guardado en la instantánea coinciden. Esta afirmación es rápida y utiliza muy poco espacio en disco. La desventaja de esta afirmación es que no existe una manera fácil de ver en qué se diferencian los dos archivos si la prueba falla.
La aserción assertMatchesFileSnapshot($filePath)
funciona casi de la misma manera que la aserción hash del archivo, excepto que en realidad guarda el archivo completo en el directorio de instantáneas. Si la afirmación falla, coloca el archivo fallido junto al archivo de instantánea para que se puedan comparar fácilmente manualmente. El archivo fallido persistente se elimina automáticamente cuando pasa la prueba. Esta afirmación es más útil cuando se trabaja con archivos binarios que deben compararse manualmente, como imágenes o archivos PDF.
assertImageSnapshot
requiere que se instale el paquete spatie/pixelmatch-php.
Esta afirmación será válida si la imagen proporcionada es casi idéntica a la instantánea que se tomó la primera vez que se ejecutó la prueba. Puede personalizar el umbral pasando un segundo argumento a la aserción. Los valores más altos harán que la comparación sea más sensible. El umbral debe estar entre 0 y 1.
$this->assertMatchesImageSnapshot($imagePath, 0.1);
Los identificadores de instantáneas se generan mediante el método getSnapshotId
en el rasgo MatchesSnapshot
. Anule el método para personalizar la identificación. De forma predeterminada, existe una identificación de instantánea del nombre de la prueba, el nombre del caso de prueba y un valor incremental, por ejemplo, Test__my_test_case__1
.
__
con --
función protegida getSnapshotId(): string{return (new ReflectionClass($this))->getShortName().'--'.$this->name().'--'.$this->snapshotIncrementor; }
De forma predeterminada, las instantáneas se almacenan en un directorio __snapshots__
relativo a la clase de prueba. Esto se puede cambiar anulando el método getSnapshotDirectory
.
__snapshots__
a snapshots
función protegida getSnapshotDirectory(): string{return dirname((new ReflectionClass($this))->getFileName()).DIRECTORY_SEPARATOR.'snapshots'; }
El controlador utilizado para serializar los datos se puede especificar como segundo argumento del método assertMatchesSnapshot
, para que puedas elegir el que mejor se adapte a tus necesidades:
utilizar SpatieSnapshotsDriversJsonDriver; utilizar SpatieSnapshotsMatchesSnapshots; clase OrderTest {use MatchesSnapshots; función pública test_snapshot_with_json_driver() {$order = new Order(1);$this->assertMatchesSnapshot($order->toJson(), new JsonDriver()); } }
Los controladores garantizan que se puedan serializar y combinar diferentes tipos de datos a su manera. Un controlador es una clase que implementa la interfaz SpatieSnapshotsDriver
, que requiere tres implementaciones de métodos: serialize
, extension
y match
.
Echemos un vistazo rápido al JsonDriver
.
espacio de nombres SpatieSnapshotsDrivers; use PHPUnitFrameworkAssert; use SpatieSnapshotsDriver; use SpatieSnapshotsExceptionsCantBeSerialized; la clase JsonDriver implementa el controlador {función pública serializar($datos): cadena{if (! is_string($datos)) {throw new CantBeSerialized('Solo las cadenas se pueden serializar en json'); }return json_encode(json_decode($datos), JSON_PRETTY_PRINT).PHP_EOL; }extensión de función pública(): cadena{return 'json'; }coincidencia de función pública ($esperada, $actual) { Afirmar::assertJsonStringEqualsJsonString($actual, $esperado); } }
El método serialize
devuelve una cadena que se escribirá en el archivo de instantánea. En JsonDriver
, decodificaremos y volveremos a codificar la cadena json para asegurarnos de que la instantánea tenga una buena impresión.
Queremos guardar instantáneas json como archivos json, por lo que usaremos json
como extensión de archivo.
Al hacer coincidir los datos esperados con los datos reales, queremos usar las aserciones json integradas de PHPUnit, por lo que llamaremos al método assertJsonStringEqualsJsonString
específico.
Los controladores se pueden utilizar pasándolos como segundo argumento de assertMatchesSnapshot
.
$this->assertMatchesSnapshot($algo->toYaml(), new MyYamlDriver());
Al ejecutar sus pruebas en Integración continua, es posible que desee deshabilitar la creación de instantáneas.
Al usar el parámetro --without-creating-snapshots
o al configurar la var env CREATE_SNAPSHOTS
en false
, PHPUnit fallará si las instantáneas no existen.
> ./vendor/bin/phpunit -d --sin-crear-instantáneas 1) Prueba de ejemplo::test_it_matches_a_string La instantánea "ExampleTest__test_it_matches_a_string__1.txt" no existe. Puede crearlo automáticamente eliminando la var de entorno `CREATE_SNAPSHOTS=false` o `-d --no-create-snapshots` de los argumentos CLI de PHPUnit.
Si desea ejecutar su prueba en paralelo con una herramienta como Paratest, o con el comando php artisan test --parallel
de Laravel, tendrá que usar las variables de entorno.
> CREATE_SNAPSHOTS=falso prueba artesanal de php --paralelo 1) Prueba de ejemplo::test_it_matches_a_string La instantánea "ExampleTest__test_it_matches_a_string__1.txt" no existe. Puede crearlo automáticamente eliminando la var de entorno `CREATE_SNAPSHOTS=false` o `-d --no-create-snapshots` de los argumentos CLI de PHPUnit.
Los usuarios de Windows deben configurar los finales de línea en .gitattributes
.
# Las instantáneas utilizadas en las pruebas contienen datos serializados y su final de línea no debe modificarsetests/**/__snapshots__/** binario
Consulte CHANGELOG para obtener más información sobre los cambios recientes.
prueba de compositor
Consulte CONTRIBUCIÓN para obtener más detalles.
Si encuentra un error relacionado con la seguridad, envíe un correo electrónico a [email protected] en lugar de utilizar el rastreador de problemas.
Eres libre de utilizar este paquete, pero si llega a tu entorno de producción, te agradeceremos mucho que nos envíes una postal desde tu ciudad natal, mencionando cuál de nuestros paquetes estás utilizando.
Nuestra dirección es: Spatie, Kruikstraat 22, 2018 Amberes, Bélgica.
Publicamos todas las postales recibidas en el sitio web de nuestra empresa.
Sebastián Deyne
Alex Vanderbist
Todos los contribuyentes
La Licencia MIT (MIT). Consulte el archivo de licencia para obtener más información.