〈Software Engineering Daily〉-EP-The State of Browser Testing

https://softwareengineeringdaily.com/podcasts/the-state-of-browser-testing/

David Burns 在 Software Engineering Daily 講瀏覽器測試。同一套測試要能驅動 Chrome、Firefox、Safari,靠的是開源專案、瀏覽器廠商,還有 W3C 這類標準組織磨了很多年。他是 BrowserStack 的 Developer Advocacy and Open Source 負責人,Selenium 跟 WebDriver 做了很久,Mozilla 待過十年。主持人 Josh Goldberg 在 Sentry 做前端,維護 TypeScript ESLint,一套給 JavaScript 跟 TypeScript 的靜態分析工具。他寫了 O'Reilly 的《Learning TypeScript》,是 Microsoft MVP(Developer Technologies),也是 SquiggleConf 共同創辦人。David 把測試收成一句:一條關鍵路徑,一條紮實的測試。

南安普敦那份第一份 QA

David 在南非長大、讀大學,主修電腦科學跟工業心理學。他自己說,當時拿不定要進科技,還是去當心理師。後來去英國,名義上是去走走。銀行給了他一份流程再造的工作,他在那裡碰到流程自動化,也跟不少做 QA 的人共事。下一站是南海岸 Southampton 的新創,大約 2006,CI 正要起來。公司以前沒有 QA,要人把東西修好,並做自動化。這是他第一份 QA。

那個年代的版本控制,檔案得 checkout 出來,別人就不能同時改同一份。CI 要怎麼跑、東西要怎麼建,都得自己想。公司給的自由很大,說法是我們沒時間搞懂,你去弄。QA 環境裡的 SRE 他得自己當,自動化框架自己搭,再幫別人用起來。Extreme Programming 那時把 TDD 帶了進來。他覺得這主意好:從一開始就想測試,應該多做。公司做的是行銷軟體,他待了大約四年。工程師跟人都很好。為了當一個稱職的 QA、搞懂他們在賣什麼,他也得學會把自己推銷出去。現在若走回去,他大概會把當時的做法全部換掉。那四年對他是很大的學習。

晚上有空檔,是因為太太是音樂人,工作常常不在。他不是會打一整晚遊戲的人,就拿晚上做開源,去幫當時才剛起步的 Selenium。

回到那天,他最先想改的是 DSL。那時 DSL 很流行:拿一個框架,用你選的語言,把 API 包成公司自己的領域語言。他認定 fluent API 漂亮,就做了一套:做這件事,點下去,做那件事,再點下去。進了除錯器,才發現這東西有多糟。每一層都是一個點,要鑽很多層才碰到真正的問題。看起來順,不好共事,別這樣做。Josh 說他還是懷念 jQuery 滿街 fluent、以及 C# 裡的 LINQ,這一點他同意。

三百五十人的 Mozilla

開源的信念從大學就有了。軟體該免費,圍繞它的服務再付費,知識放出去,世界才變好。網路在他看來是最了不起的發明,用來分享、用來學,理想上人人都能用。他也知道資本主義不會照這套走,網路有很糟的部分。Mozilla 把他所信的那一面做出來了。

換工作的原因很生活。他當時開車去 Southampton,單程一小時。太太懷孕。他不想一去一回,把跟家人的時間吃掉。Mozilla 在招人,是他碰巧看到的。進去時大約三百五十人,他覺得很小。碰到的人,他形容是自己遇過最聰明的一批,要解很難的問題、要上規模,還想讓世界好一點,來自世界各地,人也客氣。jQuery 的作者當時也在。他見到 JavaScript 的作者 Brendan Eich。這些人願意把知道的講完,他說每天都在學。

職稱是 QA lead,專案叫 Socorro,一個讓人看 Firefox 為什麼崩潰、堆疊長什麼樣的網站。當時使用者超過五億。就算只有百分之一在崩潰,進來的資料也多到不得了。他在那裡把系統操過一輪,學規模。這段大概四到五個月。

