快照測試是一種無需編寫實際測試案例的測試方法。
您可以透過我們的測試 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)。請參閱許可證文件以獲取更多資訊。