圖像對(duì)比在UI測(cè)試中的實(shí)踐-故事篇

這是一份在UI自動(dòng)化測(cè)試中使用圖像對(duì)比的實(shí)踐分享厚满,分為故事篇技術(shù)篇兩部分碧磅,故事篇會(huì)首先回顧這幾年在視覺(jué)測(cè)試上的歷程,技術(shù)篇?jiǎng)t會(huì)介紹一些視覺(jué)測(cè)試上的技術(shù)總結(jié)丰榴。

六年前剛?cè)肼毜絋houghtWorks成都辦公室后货邓,第一次參加QA社區(qū)的Catch Up四濒,那時(shí)的我在新環(huán)境中還分不清誰(shuí)是張三誰(shuí)是李四。 會(huì)上戈二,依稀記得有兩位貌似道行深厚的人物喳资,就某個(gè)工具的使用反饋觉吭,詢(xún)問(wèn)在座的眾生骨饿,現(xiàn)場(chǎng)一片寂靜亏栈。會(huì)后宏赘,回到組上,我好奇的 問(wèn)了一下我們的TL(請(qǐng)?jiān)试S這里隱去TA的名字察署,不然我多半會(huì)被懟的)那是什么東西、我們有沒(méi)有使用峻汉,面對(duì)TL一番風(fēng)卷殘?jiān)频?介紹贴汪,作為剛剛從通訊行業(yè)跨入互聯(lián)網(wǎng)行業(yè)才三天的菜鳥(niǎo)休吠,小的我真的是屁都沒(méi)聽(tīng)懂扳埂,唯一聽(tīng)明白并且記下來(lái)的就是“它還需要部署服務(wù)器瘤礁,很難用”。

那個(gè)工具的名字叫做Viff柜思,在后來(lái)很長(zhǎng)的一段時(shí)間內(nèi)岩调,我仍然不知道它是干嘛的赡盘,而這,就是我第一次和UI測(cè)試中的圖像對(duì)比的擦肩而過(guò)陨享。

一不小心,摸到了圖像對(duì)比的大門(mén)

有時(shí)候蛙紫,接觸某種技術(shù)、思考某種解決方案坑傅,靠的真不是大咖的演講,而就是那么點(diǎn)兒緣分和靈光一現(xiàn)蒜茴。

時(shí)間來(lái)到2016年10月浆西,某澳洲項(xiàng)目S。有一次近零,從王小禮的桌旁溜過(guò)久信,看她一副愁眉苦臉、生無(wú)可戀的樣子裙士,就猜到多半有”戲”腿椎。本著有“戲”大家樂(lè)的心態(tài)啃炸,隨便打聽(tīng)了一下南用。 原來(lái),她們組最近在給客戶(hù)做產(chǎn)品換膚托修。了解S項(xiàng)目的同學(xué)應(yīng)該都知道睦刃,客戶(hù)是一個(gè)集團(tuán)企業(yè)十酣,旗下有八九個(gè)品牌,所以通常一個(gè)產(chǎn)品就會(huì)有八九套UI兴泥。 而她們組在做的,就是給其中的多個(gè)品牌同時(shí)換膚如绸。面對(duì)每天都在變化的UI,有時(shí)甚至是往復(fù)修改的CSS旭贬,別說(shuō)寫(xiě)自動(dòng)化測(cè)試了稀轨,每張卡的人肉檢查早都已經(jīng)應(yīng)接不暇了瓦侮。

當(dāng)時(shí)的閑聊中肚吏,我提到的建議是台谍,不知道有沒(méi)有什么工具能幫著檢查這類(lèi)UI快速變更的頁(yè)面。下來(lái)再琢磨這個(gè)問(wèn)題仔役,經(jīng)過(guò)一番折騰,最終發(fā)現(xiàn)原來(lái)有種手段叫做“Visual Regression Testing”又兵。

至于后來(lái)王小禮是怎么熬出她們的品牌換膚的任柜,我就不知道咯宙地,阿彌陀佛~

出師未捷身先死

