測試的重要性就不在這里贅述了,本篇重點想聊一下Flutter的Widget測試(其他框架稱為組件測試)中的Golden File test。
那么什么是Golden File Test呢?
Golden File Testing are like unit tests, except the expected output is stored in a separate file. -- Max Grigorev at ZuriHac
如果有前端經(jīng)驗的童鞋可以理解Flutter的Golden File Testing相當(dāng)于Jest的快照測試。Flutter將期望的結(jié)果存儲在圖片文件(Golden Image)中。
Widget測試的目標(biāo)是驗證小部件的UI如預(yù)期那樣的外觀和交互。所以Golden File Testing 不等價Widget測試,但通過它可以很方便的測試Widget的UI是否如預(yù)期的外觀一致。
Golden File Test怎么寫,官方有很多例子,這里就不細(xì)講。
和快照測試類似,工作流程如下:

- 第一次生成Golden Image
- 人工檢查圖片,更新對比基線
- 當(dāng)產(chǎn)品代碼發(fā)生改變時,再次運行測試,測試通過Finder找到當(dāng)前Widget,通過expectLater與基線進(jìn)行對比
- 如果測試通過,并且UI預(yù)期不變,測試通過
- 如果測試通過,并且UI預(yù)期需要變,測試失敗,需找出原因并修復(fù)
- 如果測試失敗,并且UI預(yù)期不變,測試失敗,需找出原因并修復(fù)
- 如果測試失敗,并且UI預(yù)期需要變,人工檢查圖片是否與預(yù)期一致,
- 如果是,則更新對比基線
- 如果否,需找出原因并修復(fù)
在整個工作流程中,有3個關(guān)鍵點:
- 怎么更新基線的?
- 第一張golden image是怎么生成的?
- 對比時是怎么對比的?
那我們接下來一個一個的看這三個問題。
- 怎么更新基線的?
生成和更新基線,F(xiàn)lutter提供了命令行:
flutter test --update-goldens
只跑某個測試文件可以指定文件路徑:
flutter test --update-goldens <path_to_test_file>
不實用--update-goldens參數(shù),會直接生成新的圖片
通過它,可以在運行測試的同時,生成/更新圖片。

- 第一張golden image是怎么生成的?
理解以下內(nèi)容,需要對Flutter 渲染流程及相關(guān)的概念有了解,此處贅述,如果不了解請移步
architectural-overview
element
render object
isRepaintBoundary, layer
scene
當(dāng)測試在執(zhí)行斷言的過程:
- 通過
expectLater第一個參數(shù)找到的element - 將element對應(yīng)的
render object所在最近的RepaintBoundary以下的內(nèi)容在engine中合成到scene里 - Flutter engine 在后臺線程上執(zhí)行創(chuàng)建柵格圖像(這個過程很慢),將未壓縮的原始RGBA字節(jié)輸出到圖片中
- 將圖片保存到指定路徑


- 對比時是怎么對比的?
LocalFileComparator是flutter提供的默認(rèn)對比器,用于根據(jù)渲染創(chuàng)建/更新磁盤上的圖片文件。當(dāng)跑測試時,它會先將編碼后的圖片從系統(tǒng)文件中讀取到內(nèi)存,然后進(jìn)行像素對比。如果像素完全相同,則返回true。但是需注意的是,技術(shù)圖片像素相同,而圖片編碼方式不同,測試也會返回false。
compare
根據(jù)需要,可以繼承LocalFileComparator并復(fù)寫的compare和update方法得到你想要的對比器,并通過flutter_test_config.dart指定對比器。
了解Flutter Golden File Test的原理,可以幫組我們更好的去思考什么時候需要使用它。
