lucatume / codeception-snapshot-assertions
Codeception的快照断言糖语法。
Requires
- php: ^8.0
- ext-dom: *
- codeception/codeception: ^5.0
- gajus/dindent: ^2.0
Requires (Dev)
- phpstan/phpstan: ^1.10.19
- squizlabs/php_codesniffer: *
This package is auto-updated.
Last update: 2024-09-14 17:16:30 UTC
README
利用Codeception的快照支持,使Codeception项目中的快照测试更加容易。
代码示例
<?php class WidgetTest extends Codeception\TestCase\Test { use tad\Codeception\SnapshotAssertions\SnapshotAssertions; public function testDefaultContent(){ $widget = new Widget() ; $this->assertMatchesHtmlSnapshot($widget->html()); } public function testOutput(){ $widget = new Widget(['title' => 'Test Widget', 'content' => 'Some test content']) ; $this->assertMatchesHtmlSnapshot($widget->html()); } }
需求
此包基于Codeception自2.5.0版本以来添加的快照支持,因此库的要求如下:
- PHP 5.6+
- Codeception 2.5+
安装
使用Composer安装此包
composer install lucatume/codeception-snapshot-assertions
Codeception是该包运行的要求之一,如果没有在项目的Composer配置文件(composer.json
)中指定,它将被作为依赖项安装。
什么是快照测试?
快照测试是测试代码输出的便捷方式。
快照测试比完整的视觉端到端测试(但这不是替代品)更快,但比低级别的单元测试(同样不是替代品)更容易编写。
这种测试适合用于单元和集成测试来自动化输出测试。
关于快照测试的更多信息请在此处阅读
这与Codeception所做的有何不同?
- 快照不需要编写专门的类,您只需在测试用例中
use
tad\Codeception\SnapshotAssertions\SnapshotAssertions
trait并提供的一个assertMatches...
方法即可。 - 它也支持字符串和HTML快照测试。
- 代码生成的快照存储在与它们相同的文件夹中,即生成的文件夹中的
__snapshots__
。
这与Spatie包有何不同?
- 它利用了Codeception自己的快照实现,因此它将不会在纯PhpUnit上工作
- 它将库要求从PHP 7.0降低到PHP 5.6。
用法
该包支持以下类型的断言:
- 字符串快照断言,使用
assertMatchesStringSnapshot
方法将字符串与字符串快照进行比较。 - HTML快照断言,使用
assertMatchesHtmlSnapshot
方法将HTML片段与HTML片段快照进行比较。 - JSON快照断言,使用
assertMatchesJsonSnapshot
方法将JSON字符串与存储的JSON快照进行比较。 - 代码快照断言,使用
assertMatchesCodeSnapshot
方法将代码与存储的代码快照进行比较。
首次调用assert...
方法时,库将在与测试相同的目录中生成一个快照文件,在__snapshots__
文件夹中。
例如,如果以下测试用例位于tests/Output/WidgetTest.php
文件中,那么当testDefaultContent
方法运行时,库将生成tests/Output/WidgetTest__testDefaultContent__0.snapshot.html
文件;您可以通过在调试模式下运行Codeception测试来重新生成失败的快照(使用run
命令的--debug
标志)。
配置
该库与Codeception配置系统集成,允许设置一些配置选项。
- 该库支持两个配置参数:
version
(字符串):将作为快照文件名的前缀;默认为空字符串(``)。
refresh
(布尔值):在失败时自动强制重新生成快照;默认为false
。
# Codeception own configuration paths: tests: tests output: tests/_output data: tests/_data support: tests/_support envs: tests/_envs actor_suffix: Tester extensions: enabled: - Codeception\Extension\RunFailed # Snapshot configuration snapshot: version: 23 refresh: true
配置参数可以在codeception.yml
或codeception.dist.yml
文件中的snapshot
键下设置,如下所示
版本
<?php use Codeception\Test\Unit; class WidgetTest extends Unit { public function testDefaultContent():void { $widget = new Widget() ; $this->assertMatchesHtmlSnapshot($widget->html()); } }
如果将version
字符串设置为非空值,则快照文件名将添加该前缀。在以下示例中,version
参数设置为alt
,快照文件名将为WidgetTest__alt__testDefaultContent__alt.snapshot.html
如果未设置version
参数,或设置为空字符串,则快照文件名将不添加任何前缀,并将为WidgetTest__testDefaultContent__0.snapshot.html
刷新
如果将refresh
参数设置为true
,则在失败时将自动重新生成快照。通常,Codeception快照通过在调试模式下运行测试(使用run
命令的--debug
标志)并回复提示是否重新生成快照;或者手动删除快照文件来重新生成。如果将refresh
参数设置为true
,则在失败时将自动重新生成快照,无需提示,如果当前测试运行在调试模式下。
字符串断言
当方法输出为纯文本字符串时,此类断言很有用。
此类断言产生的快照将具有.snapshot.txt
文件扩展名。
用于制作字符串快照断言的方法是tad\Codeception\SnapshotAssertions\SnapshotAssertions::assertStringSnapshot()
。
<?php class ErrorMessageTest extends Codeception\TestCase\Test { use tad\Codeception\SnapshotAssertions\SnapshotAssertions; public function testClassAndMethodOutput(){ $errorMessage = new ErrorMessage(__CLASS__, 'foo') ; $this->assertMatchesStringSnapshot($errorMessage->message()); } public function testClassOnlyOutput(){ $errorMessage = new ErrorMessage(__CLASS__) ; $this->assertMatchesStringSnapshot($errorMessage->message()); } }
使用示例
HTML断言
当方法输出为HTML文档或HTML片段时,此类断言很有用。
此类断言产生的快照将具有.snapshot.html
文件扩展名。
用于制作字符串快照断言的方法是tad\Codeception\SnapshotAssertions\SnapshotAssertions::assertStringSnapshot()
。
<?php class WidgetTest extends Codeception\TestCase\Test { use tad\Codeception\SnapshotAssertions\SnapshotAssertions; public function testDefaultContent(){ $widget = new Widget() ; $this->assertMatchesHtmlSnapshot($widget->html()); } public function testOutput(){ $widget = new Widget(['title' => 'Test Widget', 'content' => 'Some test content']) ; $this->assertMatchesHtmlSnapshot($widget->html()); } }
用于制作HTML快照断言的方法是tad\Codeception\SnapshotAssertions\SnapshotAssertions::assertHtmlSnapshot()
。
JSON断言
当方法输出为HTML文档或HTML片段时,此类断言很有用。
当方法输出为JSON字符串时,此类断言很有用。
用于制作JSON快照断言的方法是tad\Codeception\SnapshotAssertions\SnapshotAssertions::assertJsonSnapshot()
。
<?php class ApiTest extends Codeception\TestCase\Test { use tad\Codeception\SnapshotAssertions\SnapshotAssertions; public function testGoodResponse(){ $this->givenTheUserIsAuthenticated(); $request = new Request([ 'me' => [ 'name' ] ]); $api = new API() ; $this->assertMatchesJsonSnapshot($api->handle($request)); } public function testMissingAuthResponse(){ $request = new Request([ 'me' => [ 'name' ] ]); $api = new API() ; $this->assertMatchesJsonSnapshot($api->handle($request)); } }
使用示例
代码断言
当方法输出为代码时,此类断言很有用。
此类断言产生的快照将默认具有.snapshot.php
文件扩展名,但您可以指定用于快照的扩展名。
用于制作字符串快照断言的方法是tad\Codeception\SnapshotAssertions\SnapshotAssertions::assertStringSnapshot()
。
<?php class ApiTest extends Codeception\TestCase\Test { use tad\Codeception\SnapshotAssertions\SnapshotAssertions; public function testGoodCode(){ $generator = new CodeGenerator(); $code = $generator->produce('phpCode'); $this->assertMatchesCodeSnapshot($code); } public function testMissingAuthResponse(){ $generator = new CodeGenerator(); $code = $generator->produce('jsCode'); $this->assertMatchesCodeSnapshot($code); } }
用于制作代码快照断言的方法是tad\Codeception\SnapshotAssertions\SnapshotAssertions::assertCodeSnapshot()
。
目录断言
当代码块输出为目录及其文件时,此类断言很有用,以确保目录结构和内容在一段时间内不发生变化。
此断言将检查当前目录和快照中捕获的目录具有相同的文件,以及每个文件的内容相同。
此类断言产生的快照将具有.snapshot
文件扩展名;它们是纯文本文件。
用于制作字符串快照断言的方法是tad\Codeception\SnapshotAssertions\SnapshotAssertions::assertStringSnapshot()
。
<?php class DirectorySetupTest extends Codeception\TestCase\Test { use tad\Codeception\SnapshotAssertions\SnapshotAssertions; public function testGoodDirectorySetUp(){ $generator = new DirectorySetup(); $destination = codecept_output_dir('test'); $generator->setUpDirectory('test', $destination ); $this->assertMatchesDirectorySnapshot($destination); } public function testFailingDirectorySetUp(){ $generator = new DirectorySetup(); $destination = codecept_output_dir('failing'); $generator->setUpDirectory('failing', $destination ); $this->assertMatchesDirectorySnapshot($destination); } }
用于制作代码快照断言的方法是tad\Codeception\SnapshotAssertions\SnapshotAssertions::assertDirectorySnapshot()
。
访问者函数
为了允许更精细地控制对数据进行的断言方式,每个快照实现都支持“数据访问者”。
数据访问者是一个callable
,它将从快照实现接收预期数据和当前数据。
根据快照类型,回调接收到的参数可能不同或超过两个。
在以下示例中,数据访客被用来从目录快照中排除一些文件,并从某些文件中丢弃一些散列行
<?php public function test_files(){ $dataVisitor = static function ($expected, $current, $pathName) { if (strpos($pathName, 'fileOne')) { // Empty file one, like dropping it. return [[], []]; } if (strpos($pathName, 'fileTwo')) { // Remove the hash line in file two. $removeHashLine = static function ($line) { return !preg_match('/\\/\\/\\s*\\[HASH].*$/uim', $line); }; return [ array_filter($expected, $removeHashLine), array_filter($current, $removeHashLine) ]; } return [$expected, $current]; }; $dirToTest = codecept_output('dir-to-test'); $snapshot = new DirectorySnapshot($dirToTest); $snapshot->setDataVisitor($dataVisitor); $snapshot->assert(); }
在这个示例中,数据访客被用来从JSON对象中移除一些散列数据
<?php public function test_json_object(){ $removeHashEntry = static function ($jsonString) { // Remove the `hash` key from the JSON object. return json_encode(array_diff_key(json_decode($jsonString, true), array_flip(['hash']))); }; $dataVisitor = static function ($expected, $current) use ($removeHashEntry) { return array_map($removeHashEntry, [$expected, $current]); }; // This first snapshot will create the first HTML snapshot. $firstSnapshot = new JsonSnapshot(MyJsonProducingObject::data()); $firstSnapshot->setDataVisitor($dataVisitor); $firstSnapshot->assert(); }