接著調去 Automation and Tools 團隊。Mozilla 用的測試框架,很多是這個團隊做的。買一套現成工具就指望它能用,在那裡行不通,東西得手工打造。團隊也管一部分 CI。大約第三年,他轉成工程經理。他把人看成另一種要解的問題,而且喜歡。他覺得這跟大學那門工業心理學有關。接下來六年,問題從建置、CI,做到 CI 視覺化怎麼擴充,中間仍有時間碰 Selenium。整段在 Mozilla,是十年。

瑞士那場會,Opera 把 Selenium 做進瀏覽器

進 Mozilla 的時候,Selenium 他已經做了大約四年。後來開始談標準,起點是瑞士一場會。聽比較久的人會記得 Google Test Automation Conference,簡稱 GTAC,以前在世界各地辦。有一年 Opera 有人帶著自己做的東西來:他把 Selenium 做進 Opera。在場的人覺得了不起,有瀏覽器的公司都該這樣。對方說,要大家這樣做,出路在標準裡。David 他們當時不知道那是什麼意思。

規格他讀過。新功能常常從規格來,為的是瀏覽器之間能互通,他也幫人圍繞那些功能做測試框架。從來沒有一份規格在講:把一套自動化框架做進瀏覽器。他們開始做。大約十八個月後,一個叫 Andreas Tulfsen 的人加入他的團隊,一起把規格寫出來。WebDriver 的作者 Simon Stewart 當時在 Facebook,兩人合作把標準推動下去。事情動起來之後,他們才看清有多要緊:當時拿標準去測瀏覽器,很多仍是手工,很慢,也很容易錯。有人看兩張圖,差了半個像素,就判定失敗。他記得有個 Internet Explorer 的 QA 在做這種事。某些情況下,對方把完美放在夠好前面,時間花下去,多半是浪費。再給聽比較久的人一個名字:渲染用的 Acid tests。有的瀏覽器做到百分之百,有的做到百分之九十八。他們的判斷是,那就夠了。把一份標準做出來,比你在 W3C 或 WHATWG 網站上讀到的那一頁難得多。

點擊好定,等多久不定

規格有了方向之後,大量工作是在決定什麼能定、什麼不能定。對 Selenium,也可以說對 WebDriver,好定的是這些:我要打字,我要點,我要移動滑鼠,我要拖放。難的是,你怎麼知道一個元素真的在頁面上,以及你該等多久。

要把「有意義的等待」定成標準,又不能去解停機問題。停機問題是 Turing 那個著名的問題,解不了。自動化一碰到「它到底會不會停」,就很難。他們不打算解那一個。

另一個難處是,你想動作的時候,那樣東西看不看得見。WebDriver 一開始,Simon 的要求是:人要點一個東西,它得可見。可見是什麼?不能靠逐像素去對。畫面上會有遮罩。CSS 有 z-index,但那又不完全是一條乾淨的前後座標,DOM 跟 CSS 怎麼排,別的東西照樣可以蓋上來。力氣大多花在這裡。這些是別人自己未必得解的問題,寫進標準就躲不掉。

他們另外留了一條路:別人可以用其他標準、其他規格,把 WebDriver 往外接。做新功能的人就可以說,我們知道怎麼測了。現在很多瀏覽器就是這樣測。他拿權限當例子,因為這集正在錄音。你打開一個網站,它問要不要把攝影機跟麥克風交給它。這種對話框怎麼測,很難。規格裡把 WebDriver 的 API 做出來,就可以延伸、就可以開始測。現在的力氣多半在把這些東西做好。舊的那份他們叫 WebDriver Classic。眼前很多工作在 WebDriver Bidirectional,雙向那一份。

Josh 把定義收成一句:WebDriver 描述你怎麼對瀏覽器送指令、收回覆,像點擊,像問元素看不看得到;上面的工具,例如 Selenium,拿去做自動化或無障礙測試。David 補了名單:Selenium、WebDriverIO、Nightwatch.js,外面還有一大堆。它們做得到,是因為對瀏覽器說話被簡化了,不用各自去想怎麼鑽進去。

