Snapshot-Tests sind eine Möglichkeit zum Testen, ohne tatsächliche Testfälle zu schreiben.
Mehr erfahren Sie in diesem kostenlosen Video aus unserem Testing Laravel-Kurs. Machen Sie sich keine Sorgen, Sie können dieses Paket auch in Nicht-Laravel-Projekten verwenden.
Verwenden Sie SpatieSnapshotsMatchesSnapshots;class OrderTest {use MatchesSnapshots;public function test_it_casts_to_json() {$order = new Order(1);$this->assertMatchesJsonSnapshot($order->toJson()); } }
Beim ersten Durchlauf erstellt der Testläufer einen neuen Snapshot.
> ./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.
Bei nachfolgenden Durchläufen wird der Test bestanden, solange sich der Snapshot nicht ändert.
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
Bei einer Regression schlägt der Test fehl!
$orderId = neue Bestellung(2); // Rückschritt! War „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.
Wir investieren viele Ressourcen in die Erstellung erstklassiger Open-Source-Pakete. Sie können uns unterstützen, indem Sie eines unserer kostenpflichtigen Produkte kaufen.
Wir freuen uns sehr, dass Sie uns eine Postkarte aus Ihrer Heimatstadt schicken und erwähnen, welches unserer Pakete Sie verwenden. Unsere Adresse finden Sie auf unserer Kontaktseite. Wir veröffentlichen alle erhaltenen Postkarten auf unserer virtuellen Postkartenwand.
Sie können das Paket über Composer installieren:
Composer erfordert --dev spatie/phpunit-snapshot-assertions
Um Snapshot-Behauptungen zu erstellen, verwenden Sie das Merkmal SpatieSnapshotsMatchesSnapshots
in Ihrer Testfallklasse. Dadurch wird der Klasse eine Reihe von Assertionsmethoden hinzugefügt:
assertMatchesSnapshot($actual)
assertMatchesFileHashSnapshot($actual)
assertMatchesFileSnapshot($actual)
assertMatchesHtmlSnapshot($actual)
assertMatchesJsonSnapshot($actual)
assertMatchesObjectSnapshot($actual)
assertMatchesTextSnapshot($actual)
assertMatchesXmlSnapshot($actual)
assertMatchesYamlSnapshot($actual)
assertMatchesImageSnapshot($actual)
Lassen Sie uns eine Snapshot-Behauptung für eine einfache Zeichenfolge erstellen, „foo“.
öffentliche Funktion test_it_is_foo() {$this->assertMatchesSnapshot('foo'); }
Wenn die Behauptung zum ersten Mal ausgeführt wird, gibt es keinen Snapshot, mit dem die Zeichenfolge verglichen werden kann. Der Testläufer generiert einen neuen Snapshot und markiert den Test als unvollständig.
> ./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.
Snapshot-IDs werden basierend auf den Namen des Tests und des Testfalls generiert. Einfache Snapshots geben eine Klartext- oder YAML-Darstellung des tatsächlichen Werts zurück.
foo
Lassen Sie uns den Test noch einmal durchführen. Der Testläufer erkennt, dass für die Behauptung bereits ein Snapshot vorhanden ist, und führt einen Vergleich durch.
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
Wenn wir den tatsächlichen Wert in „bar“ ändern, schlägt der Test fehl, da der Snapshot immer noch „foo“ zurückgibt.
öffentliche Funktion 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.
Wenn wir einen geänderten Wert erwarten, müssen wir den Testläufer anweisen, die vorhandenen Snapshots zu aktualisieren, anstatt den Test nicht zu bestehen. Dies ist möglich, indem Sie dem Befehl phpunit
das Flag -d --update-snapshots
hinzufügen oder die Umgebungsvariable UPDATE_SNAPSHOTS
auf true
setzen.
> ./vendor/bin/phpunit -d --update-snapshots OK (1 test, 1 assertion)
Infolgedessen gibt unsere Snapshot-Datei „bar“ anstelle von „foo“ zurück.
Bar
Das Merkmal MatchesSnapshots
bietet zwei Möglichkeiten, um sicherzustellen, dass eine Datei mit dem Snapshot identisch ist, der bei der ersten Ausführung des Tests erstellt wurde:
Die Behauptung assertMatchesFileHashSnapshot($filePath)
bestätigt, dass der Hash der an die Funktion übergebenen Datei und der im Snapshot gespeicherte Hash übereinstimmen. Diese Behauptung ist schnell und verbraucht sehr wenig Speicherplatz. Der Nachteil dieser Behauptung besteht darin, dass es keine einfache Möglichkeit gibt, den Unterschied zwischen den beiden Dateien zu erkennen, wenn der Test fehlschlägt.
Die Assertion assertMatchesFileSnapshot($filePath)
funktioniert fast auf die gleiche Weise wie die Datei-Hash-Assertion, außer dass sie tatsächlich die gesamte Datei im Snapshots-Verzeichnis speichert. Wenn die Behauptung fehlschlägt, wird die fehlgeschlagene Datei neben der Snapshot-Datei platziert, sodass sie einfach manuell verglichen werden kann. Die persistente fehlgeschlagene Datei wird automatisch gelöscht, wenn der Test erfolgreich ist. Diese Behauptung ist am nützlichsten, wenn Sie mit Binärdateien arbeiten, die manuell verglichen werden sollen, wie z. B. Bilder oder PDFs.
Für den assertImageSnapshot
muss das Paket spatie/pixelmatch-php installiert sein.
Diese Behauptung wird bestanden, wenn das angegebene Bild nahezu identisch mit dem Schnappschuss ist, der bei der ersten Ausführung des Tests erstellt wurde. Sie können den Schwellenwert anpassen, indem Sie der Behauptung ein zweites Argument übergeben. Höhere Werte machen den Vergleich empfindlicher. Der Schwellenwert sollte zwischen 0 und 1 liegen.
$this->assertMatchesImageSnapshot($imagePath, 0.1);
Snapshot-IDs werden über die getSnapshotId
-Methode für das MatchesSnapshot
Merkmal generiert. Überschreiben Sie die Methode, um die ID anzupassen. Standardmäßig besteht eine Snapshot-ID aus dem Testnamen, dem Testfallnamen und einem inkrementierenden Wert, z. B. Test__my_test_case__1
.
__
Trennzeichens durch --
protected function getSnapshotId(): string{return (new ReflectionClass($this))->getShortName().'--'.$this->name().'--'.$this->snapshotIncrementor; }
Snapshots werden standardmäßig in einem __snapshots__
Verzeichnis relativ zur Testklasse gespeichert. Dies kann durch Überschreiben der getSnapshotDirectory
-Methode geändert werden.
__snapshots__
in snapshots
protected function getSnapshotDirectory(): string{return dirname((new ReflectionClass($this))->getFileName()).DIRECTORY_SEPARATOR.'snapshots'; }
Der zum Serialisieren der Daten verwendete Treiber kann als zweites Argument der Methode assertMatchesSnapshot
angegeben werden, sodass Sie einen auswählen können, der Ihren Anforderungen besser entspricht:
verwende SpatieSnapshotsDriversJsonDriver; verwende SpatieSnapshotsMatchesSnapshots; Klasse OrderTest {use MatchesSnapshots;public function test_snapshot_with_json_driver() {$order = new Order(1);$this->assertMatchesSnapshot($order->toJson(), new JsonDriver()); } }
Treiber stellen sicher, dass verschiedene Datentypen auf ihre eigene Weise serialisiert und abgeglichen werden können. Ein Treiber ist eine Klasse, die die SpatieSnapshotsDriver
Schnittstelle implementiert, die drei Methodenimplementierungen erfordert: serialize
, extension
und match
.
Werfen wir einen kurzen Blick auf den JsonDriver
.
Namespace SpatieSnapshotsDrivers; PHPUnitFrameworkAssert verwenden; SpatieSnapshotsDriver verwenden; SpatieSnapshotsExceptionsCantBeSerialized verwenden; Klasse JsonDriver implementiert Treiber {public function serialize($data): string{if (! is_string($data)) {throw new CantBeSerialized('Nur Strings können nach JSON serialisiert werden'); }return json_encode(json_decode($data), JSON_PRETTY_PRINT).PHP_EOL; }public function extension(): string{return 'json'; }public function match($expected, $actual) { Assert::assertJsonStringEqualsJsonString($actual, $expected); } }
Die serialize
gibt eine Zeichenfolge zurück, die in die Snapshot-Datei geschrieben wird. Im JsonDriver
dekodieren wir die JSON-Zeichenfolge und kodieren sie erneut, um sicherzustellen, dass der Snapshot gut gedruckt wird.
Wir möchten JSON-Snapshots als JSON-Dateien speichern, daher verwenden wir json
als Dateierweiterung.
Beim Abgleich der erwarteten Daten mit den tatsächlichen Daten möchten wir die integrierten JSON-Assertionen von PHPUnit verwenden, daher rufen wir die spezifische Methode assertJsonStringEqualsJsonString
auf.
Treiber können verwendet werden, indem sie als zweites Argument von assertMatchesSnapshot
“ übergeben werden.
$this->assertMatchesSnapshot($something->toYaml(), new MyYamlDriver());
Wenn Sie Ihre Tests in Continuous Integration ausführen, möchten Sie möglicherweise die Erstellung von Snapshots deaktivieren.
Wenn Sie den Parameter --without-creating-snapshots
verwenden oder die Umgebungsvariable CREATE_SNAPSHOTS
auf false
setzen, schlägt PHPUnit fehl, wenn die Snapshots nicht vorhanden sind.
> ./vendor/bin/phpunit -d --without-creating-snapshots 1) BeispielTest::test_it_matches_a_string Snapshot „ExampleTest__test_it_matches_a_string__1.txt“ existiert nicht. Sie können es automatisch erstellen, indem Sie die Umgebungsvariable „CREATE_SNAPSHOTS=false“ oder „-d --no-create-snapshots“ der CLI-Argumente von PHPUnit entfernen.
Wenn Sie Ihren Test parallel mit einem Tool wie Paratest oder dem Befehl php artisan test --parallel
von Laravel ausführen möchten, müssen Sie die Umgebungsvariablen verwenden.
> CREATE_SNAPSHOTS=false php artisan test --parallel 1) BeispielTest::test_it_matches_a_string Snapshot „ExampleTest__test_it_matches_a_string__1.txt“ existiert nicht. Sie können es automatisch erstellen, indem Sie die Umgebungsvariable „CREATE_SNAPSHOTS=false“ oder „-d --no-create-snapshots“ der CLI-Argumente von PHPUnit entfernen.
Windows-Benutzer sollten ihre Zeilenenden in .gitattributes
konfigurieren.
# In Tests verwendete Snapshots enthalten serialisierte Daten und ihr Zeilenende sollte unverändert bleibentests/**/__snapshots__/** binär
Weitere Informationen zu den letzten Änderungen finden Sie im CHANGELOG.
Komponistentest
Weitere Informationen finden Sie unter BEITRAGEN.
Wenn Sie einen Sicherheitsfehler gefunden haben, senden Sie bitte eine E-Mail an [email protected], anstatt den Issue-Tracker zu verwenden.
Es steht Ihnen frei, dieses Paket zu verwenden, aber wenn es in Ihre Produktionsumgebung gelangt, würden wir uns sehr freuen, wenn Sie uns eine Postkarte aus Ihrer Heimatstadt schicken und erwähnen, welches unserer Pakete Sie verwenden.
Unsere Adresse lautet: Spatie, Kruikstraat 22, 2018 Antwerpen, Belgien.
Wir veröffentlichen alle erhaltenen Postkarten auf unserer Firmenwebsite.
Sebastian De Deyne
Alex Vanderbist
Alle Mitwirkenden
Die MIT-Lizenz (MIT). Weitere Informationen finden Sie in der Lizenzdatei.