一個人從零扛 App 自動化:從 16 個元件的藍圖,到「先求穩定」
#自動化測試 #Appium #QA 實戰 #flaky test #QA 思維
一個人從零扛 App 自動化:從 16 個元件的藍圖,到「先求穩定」 公司決定要做 App 自動化的時候,我還沒報到。 是公司需要有人導入,我就是那個人。團隊裡沒有人做過:有人摸過一點 Katalon,iOS 工程師用原生語言寫過幾支 UI test,就這樣。沒有框架,沒有前人留下的坑可以參考,也沒有人可以問。 所以報到前,我先畫了一張圖。 16 個元件的藍圖 我想讓新主管在我報到前就知道我打算怎麼做,所以把知道的工具全部擺上去:兩套腳本工具、實機加雲端裝置、CI、AI 視覺比對、案例管理平台、報表、Grafana、寄信服務,還有一個自己寫的測資微服務。數一數,16 個元件。 每一格單看都合理。問題是全部加起來,一個人要顧 16 個系統的安裝、升級、帳號和串接。 真正跑起來的只有三塊:一台 Mac mini 接三台實機、self hosted 的 GitHub Actions、ReportPortal。其他的,理由幾乎都是同一句:規模還沒大到用得上。 藍圖怎麼砍、每一塊的設定和實機的坑,我另外寫在報到前我畫了 16 個元件的自動化架構,最後只做了 3 個。這篇講的是砍完之後的事。 我寫的第一支測試是登入。後來才知道,登入是整套裡面最難維護的區塊之一。訪客、不同身分、各種彈窗、登出再登入,每一種組合都會長出新的分支。 撞牆:一直紅,一直修,一直追不上 接下來幾個月,測試一直不穩定。 測試三天兩頭亂紅。修好一支,下一個版本又壞了。App 改版很快,我的腳本永遠在後面追。公司期待的是數量和時程:什麼時候能覆蓋多少。我每天的時間卻大半花在修昨天還好好的測試,新的測試寫不出來。 根因不在腳本 一開始我以為是自己腳本寫得不夠好,或是環境不穩。查到後來發現,大部分的問題出在 App 本身。 很多元件沒有 accessibility id,只能靠文字、XPath 甚至圖片找。 有一整頁是畫在 canvas 上的,dump 出來只有一個全螢幕的元件,裡面什麼都抓不到。偏偏那是測試最該保護的地方。 同一個畫面,這個版本是 WebView,下個版本換成原生,locator 一夕之間全斷。 我去推開發加 accessibility id,但一直排不進去,就算排進去也很慢。等不了,只好自己繞:圖片比對、OCR、座標點擊。能跑,可是很脆。後來盤點 locator,三成多都是這種高風險寫法,改版的工時大多花在它們身上。 轉折:不是技術解的 我找主管重新談期待,把上面那些攤開來講,一起討論 root cause。最後把目標從「要多少」改成「先求穩定」。 報表全綠,畫面卻不對 穩定性開始有起色的某一天,報表全綠。 照理說該高興,但我習慣邊跑邊看手機畫面。那天我看到的畫面,跟報表的全綠對不上。 翻 log 才知道,很多測試其實第一次就失敗了,是重跑才過的。 報表全綠,畫面卻對不上 🟡 報表: 全部通過 實際: 手機畫面跟報表對不上 原因: 全域開著自動重跑一次,第一次失敗、第二次通過,報表只記最後的綠燈 後果: flaky 被整個藏起來,連標記成 flaky 的那幾支都形同裝飾 自動重跑本來是為了減少雜訊,結果把我最需要看到的訊號一起蓋掉了。後來我自己寫了一個小工具,專門記「重跑才過」的測試,分裝置記,才分得出是腳本的問題還是某一台手機的問題。 如果只看報表,我永遠不會知道。另一次更驚險的,是 flaky 紅燈裡藏著一隻真的登入 bug,差點被我當成雜訊重跑掉,寫在那一成紅燈,差點讓我放掉一隻登入 bug。 後期,AI 進來幫忙也幫倒忙 剛開始做的時候,AI 還沒有這麼普遍,前面那些全是手工一行一行修出來的。2025 年 6 月,我才開始用 Cursor 協助開發,主要用在兩類事:一是修壞掉的測試、查 flaky 的原因;二是整理文件和規則,讓 AI 照我的規矩寫。 它幫了很多,也惹了兩次麻煩。 第一次是 sleep。請 AI 寫腳本,它很愛塞 sleep(2),等不到元素就多睡兩秒。我先是 review 時手動刪,刪了一陣子刪不完,只好加一道 lint 檢查,擋住新加的寫死等待。舊的不動,真的需要的加註解放行。 第二次比較嚴重。AI 修一支壞掉的測試,搞錯了 root cause,順手改了一個共用函式的參數,結果其他好幾支測試跟著壞。這是我自己 review diff 的時候發現的。 那之後我把高風險函式列成清單,連同「不准改函式簽名」這類規則,寫進給 AI 讀的規則檔。以前這些規矩只在我腦袋裡,AI 當然不知道。 一個人能顧多少 我一直沒做平行執行,CI 也沒讓它自動跑。 文件上寫的理由是裝置不足。真正的原因是:一個人維護不來。平行執行要解決的是時間,但會換來裝置管理和測試帳號互撞的新問題;CI 自動跑,失敗了也是我一個人看。我那時寧可手動觸發,跑完看得完,也不要自動跑出一堆沒人處理的紅燈。 雲端裝置也是。開了,但自動化幾乎沒在用,主要是使用者回報我們手上沒有的機型時,手動測試拿來重現。對一個人的自動化來說,雲端裝置拿來補機型就夠了。 交出去 一年多之後,我轉去做探索式測試,自動化交給開發團隊維護。 交出去的時候,還有很多事沒做完。測試清單散在三個地方,改個名字漏改一處就全掛,統一成一份的工作排在最優先,沒來得及做完。每週修 flaky 前十名的節奏,定了,也沒真的做到。 說不捨得是騙人的。從一張藍圖開始,一行一行蓋起來的東西,突然變成別人的。但同時也鬆了一口氣,終於不用一個人扛著。 交接時我能給的,是自己開發時留下的筆記。整理的時候才發現,那些筆記是寫給自己看的,很多前因後果只有我懂。一個人做的時候不覺得,要交給別人了,才知道沒寫下來的東西有多少。 學到的一件事 回頭看這一年多,我學到的是:自動化先求穩定,再求數量。 一百多個沒人敢信的測試,比不上幾十個紅燈一亮、大家就會停下來看的測試。 報到前我畫了 16 個元件的自動化架構,最後只做了 3 個 那一成紅燈,差點讓我放掉一隻登入 bug 三個月後我的自動化測試變成了維護地獄 Appium 搭配 pytest 完整實務:從 fixture 設計到 CI 執行