以前鑽進 Firefox,靠的是做在 Firefox 裡的擴充功能。WebDriver 要對付 Internet Explorer,得做很多 COM 互操作,一換語言就更痛。從微軟自己的語言進 .NET,這條路很順。Java 進 .NET 就不怎麼樣。Python 跟 Ruby 更差。走到 Node,他的說法是:誰知道。

雲上的 Selenium,專案留在外面

BrowserStack 是 SaaS 測試平台。產品從測試管理工具到圍繞測試的 AI 工具都有。起步是把 Selenium 放上雲。擴充是很多人最頭痛的事,QA 這塊尤其,不是每個人都有那種經驗。不少公司的想法很直接:為什麼再雇一個人,付錢買服務不行嗎?行動裝置也在這條線上。

這是他在 BrowserStack 的第六年左右。進去時做的是 open source program office,其中一件事是回饋那些讓 BrowserStack 得以出現的社群。公司要他做 Selenium 的工作,把關係維持好。他們明確不想把 Selenium 收成自己的,想讓它留在原地。Appium 一樣。他跟 Appium 的人、跟 WebDriverIO 關係都好,標準的工作也還在做。對手會受益。他的講法是水漲,船都浮起來。會上他講他們做出來的東西,也講那些因為對產業重要、就放出來的東西。

Josh 把問題丟給一個想像中的大公司主管。開源是一邊,資本主義的帳在另一邊。為什麼要養一個會讓對手一起受惠的人?David 說,主管腦中全是風險。最大的一條:那個專案上的人如果全部停手,會怎樣。

他看過開源工程師被逼到盡頭,直接翻臉,把整個專案下毒,毒再蔓延出去。他記得有一樁大約在 2020、疫情那段,他以為是 left-pad,一個 Node 套件。那位工程師一直問:我失業了,你們都靠我這個東西,能不能給點錢。沒人給。他就把套件全部下毒,程式碼也刪了。這是他眼中最壞的情況。

他覺得公司該做的理由是企業責任。學校多半教過:讓你賺到錢的東西,包含上游那些供應,你得照顧。到了 AI 這段,他認為供應鏈攻擊會更常見。人在專案裡幫忙把東西顧好,會送出一些成果,生意的風險也被壓低。到不了零,是盡量低。

Josh 補了一層:熟悉規格、也熟悉規格後面那些人,对公司有用,想推一個功能或把某一塊顧好的時候尤其。David 同意。自家網站或產品跟 Google Chrome 出了大問題,他有聯絡人,可以直接找:這個 bug 我們重現了,能不能幫忙排優先。這也是在告訴 Chrome,你們的產品有這個 bug,拿掉吧。他們受益,別人也受益。工程師不想寫一堆 bug。bug 一直在,只是那條路還沒被那樣測過,現在可以去修。

行銷首頁可以不管

換成一家有網站的公司,為什麼要在意 BrowserStack,或這集講的任何一件事。David 先看你在不在意別人真的來用。不在意的話,BrowserStack 對你沒有用。只是一張行銷首頁,誰在乎。若是一家 SaaS,他認為至少每條關鍵路徑要有一條測試。這是他覺得最要緊的做法。

這不表示一定得用 BrowserStack。每條關鍵路徑仍該有那一條。一開始寫,測試會變多,也會變得要緊。旁邊還有法規。大家放在心上很多年的最大一項是無障礙,他認為在 AI 這塊會很大。治理是另一項,很多人得開始在意它跟其他東西怎麼咬在一起。

很多人只看價格,不看拿掉了多少認知負荷。他說,就算自己不是 BrowserStack 的人,也會建議有機會就用一家這類公司。自己雇人維護那套基礎設施,不能只雇一個,得兩個,要有備援,不然 bus factor 很糟,人一不在整條就停。之後是他們得不斷維護多少。這類公司把成本攤開比較容易,重活他們扛。人知道它會動,上面有 SLA,不用自己扛。認知負荷拿掉之後,剩下的是:我要測這個,我要產品品質好。他認為品質好,銷售會跟著來。

怎麼開始,他每次都說:先做一條,再往外長。理想上,一條關鍵路徑只留一條。架構時如果想過,別的保護在其他層:可觀測性、telemetry、中間那些,再加上日誌,事情發生時看得到。那一條是「我登得進去,而且做得出 X」。做完就好,再看哪一層變得更要緊。