既然摸到了圖像對(duì)比的大門(mén)电谣,不進(jìn)去搗騰搗騰企垦,就說(shuō)不過(guò)去了是吧!當(dāng)時(shí)荧降,開(kāi)源社區(qū)中的當(dāng)家花旦是BackstopJS列牺,使用配置文件的方式來(lái)編寫(xiě)和管理測(cè)試案例瞎领,完全沒(méi)有多大的上手難度,輸出的報(bào)告對(duì)于從來(lái)沒(méi)接觸過(guò)視覺(jué)測(cè)試的人來(lái)說(shuō),還是讓人眼前一亮乙各。

當(dāng)時(shí),我們組的工作也是維護(hù)一個(gè)S項(xiàng)目下的某個(gè)前端應(yīng)用幢竹,所以在項(xiàng)目上通過(guò)BackstopJS來(lái)實(shí)踐視覺(jué)測(cè)試耳峦,便成了非常正兒八經(jīng)的選項(xiàng)。然而焕毫、可是蹲坷、沒(méi)想到,僅僅用BackstopJS遍歷了兩三個(gè)頁(yè)面邑飒,測(cè)試就…崩了!是的循签,你沒(méi)看錯(cuò),崩了疙咸!經(jīng)過(guò)幾番調(diào)查县匠,問(wèn)題很快確定了:BackstopJS基于配置文件來(lái)組織測(cè)試案例,執(zhí)行測(cè)試時(shí)為了能夠做到Headless,使用的驅(qū)動(dòng)是PhantomJS(是的聚唐,就是那個(gè)作者半途跑路的PhantomJS)丐重,而PhantomJS原生不支持ES6。所以杆查,解決辦法就是……沒(méi)有辦法扮惦!什么,你說(shuō)BackstopJS支持Puppeteer亲桦?Puppeteer發(fā)布v1版本是在2018年的一月崖蜜,至于BackstopJS完成使用Puppeteer替換PhantomJS,那更是猴年馬月的事情咯~

找準(zhǔn)目標(biāo)客峭,二次開(kāi)發(fā)

剛剛開(kāi)門(mén)就撞上了嘆息之墻豫领,有夠背的,可即便沒(méi)能取得開(kāi)門(mén)紅舔琅,圖像對(duì)比在UI測(cè)試中的巨大潛力等恐,仍舊讓我深信這是一灘值得去趟的“渾水”。

換個(gè)工具繼續(xù)嘗試备蚓,接下來(lái)盯上的就是Dpxdt(我用辦公室阿姨擦桌子的抹布打賭课蔬,你第一次絕對(duì)不知道這玩意兒怎么念)。選擇Dpxdt是有一番考量的郊尝,包括:

  • 作者是Google的工程師二跋,貌似很靠譜;
  • 源碼是Python流昏,逼不得已了還能自己搶救搶救扎即;
  • 支持以服務(wù)化的方式來(lái)進(jìn)行測(cè)試;

其中况凉,服務(wù)化的測(cè)試方式是選擇Dpxdt的重中之重谚鄙!之前雖然在BackstopJS身上出師不利,但卻發(fā)現(xiàn)了對(duì)視覺(jué)測(cè)試來(lái)說(shuō)非常重要的關(guān)鍵點(diǎn):視覺(jué)測(cè)試的最大價(jià)值在于圖像對(duì)比茎刚,其它諸如瀏覽器驅(qū)動(dòng)襟锐、頁(yè)面操作撤逢、截圖等工作膛锭,都不是也不應(yīng)該是視覺(jué)測(cè)試的核心內(nèi)容,它們應(yīng)該由其它更擅長(zhǎng)蚊荣、更專(zhuān)注于此類(lèi)活動(dòng)的技術(shù)組件來(lái)負(fù)責(zé)初狰,即術(shù)業(yè)有專(zhuān)攻,從自動(dòng)化實(shí)施的層面考慮互例,盡量做到技術(shù)組件的功能內(nèi)聚奢入,這樣,無(wú)論將來(lái)前端技術(shù)如何演進(jìn)媳叨,也只需要更新相應(yīng)的驅(qū)動(dòng)組件即可腥光,而圖像對(duì)比作為視覺(jué)測(cè)試的核心关顷,則不會(huì)受到影響。

