O teste de instantâneo é uma forma de testar sem escrever casos de teste reais.
Você pode aprender mais neste vídeo gratuito do nosso curso Testando Laravel. Não se preocupe, você também pode usar este pacote em projetos que não sejam do Laravel.
usar SpatieSnapshotsMatchesSnapshots;classe OrderTest {use MatchesSnapshots;função pública test_it_casts_to_json() {$order = new Order(1);$this->assertMatchesJsonSnapshot($order->toJson()); } }
Na primeira execução, o executor de teste criará um novo instantâneo.
> ./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.
Nas execuções subsequentes, o teste será aprovado desde que o instantâneo não seja alterado.
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
Se houver uma regressão, o teste falhará!
$orderId = novo pedido(2); // Regressão! 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.
Investimos muitos recursos na criação dos melhores pacotes de código aberto. Você pode nos apoiar comprando um de nossos produtos pagos.
Agradecemos muito que você nos envie um cartão postal de sua cidade natal, mencionando qual(is) de nossos pacotes você está usando. Você encontrará nosso endereço em nossa página de contato. Publicamos todos os cartões postais recebidos em nosso mural virtual de cartões postais.
Você pode instalar o pacote via compositor:
compositor requer --dev spatie/phpunit-snapshot-assertions
Para fazer asserções de instantâneo, use o atributo SpatieSnapshotsMatchesSnapshots
em sua classe de caso de teste. Isso adiciona um conjunto de métodos de asserção à classe:
assertMatchesSnapshot($actual)
assertMatchesFileHashSnapshot($actual)
assertMatchesFileSnapshot($actual)
assertMatchesHtmlSnapshot($actual)
assertMatchesJsonSnapshot($actual)
assertMatchesObjectSnapshot($actual)
assertMatchesTextSnapshot($actual)
assertMatchesXmlSnapshot($actual)
assertMatchesYamlSnapshot($actual)
assertMatchesImageSnapshot($actual)
Vamos fazer uma asserção instantânea para uma string simples, "foo".
função pública test_it_is_foo() {$this->assertMatchesSnapshot('foo'); }
Na primeira vez que a asserção é executada, ela não possui um instantâneo para comparar a string. O executor de teste gera um novo instantâneo e marca o teste como incompleto.
> ./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.
Os IDs de instantâneo são gerados com base nos nomes do teste e do caso de teste. Os instantâneos básicos retornam um texto simples ou uma representação YAML do valor real.
foo
Vamos refazer o teste. O executor de teste verá que já existe um instantâneo da afirmação e fará uma comparação.
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
Se alterarmos o valor real para “bar”, o teste falhará porque o instantâneo ainda retorna “foo”.
função 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.
Quando esperamos um valor alterado, precisamos informar ao executor de teste para atualizar os instantâneos existentes em vez de falhar no teste. Isso é possível adicionando um sinalizador -d --update-snapshots
ao comando phpunit
ou definindo UPDATE_SNAPSHOTS
env var como true
.
> ./vendor/bin/phpunit -d --update-snapshots OK (1 test, 1 assertion)
Como resultado, nosso arquivo de snapshot retorna “bar” em vez de “foo”.
bar
O atributo MatchesSnapshots
oferece duas maneiras de afirmar que um arquivo é idêntico ao instantâneo que foi feito na primeira vez que o teste foi executado:
A afirmação assertMatchesFileHashSnapshot($filePath)
afirma que o hash do arquivo passado para a função e o hash salvo no instantâneo correspondem. Esta afirmação é rápida e utiliza muito pouco espaço em disco. A desvantagem dessa afirmação é que não há uma maneira fácil de ver como os dois arquivos diferem se o teste falhar.
A asserção assertMatchesFileSnapshot($filePath)
funciona quase da mesma maneira que a asserção de hash do arquivo, exceto que na verdade salva o arquivo inteiro no diretório de snapshots. Se a asserção falhar, ela colocará o arquivo com falha próximo ao arquivo de instantâneo para que possam ser facilmente comparados manualmente. O arquivo com falha persistente é excluído automaticamente quando o teste é aprovado. Esta afirmação é mais útil ao trabalhar com arquivos binários que devem ser comparados manualmente como imagens ou PDFs.
O assertImageSnapshot
requer que o pacote spatie/pixelmatch-php seja instalado.
Esta afirmação será aprovada se a imagem fornecida for quase idêntica ao instantâneo feito na primeira vez que o teste foi executado. Você pode personalizar o limite passando um segundo argumento para a asserção. Valores mais altos tornarão a comparação mais sensível. O limite deve estar entre 0 e 1.
$this->assertMatchesImageSnapshot($imagePath, 0.1);
Os IDs de instantâneo são gerados por meio do método getSnapshotId
na característica MatchesSnapshot
. Substitua o método para personalizar o ID. Por padrão, existe um ID de instantâneo do nome do teste, o nome do caso de teste e um valor incremental, por exemplo, Test__my_test_case__1
.
__
por --
função protegida getSnapshotId(): string{return (new ReflectionClass($this))->getShortName().'--'.$this->name().'--'.$this->snapshotIncrementor; }
Por padrão, os snapshots são armazenados em um diretório __snapshots__
relativo à classe de teste. Isso pode ser alterado substituindo o método getSnapshotDirectory
.
__snapshots__
para snapshots
função protegida getSnapshotDirectory(): string{return dirname((new ReflectionClass($this))->getFileName()).DIRECTORY_SEPARATOR.'snapshots'; }
O driver usado para serializar os dados pode ser especificado como segundo argumento do método assertMatchesSnapshot
, para que você possa escolher aquele que melhor atenda às suas necessidades:
usar SpatieSnapshotsDriversJsonDriver; usar SpatieSnapshotsMatchesSnapshots;class OrderTest {use MatchesSnapshots;função pública test_snapshot_with_json_driver() {$order = new Order(1);$this->assertMatchesSnapshot($order->toJson(), new JsonDriver()); } }
Os drivers garantem que diferentes tipos de dados possam ser serializados e combinados à sua maneira. Um driver é uma classe que implementa a interface SpatieSnapshotsDriver
, que requer três implementações de métodos: serialize
, extension
e match
.
Vamos dar uma olhada rápida no JsonDriver
.
namespace SpatieSnapshotsDrivers; usar PHPUnitFrameworkAssert; usar SpatieSnapshotsDriver; usar SpatieSnapshotsExceptionsCantBeSerialized; classe JsonDriver implementa Driver {função pública serialize($data): string{if (! is_string($data)) {throw new CantBeSerialized('Apenas strings podem ser serializadas para json'); }retornar json_encode(json_decode($data), JSON_PRETTY_PRINT).PHP_EOL; }extensão de função pública(): string{return 'json'; }correspondência de função pública($esperado, $real) { Assert::assertJsonStringEqualsJsonString($real, $esperado); } }
O método serialize
retorna uma string que será gravada no arquivo de snapshot. No JsonDriver
, decodificaremos e recodificaremos a string json para garantir que o instantâneo tenha uma impressão bonita.
Queremos salvar instantâneos json como arquivos json, então usaremos json
como extensão de arquivo.
Ao combinar os dados esperados com os dados reais, queremos usar as asserções json integradas do PHPUnit, então chamaremos o método específico assertJsonStringEqualsJsonString
.
Os drivers podem ser usados passando-os como o segundo argumento de assertMatchesSnapshot
.
$this->assertMatchesSnapshot($something->toYaml(), new MyYamlDriver());
Ao executar seus testes em Integração Contínua você possivelmente desejará desabilitar a criação de snapshots.
Usando o parâmetro --without-creating-snapshots
ou definindo CREATE_SNAPSHOTS
env var como false
, o PHPUnit falhará se os snapshots não existirem.
> ./vendor/bin/phpunit -d --sem criar instantâneos 1) ExemploTeste::test_it_matches_a_string O instantâneo "ExampleTest__test_it_matches_a_string__1.txt" não existe. Você pode criá-lo automaticamente removendo o env var `CREATE_SNAPSHOTS=false` ou `-d --no-create-snapshots` dos argumentos CLI do PHPUnit.
Se você quiser rodar seu teste em paralelo com uma ferramenta como o Paratest, ou com o comando php artisan test --parallel
do Laravel, você terá que usar as variáveis de ambiente.
> CREATE_SNAPSHOTS=falso teste de artesão php --parallel 1) ExemploTeste::test_it_matches_a_string O instantâneo "ExampleTest__test_it_matches_a_string__1.txt" não existe. Você pode criá-lo automaticamente removendo o env var `CREATE_SNAPSHOTS=false` ou `-d --no-create-snapshots` dos argumentos CLI do PHPUnit.
Os usuários do Windows devem configurar seus finais de linha em .gitattributes
.
# Snapshots usados em testes contêm dados serializados e seu final de linha deve ser deixado inalteradotests/**/__snapshots__/** binary
Consulte CHANGELOG para obter mais informações sobre o que mudou recentemente.
teste de compositor
Consulte CONTRIBUINDO para obter detalhes.
Se você encontrou um bug relacionado à segurança, envie um email para [email protected] em vez de usar o rastreador de problemas.
Você é livre para usar este pacote, mas se ele chegar ao seu ambiente de produção, agradecemos muito que você nos envie um cartão postal de sua cidade natal, mencionando quais de nossos pacotes você está usando.
Nosso endereço é: Spatie, Kruikstraat 22, 2018 Antuérpia, Bélgica.
Publicamos todos os cartões postais recebidos no site da nossa empresa.
Sebastião De Deyne
Alex Vanderbist
Todos os colaboradores
A licença MIT (MIT). Consulte Arquivo de licença para obter mais informações.