下一條仍該是關鍵路徑。十五條大致在做同一件事,就不必再加。一條大約一分鐘,十五條是十五分鐘。你真的要等這十五分鐘嗎?沒有唯一配方。放在一起看的是花多久、有多關鍵、風險多大。套件若要跑二十四小時,能不能拆成一天裡的多段、不同區塊?平行愈多,回來得愈快,也省掉一種負荷:二十四小時前我在做什麼,才撞到這個 bug。他把這三邊叫做速度、正確、風險。

Josh 注意到,這跟很多人講單元測試、整合測試時很像:套件小一點、循環快一點,這裡拿來講端到端的瀏覽器測試。David 說他這行看下來,很多人單元測試堆很多,走測試金字塔:底下小測試,中間中等,上面長測試,從下往上該愈來愈少。元件測試起來之後,尤其 React、Vue,大家問這一個元件怎麼測,金字塔就被做成別的形狀。有人長成聖誕樹。也有人形容成沙漏:中間收一下,很快又往上爆開。兩種他都不要。

所以每條關鍵路徑那一條最重要。做事的一條好測試,無障礙一條,視覺測試一條,其他每樣一條。加起來也許一百條,卻是有瀏覽器時最該留的。瀏覽器啟動很貴,吃運算時間。瀏覽器現在複雜到像作業系統。有 Chrome OS,以前有 Firefox OS。一直重開,等於每次啟動一台電腦,而且是電腦裡的電腦。能往金字塔下面壓就壓。端到端還要不要留,他問了,沒有替聽眾把答案說死。

無障礙先是少碰滑鼠

對有客戶、又跟別的公司或政府有合約的生意,無障礙測試要怎麼講才講得動。他從來源講起:很多人忘了,不少東西一開始是當無障礙工具做出來的。

工程師在 IDE 裡工作。AI 還沒進來之前,一個方向是盡量不碰滑鼠能做多少。那件事做對,就是無障礙測試,因為不是每個人都能用滑鼠。另一個例子:開車時簡訊進來,手機把訊息唸出來,你可以回。那一大塊圍繞無障礙工具做出來,給當時不一定能直接操作手機、但想用講的人。這是生產力,多快能到我要的地方。旅遊網站能不能用 Tab 跳到要填的欄位。搶注意力的環境裡,人沒有多少注意力。把這件事做順,無障礙同時被解掉。

自動化這邊也有人在做螢幕閱讀器。一份正在試著訂出來的規格叫 Accessibility Test Driver,路數像 WebDriver,讓你驅動螢幕閱讀器走完一個網站。他要把焦點放在流程變好。另一種講法是「我為了這條法律花了這麼多錢,感覺沒受益」,他覺得這是反的。

Josh 用胡蘿蔔跟棍子做比喻。有人因為好處才做無障礙,也有訴訟這類棍子把公司推過去。天平有沒有在移?David 的看法是,很多公司永遠只看棍子,這件事你改變不了多少。能把他們拉去看好處,空間就大了。我們加了這個功能,對上對手的好處是這些。話裡不必點出無障礙,工具卻都在。他認為那是很大的贏面。

另一面他不給數字。無障礙人口在不同國家占多少百分比,他說他不知道。網站或 App 做不到,你放不放得下那些人的銷售?他們的錢跟我的錢一樣好。同一套可以拿去講「我們現在只測 Chrome」。Apple 有 Safari,Mozilla 有 Firefox。那一塊會不會有人來買,你在不在意。做這件事是對的,也會加上一堆好用的功能。

Josh 自己常用 Axe Core。David 說,Axe Core 就是一個工具,走過 DOM,指出這裡有哪些無障礙問題。競爭的工具不少。BrowserStack 有一個叫 Specter,做類似的事,做法稍有不同。很多工具是讀 DOM,再去推斷。AT driver,也就是 accessibility test driver,走另一條:驅動螢幕閱讀器,再由閱讀器驅動瀏覽器。你用螢幕閱讀器按 Tab,它會告訴你現在在哪,把那樣東西描述給你。這種描述算不算標準,就是它要碰的問題。