想法很豐滿(mǎn)武福,現(xiàn)實(shí)卻很骨感议双。原生的Dpxdt,在實(shí)現(xiàn)上與BackstopJS有相似之處捉片,比如平痰,同樣使用配置文件來(lái)管理測(cè)試案例,同樣使用PhantomJS來(lái)驅(qū)動(dòng)瀏覽器伍纫,但在架構(gòu)上宗雇,Dpxdt實(shí)現(xiàn)了測(cè)試端和服務(wù)端的分離。在測(cè)試端莹规,使用PhantomJS驅(qū)動(dòng)瀏覽器進(jìn)行頁(yè)面操作和截圖赔蒲,然后將截取的圖片上傳到服務(wù)端,服務(wù)端使用ImageMagic進(jìn)行圖像對(duì)比良漱,最后以一個(gè)Web應(yīng)用的方式來(lái)管理和展示圖像對(duì)比的結(jié)果嘹履。

很明顯,直接使用Dpxdt是不可行的债热,因?yàn)槔@不過(guò)PhantomJS的死結(jié)砾嫉,但Dpxdt兩端分離的架構(gòu)設(shè)計(jì),給移花接木帶來(lái)了可能窒篱。為了在項(xiàng)目上進(jìn)行視覺(jué)測(cè)試焕刮,只能對(duì)Dpxdt進(jìn)行二次開(kāi)發(fā),包括:

  • 封裝Dpxdt暴露的API接口墙杯,重新構(gòu)建可獨(dú)立使用的客戶(hù)端庫(kù)配并;
  • 解決一些Dpxdt在Windows環(huán)境下的兼容性問(wèn)題,因?yàn)閁I測(cè)試運(yùn)行在Windows的EC2上高镐;
  • 加入了Ghost功能溉旋;
  • 重建了部分服務(wù)的UI界面,原版的實(shí)在有些丑嫉髓;
  • Dpxdt在使用ImageMagic對(duì)比不同尺寸的圖片時(shí)容易出錯(cuò)观腊,使用compose進(jìn)行了相應(yīng)的預(yù)處理操作;

經(jīng)過(guò)以上的修改算行,2017年5月梧油,定制版的Dpxdt基本具備了相對(duì)穩(wěn)定的圖像對(duì)比功能。其帶來(lái)的收益也是杠杠的州邢,像素對(duì)比帶來(lái)極高的測(cè)試敏感度儡陨,不會(huì)漏掉UI的任何異常,同時(shí),去掉了UI測(cè)試中的幾乎所有斷言語(yǔ)句骗村,大大的提高了測(cè)試的穩(wěn)定性嫌褪,這在那個(gè)Selenium的年代,是非常有價(jià)值的胚股。

費(fèi)勁心思修改出來(lái)的Dpxdt渔扎,肯定不會(huì)僅僅服務(wù)于一個(gè)項(xiàng)目。通過(guò)將Dpxdt部署到獨(dú)立的EC2上(不得不說(shuō)當(dāng)年的客戶(hù)真的是金主爸爸信轿,EC2基本就是隨意開(kāi))晃痴,這個(gè)視覺(jué)測(cè)試服務(wù)在TW和該客戶(hù)合作的最后兩年里,先后服務(wù)過(guò)6個(gè)項(xiàng)目產(chǎn)品财忽,完成了超過(guò)5000次的圖像對(duì)比倘核,給合作的客戶(hù)團(tuán)隊(duì)也留下了非常深的印象。

自力更生

“如果讓我再選擇一次即彪,我絕不會(huì)再用Dpxdt”紧唱,這是后來(lái)TW結(jié)束S項(xiàng)目后,正荷在一次QA社區(qū)的Catch Up上分享我們的視覺(jué)測(cè)試實(shí)踐時(shí)隶校,留下的讓我記憶最深的話(huà)漏益。原因很簡(jiǎn)單,除了我們當(dāng)時(shí)整套自動(dòng)化測(cè)試架構(gòu)過(guò)于復(fù)雜之外深胳,最讓人難以忍受的就是Dpxdt的慢绰疤!賊慢!比賊還慢舞终!其主要原因有二轻庆,一是Dpxdt將圖片保存進(jìn)了sqlite數(shù)據(jù)庫(kù)文件,使得歷史數(shù)據(jù)多了之后敛劝,數(shù)據(jù)庫(kù)讀寫(xiě)會(huì)非常慢余爆。二是ImageMagic進(jìn)行圖片對(duì)比的速度實(shí)在是太慢了。久而久之夸盟,使用Dpxdt服務(wù)瀏覽圖片和進(jìn)行差異判定蛾方,就成了一件非常痛苦的事情。

