快照测试是一种无需编写实际测试用例的测试方法。
您可以通过我们的测试 Laravel 课程的免费视频了解更多信息。不用担心,您也可以在非 Laravel 项目中使用这个包。
使用 SpatieSnapshotsMatchesSnapshots;类 OrderTest {使用 MatchesSnapshots;公共函数 test_it_casts_to_json() {$order = new Order(1);$this->assertMatchesJsonSnapshot($order->toJson()); } }
第一次运行时,测试运行程序将创建一个新快照。
> ./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.
在后续运行中,只要快照不更改,测试就会通过。
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
如果出现回归,测试就会失败!
$orderId = 新订单(2); // 回归!是“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.
我们投入了大量资源来创建一流的开源包。您可以通过购买我们的一款付费产品来支持我们。
我们非常感谢您从家乡寄给我们一张明信片,并注明您正在使用我们的哪种套餐。您可以在我们的联系页面上找到我们的地址。我们在虚拟明信片墙上发布所有收到的明信片。
您可以通过 Composer 安装该软件包:
作曲家需要 --dev spatie/phpunit-snapshot-assertions
要进行快照断言,请在测试用例类中使用SpatieSnapshotsMatchesSnapshots
特征。这向类添加了一组断言方法:
assertMatchesSnapshot($actual)
assertMatchesFileHashSnapshot($actual)
assertMatchesFileSnapshot($actual)
assertMatchesHtmlSnapshot($actual)
assertMatchesJsonSnapshot($actual)
assertMatchesObjectSnapshot($actual)
assertMatchesTextSnapshot($actual)
assertMatchesXmlSnapshot($actual)
assertMatchesYamlSnapshot($actual)
assertMatchesImageSnapshot($actual)
让我们对一个简单的字符串“foo”进行快照断言。
公共函数 test_it_is_foo() {$this->assertMatchesSnapshot('foo'); }
第一次运行断言时,它没有用于比较字符串的快照。测试运行程序生成新快照并将测试标记为未完成。
> ./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.
快照 ID 是根据测试和测试用例的名称生成的。基本快照返回实际值的纯文本或 YAML 表示形式。
富
让我们重新运行测试。测试运行者将看到已经有断言的快照并进行比较。
> ./vendor/bin/phpunit OK (1 test, 1 assertion)
如果我们将实际值更改为“bar”,测试将失败,因为快照仍然返回“foo”。
公共函数 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.
当我们期望值发生变化时,我们需要告诉测试运行者更新现有快照而不是使测试失败。这可以通过在phpunit
命令中添加-d --update-snapshots
标志或将UPDATE_SNAPSHOTS
环境变量设置为true
来实现。
> ./vendor/bin/phpunit -d --update-snapshots OK (1 test, 1 assertion)
结果,我们的快照文件返回“bar”而不是“foo”。
酒吧
MatchesSnapshots
特征提供了两种方法来断言文件与第一次运行测试时创建的快照相同:
assertMatchesFileHashSnapshot($filePath)
断言断言传递到函数中的文件的哈希值与快照中保存的哈希值匹配。该断言速度很快并且使用很少的磁盘空间。这种断言的缺点是,如果测试失败,没有简单的方法可以看出这两个文件有何不同。
assertMatchesFileSnapshot($filePath)
断言的工作方式与文件哈希断言几乎相同,只是它实际上将整个文件保存在快照目录中。如果断言失败,它会将失败的文件放在快照文件旁边,以便可以轻松地手动比较它们。当测试通过时,持久化的失败文件将被自动删除。当处理应手动比较的二进制文件(如图像或 pdf)时,此断言最有用。
assertImageSnapshot
需要安装 spatie/pixelmatch-php 包。
如果给定的图像与第一次运行测试时生成的快照几乎相同,则该断言将通过。您可以通过向断言传递第二个参数来自定义阈值。较高的值将使比较更加敏感。阈值应介于 0 和 1 之间。
$this->assertMatchesImageSnapshot($imagePath, 0.1);
快照 ID 是通过MatchesSnapshot
特征上的getSnapshotId
方法生成的。重写该方法以自定义 id。默认情况下,存在测试名称、测试用例名称和递增值的快照 ID,例如Test__my_test_case__1
。
__
分隔符替换为--
protected function getSnapshotId(): string{return (new ReflectionClass($this))->getShortName().'--'.$this->name().'--'.$this->snapshotIncrementor; }
默认情况下,快照存储在与测试类相关的__snapshots__
目录中。这可以通过重写getSnapshotDirectory
方法来更改。
__snapshots__
目录重命名为snapshots
protected function getSnapshotDirectory(): string{return dirname((new ReflectionClass($this))->getFileName()).DIRECTORY_SEPARATOR.'snapshots'; }
用于序列化数据的驱动程序可以指定为assertMatchesSnapshot
方法的第二个参数,因此您可以选择一个更适合您的需求的驱动程序:
使用 SpatieSnapshotsDriversJsonDriver;使用 SpatieSnapshotsMatchesSnapshots;类 OrderTest {使用 MatchesSnapshots;公共函数 test_snapshot_with_json_driver() {$order = new Order(1);$this->assertMatchesSnapshot($order->toJson(), new JsonDriver()); } }
驱动程序确保不同类型的数据可以按照自己的方式进行序列化和匹配。驱动程序是一个实现SpatieSnapshotsDriver
接口的类,该接口需要三个方法实现: serialize
、 extension
和match
。
让我们快速浏览一下JsonDriver
。
命名空间 SpatieSnapshotsDrivers;使用 PHPUnitFrameworkAssert;使用 SpatieSnapshotsDriver;使用 SpatieSnapshotsExceptionsCantBeSerialized;类 JsonDriver 实现驱动程序 {public function serialize($data): string{if (!is_string($data)) { throw new CantBeSerialized('只有字符串可以序列化为json'); }返回 json_encode(json_decode($data), JSON_PRETTY_PRINT).PHP_EOL; }公共函数扩展(): string{return 'json'; }公共函数匹配($预期,$实际) { 断言::assertJsonStringEqualsJsonString($actual, $expected); } }
serialize
方法返回一个字符串,该字符串将被写入快照文件。在JsonDriver
中,我们将解码并重新编码 json 字符串,以确保快照具有良好的打印效果。
我们希望将 json 快照保存为 json 文件,因此我们将使用json
作为其文件扩展名。
当将预期数据与实际数据进行匹配时,我们希望使用PHPUnit内置的json断言,因此我们将调用特定的assertJsonStringEqualsJsonString
方法。
可以通过将驱动程序作为assertMatchesSnapshot
的第二个参数传递来使用它们。
$this->assertMatchesSnapshot($something->toYaml(), new MyYamlDriver());
在持续集成中运行测试时,您可能希望禁用快照的创建。
通过使用--without-creating-snapshots
参数或将CREATE_SNAPSHOTS
环境变量设置为false
,如果快照不存在,PHPUnit 将失败。
> ./vendor/bin/phpunit -d --without-creating-snapshots 1) 示例测试::test_it_matches_a_string 快照“ExampleTest__test_it_matches_a_string__1.txt”不存在。 您可以通过删除 PHPUnit CLI 参数的“CREATE_SNAPSHOTS=false”环境变量或“-d --no-create-snapshots”来自动创建它。
如果您想使用 Paratest 等工具并行运行测试,或者使用 Laravel 的php artisan test --parallel
命令,则必须使用环境变量。
> CREATE_SNAPSHOTS=false php artisan 测试 --parallel 1) 示例测试::test_it_matches_a_string 快照“ExampleTest__test_it_matches_a_string__1.txt”不存在。 您可以通过删除 PHPUnit CLI 参数的“CREATE_SNAPSHOTS=false”环境变量或“-d --no-create-snapshots”来自动创建它。
Windows 用户应在.gitattributes
中配置行结尾。
# 测试中使用的快照保存序列化数据,其行尾应保持不变tests/**/__snapshots__/** binary
请参阅变更日志以了解最近更改的更多信息。
作曲家测试
详细信息请参阅贡献。
如果您发现有关安全的错误,请发送邮件至 [email protected],而不是使用问题跟踪器。
您可以自由使用这个软件包,但如果它进入您的生产环境,我们非常感谢您从您的家乡给我们寄一张明信片,注明您正在使用我们的哪个软件包。
我们的地址是:Spatie, Kruikstraat 22, 2018 安特卫普, 比利时。
我们在公司网站上发布所有收到的明信片。
塞巴斯蒂安·德·戴因
亚历克斯·范德比斯特
所有贡献者
麻省理工学院许可证 (MIT)。请参阅许可证文件以获取更多信息。