做無障礙的人這裡會挫折:每個作業系統的螢幕閱讀器差很多。Linux、Mac、Windows 不一樣,同一平台上不同公司做的也不一樣。這跟用 Appium 做手機自動化是同一類,其他工具也有。Apple 上的做法跟 Android 差很遠,沒有標準,他們也不想要。他的說法是,近乎獨占時人家會覺得夠好了,那個問題不必管,別的問題會冒出來。無障礙這邊他感覺到的是:把事情做好,才找得出做法,才有標準做法,Chrome、Firefox、Safari 的互通會跟著變好。你在 Linux 上走過一個網站的導覽長這樣,到 Mac 上長那樣,而那該是一個人可能想要、或需要的同一件事。

規格慢,是因為快會把通話打壞

規格一直在長,他覺得興奮。他也知道聽眾多半的挫折:一件事走進規格,真的被訂出來,非常慢。

他開始工作時,JavaScript 在不同瀏覽器上是一團亂。每一邊得各做一套,人就掉進 callback hell。後來 ECMAScript 的標準化進來,他覺得很酷,也開始有可以跑過全部的測試套件。慢,反而讓它變正確。做得快,會製造別的問題。規格這一行他看過。

有一份規格他一時叫不出名字,用來在瀏覽器之間傳訊息。想在瀏覽器裡打電話,走的就是這個。它已經第三代。第三代慢很多,也更正確。前兩代問題很多:Firefox 打給 Firefox、Chrome 打給 Chrome 都不順,Firefox 打到 Chrome 一直做不到。WebDriver 是同一類教訓。外面跟 Selenium 競爭的工具,像 Playwright、Cypress,不曾真的深進規格那一段。他們做的時候想的是,你永遠可以往外延伸:瀏覽器加上這個功能,就有一個 WebDriver 測試,不同瀏覽器給你的東西你知道是什麼。這在手機上更要緊。Android 上的 Chrome、iOS 上的 Safari,彼此怎麼碰上、怎麼把好的結果帶出來,都得想。

一段 prompt,正式環境的資料庫可以沒了

BrowserStack 還在往前,焦點仍是把測試做成平台。他認為這會很要緊,AI 這段測試只會更要緊。今年稍早他有一場演講,講 vibe coding,也講 vibe testing。vibe coding 就是寫一段 prompt,盼望出來是對的,感覺對了就往下走。測試也有人這樣做。

問題是人會用這種方式把正式環境的資料庫搞到報廢,東西直接被丟掉。這類故事很多,而且沒有變好。他說去年有 Replit 那類事情,對方後來加上防護,把東西存下來。然後有人說那不要 Replit 了,直接用 Claude。有人沒給限制,正式環境的資料庫就被刪了。AI 有幫助,仍需要看得懂它生成了什麼的人去設限、去修。你我說話時,活過的經驗會補進句子裡,AI 不一定有這個。它很會做快速原型,也很會做要緊的轉換,例如把資料從一處搬到另一處。他是真的喜歡 AI,也覺得它被太快交到所有人手上。人該有這些工具。跟著冒出來的是安全問題。

主持人給了兩條路:人愈熟,問題會變小;或愈普及,擴散更大。David 選後面那條。愈把它交出去,場面會愈糟。

做瀏覽器時,有一份問題清單被一再灌進腦子裡。很多瀏覽器用 C、C++、Rust 這類原生語言。Rust 這類問題現在沒那麼嚴重。C 跟 C++ 的年代,規則包括:變數已經交給垃圾回收,就不要再去碰。還有,有沒有真的檢查這個人通過驗證,API key 會不會不小心寫進程式、沒有好好混淆。沒有人這樣講,這些就不會進到做法裡。那是做過軟體的人才被敲進去的知識。從來沒做過、一開始也沒人敲的人,他覺得很危險。