在Dpxdt服務(wù)上近兩年的視覺(jué)測(cè)試實(shí)踐上陕,讓我更加確幸了一件事情:服務(wù)型的視覺(jué)測(cè)試方案桩砰,才是UI測(cè)試中圖像對(duì)比的王道,原因我會(huì)在之后的技術(shù)篇中細(xì)聊唆垃。

時(shí)間來(lái)到2020年初五芝,得知春節(jié)后將會(huì)入場(chǎng)的一個(gè)新加坡項(xiàng)目對(duì)Web UI有很高的要求(高到啥程度?后來(lái)的一次Sign Off辕万,PO說(shuō):“你把F12打開(kāi),讓我看看”,然后渐尿,“看吧醉途,這個(gè)margin和設(shè)計(jì)差了2個(gè)px吧” ……想知道當(dāng)時(shí)QA和BA的心情嗎?)砖茸,視覺(jué)測(cè)試自然就被我提上了日程隘擎。然而,Dpxdt畢竟已經(jīng)是六七年前的作品凉夯,方案實(shí)現(xiàn)落后太多货葬,繼續(xù)改造已無(wú)益處。放眼此時(shí)的開(kāi)源市場(chǎng)劲够,提供圖像對(duì)比的UI測(cè)試工具已經(jīng)比比皆是了震桶,光Cypress的插件就有一大堆≌饕铮可是蹲姐,服務(wù)型的解決方案卻只有商業(yè)軟件,比如大名鼎鼎的Applitools人柿,可開(kāi)源解決方案柴墩,一個(gè)都沒(méi)有,這凫岖,就有些玩兒不動(dòng)了江咳。

人不折騰,天誅地滅哥放,沒(méi)有現(xiàn)成的扎阶,就自己擼一個(gè)唄!天意弄人婶芭,趕上新冠疫情东臀,10天的閉門(mén)春節(jié)假期,還真就讓我碼了一個(gè)出來(lái)犀农,取了個(gè)很俗氣的名字叫Team Visual Test惰赋,簡(jiǎn)稱(chēng)TVT(是不是很?chē)澹VT在考慮之初呵哨,就奔著跨團(tuán)隊(duì)和開(kāi)源共享去做的赁濒,所以使用的都是非工作時(shí)間進(jìn)行的開(kāi)發(fā)和維護(hù)。

為了最大程度的提高視覺(jué)測(cè)試的速度孟害,TVT在具體的圖像對(duì)比技術(shù)上拒炎,選擇了native-image-diff,雖然這是一個(gè)名不見(jiàn)經(jīng)傳的NodeJS圖像對(duì)比工具挨务,但它的實(shí)測(cè)速度是非常理想的击你,通過(guò)比較玉组,native-image-diff的圖像對(duì)比速度要比ImageMagick和OpenCV快得多。比如丁侄,下圖是之前做的native-image-diff和ImageMagick在對(duì)比不通尺寸圖片時(shí)的速度表現(xiàn)惯雳,native-image-diff的對(duì)比速度幾乎是ImageMagick的三倍。