他喜歡 AI,同時覺得初階工程師該少用很多,比較像後備:拿來複查,問有沒有想過這個問題、那個問題,好讓知識從一開始被敲進去,然後該做的再去做。原型則是每個人都該有機會。有個想法,做出來,真的很酷。接著要重寫,或至少過一遍安全檢查,確定原型進正式環境是安全的。十到十五年前的原型,問題大概在哪,一開始就有個粗糙的概念,進去之前修得掉。

Josh 拿 Stack Overflow 對照。有經驗的開發者可以上去複製一段答案,而且知道那樣是好的。還不知道實際上在發生什麼就這樣做,等於把學習拿掉。David 同意。他把 AI 比成做過很多 .NET 的人會記得的 ReSharper。他不確定那還是不是一個獨立的工具,還是已經做進 JetBrains 做的每樣東西裡。它很會給好的模板,東西做得很快。他覺得 AI 就在那個位置。它也會給很多資訊。對或不對,仍得用自己的知識判斷。AI 會幻覺,一定會,沒有也許。有意思的是多常發生。回去複查之前,分不出來。

從打開網站那一步就把 trace 接上

近一點的小專案,是讓更多人去看可觀測性。可觀測性讓人在應用裡做出 trace,把一條路徑串過去。OpenTelemetry 這套,大家做了大約八、九年。他不覺得很多人把它放進測試:一條測試從「我打開了網站」走到應用裡面,失敗時知道斷在哪。他覺得這很酷。

另一件他在讀的是 CD events。他說這可以是連續部署的事件,也可以是連續交付的事件。它讓你把事件驅動的東西做進 CI 跟管線,某件事可能在哪裡,一直追得住。這塊有不少好工作,仍算早期。

接到端到端的瀏覽器測試上,失敗會更好除錯。David 說就是這樣。你給一組 trace key,要求它一路帶下去。有些東西會在開發、把東西傳下去的方式裡被撿起來。他說今年底有一連串演講,會把這部分工作拿出來。

很多年人們只是在讀日誌,而且得先知道那條日誌跟什麼接得上。OpenTelemetry 出來之後,你看得到它經過這裡,卻常常不知道怎麼開始的,只看到資料進了系統。加進元件測試、瀏覽器測試或手機測試,一路走完,就不一樣。看到失敗,手上有這份資料,就用它進來的方式重現。同一份資料填進表單,這次卻過了,那也許有人用另一種方式在做,就可以去追。資訊先放進測試,再跟著走,不用先花時間找起點。

改 OpenTelemetry 規格,他覺得不必。東西都在,他也做出能示範的東西。唯一可能要補的,是人怎麼把測試啟動起來,給一個最基本的做法:動一開始進伺服器的網路連線,其實只是加幾個 header,沒有改寫連線再跟著走。規格不用改。只是這件事沒什麼人在講。他跟 Marie Cruz 做過一集 podcast,她在 Grafana。她的反應是但願更多人在做。東西已經在那裡,大家不知道怎麼開始。

赤腳跑過荊棘

收尾前 Josh 要一個跟工作無關的歷史冷知識。David 回到南非。他成長時學的是這個國家怎麼成立,以及英國人在南非的歷史。他一直覺得有意思:很多歷史是多年口耳相傳,之後還得有人回去再核。

Shaka Zulu 是南非很有名的祖魯國王。他訓練士兵在荊棘上跑。他們赤腳跑過非洲鄉間,把腳底練厚。知道自己必須到某個地方時,就不會去想腳上的痛。他覺得有意思的是:重點不是做鞋子,是把這個東西練硬,好讓後面其他部分可以專心。

Josh 要他把這件事比到測試,或正式環境的可觀測性。他接到安全上。先試一件新的,再把它練硬。安全要有這些層,有些靠犯錯換來。犯錯若發生在安全的環境裡,像他訓練戰士那樣,才學得會,才演進,才變好。

想繼續看這些規格,他指了幾個地方。BrowserStack 的 community,路徑裡有 /community,從 Discord 到他自己的 podcast 都在裡面。部落格是 theautomatedtester.co.uk。LinkedIn 上的電子報叫 Automation Isn't Scary,分享他覺得大家該知道的零碎,希望做這行的人不要那麼怕。人在各個 Slack 跟 Discord。公開傳訊,他能幫的地方會盡量幫。