除了對(duì)圖像對(duì)比技術(shù)的甄選鸿摇,TVT還在項(xiàng)目上因地制宜的實(shí)現(xiàn)了一個(gè)圖片文件共享的方案石景。我們使用容器化的方式來(lái)執(zhí)行功能測(cè)試,然后將功能測(cè)試的容器和TVT服務(wù)的容器運(yùn)行在相同的ECS Fargate實(shí)例的Task上拙吉,這樣功能測(cè)試和TVT服務(wù)就能通過(guò)Bing Mounts的方式共享文件存儲(chǔ)潮孽,從而實(shí)現(xiàn)了功能測(cè)試獲取的截圖,可以被TVT服務(wù)直接使用筷黔,從而避免了文件上傳帶來(lái)的耗時(shí)往史,使得整個(gè)視覺(jué)測(cè)試方案的速度可以更快。這樣的實(shí)施方案必逆,既有它的特性怠堪,比如項(xiàng)目上本來(lái)就使用Fargate實(shí)例,也有它的共性名眉,比如即便不使用Fargate粟矿,隨便一個(gè)Docker Swarm的環(huán)境,都能使用共享存儲(chǔ)的方式實(shí)現(xiàn)類(lèi)似的效果损拢。

另外陌粹,不同于Dpxdt的單體服務(wù),TVT在架構(gòu)上是一個(gè)簡(jiǎn)單的微服務(wù)系統(tǒng)福压,將負(fù)責(zé)圖片對(duì)比的圖像對(duì)比服務(wù)和負(fù)責(zé)測(cè)試結(jié)果呈現(xiàn)的主服務(wù)分離開(kāi)來(lái)掏秩。這樣,如果將來(lái)有更強(qiáng)大的圖片對(duì)比技術(shù)荆姆,只需要單獨(dú)更新圖像對(duì)比服務(wù)蒙幻,就可以對(duì)TVT進(jìn)行升級(jí)。 后來(lái)胆筒,在那個(gè)新加坡項(xiàng)目上邮破,配上與Telegram的消息集成,TVT取得了非常好的效果仆救。

然而抒和,TVT畢竟只是一個(gè)春節(jié)假期趕工出來(lái)的成果,在服務(wù)部署彤蔽、易用性摧莽、安全性、以及多客戶(hù)端支持上都有不少欠缺顿痪。下項(xiàng)目后镊辕,又陸陸續(xù)續(xù)的花了一些時(shí)間來(lái)對(duì)TVT進(jìn)行修修補(bǔ)補(bǔ)油够,于是打磨出了如今的開(kāi)源視覺(jué)測(cè)試服務(wù)Micoo。關(guān)于Micoo丑蛤,這里就不多言了叠聋,在稍后的技術(shù)篇中也許會(huì)提到部分內(nèi)容撕阎,更多的細(xì)節(jié)受裹,感興趣的同學(xué)可以查看:

寫(xiě)在最后

目前,在SEA虏束,在沒(méi)有任何推廣的情況下棉饶,已經(jīng)和正在使用Micoo(包括其前身TVT)的客戶(hù)項(xiàng)目已有4個(gè)。所以镇匀,故事講到這里照藻,故事也還在發(fā)生。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末汗侵,一起剝皮案震驚了整個(gè)濱河市幸缕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罐氨,死亡現(xiàn)場(chǎng)離奇詭異壮不,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)到逊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人译仗,你說(shuō)我怎么就攤上這事」倜伲” “怎么了纵菌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)休涤。 經(jīng)常有香客問(wèn)我咱圆,道長(zhǎng),這世上最難降的妖魔是什么滑绒? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任闷堡,我火速辦了婚禮,結(jié)果婚禮上疑故,老公的妹妹穿的比我還像新娘杠览。我一直安慰自己,他們只是感情好纵势,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布踱阿。 她就那樣靜靜地躺著管钳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪软舌。 梳的紋絲不亂的頭發(fā)上才漆,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音佛点,去河邊找鬼醇滥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛超营,可吹牛的內(nèi)容都是我干的鸳玩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼演闭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼不跟!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起米碰,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤窝革,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后吕座,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體虐译,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年米诉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了菱蔬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡史侣,死狀恐怖拴泌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惊橱,我是刑警寧澤蚪腐,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站税朴,受9級(jí)特大地震影響回季,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜正林,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一泡一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧觅廓,春花似錦鼻忠、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)矮瘟。三九已至,卻和暖如春塑娇,著一層夾襖步出監(jiān)牢的瞬間澈侠,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工埋酬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哨啃,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓奇瘦,卻偏偏與公主長(zhǎng)得像棘催,于是被迫代替她去往敵國(guó)和親劲弦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耳标,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容