2026/04/10

當「抓住恩典的男孩」成為了打工人:關於我的部落格分家計畫

親愛的讀者:

在這個名為《The Elijah Web》的小角落裡,我們一起經歷過 Selenium 的除錯、聽過 Josiah Queen 的詩歌,甚至討論過如何用小蘇打粉解決生活的尷尬。這裡記錄了我試圖抓住上帝恩典的每一個瞬間 —— 雖然通常是沒抓到(笑)。

退伍後進入職場這兩年,我發現自己對「品質」與「架構」的執著,似乎總與周遭有些出入。我有了一點點更嚴謹的追求,卻也同時擔心自己在環境的浸泡下,會不自覺地變成「酸黃瓜理論」裡那條隨波逐流的新黃瓜。

為了對抗這種平庸,也為了讓這個溫馨的客廳能更純粹地分享關於基督信仰、愛情理解與生活感悟,我決定將「硬核技術」的部分遷移到一個更專業的實驗室。

實話說,我正試著建立個人品牌。在自動化測試這個領域,我希望自己不只是個寫腳本的打工人,而是能朝向「顧問」的職涯目標邁進。如果你也是為了 Appium 架構、自動化測試或 QA 職涯規劃而來,誠摯邀請你前往我的新家:

🚀 我的新技術部落格:[Elijah’s Quality Lab] 🔗 傳送門: https://jiamingla.github.io/

在新站裡,我會專注分享如何建構理想的自動化架構、避開技術坑洞,以及那些只有測試工程師才懂的邏輯浪漫 —— 例如在西式餐廳點了一盤炒飯(並測試主廚會不會崩潰)。

而在這裡,我依然是那個和你一起數算恩典、聊聊愛情的阿名。說真的,我對於台灣基督徒圈子找對象這件事感到無比困惑,這過程的複雜程度有時不亞於除一個深層的 Bug。未來我會多寫這類文章,畢竟這些內心戲,我想你跟我一樣,都不敢在熟悉的朋友面前高談闊論(笑)。

專業歸於邏輯,生命歸於信仰。我們在兩個地方,不見不散。

2026/01/15

Selenium在find_elements實作上的不同

 By.IDBy.XPATH 在底層掃描邏輯與規範約束力上的不同。


1. By.ID 的實作:優化優先 (Fast Lookup)

在多數瀏覽器和 Android 系統中,ID(或 resource-id)被設計為一個「快速索引」。

  • 實作方式:

    系統通常會維護一個 Hash Map(雜湊表) 或索引表。當你調用 find_elements(By.ID, "...") 時,驅動程式並不一定會從根節點乖乖地開始遍歷,而是直接向系統底層詢問:「誰的 ID 是這個?」

  • 排序特點:

    由於底層索引表的目的是「快」,它有時會返回最先被系統註冊到索引中的元素。在 Android UIAutomator 中,如果一個佈局是異步渲染的,或者某些 View 被優化(如 merge 標籤),索引返回的順序並不絕對保證是物理 DOM 順序。

  • 為什麼抓到子元素?

    在 Android 的 Accessibility Node 樹中,有些父元素會被標記為「僅作為容器(Non-important for accessibility)」,而底層搜尋引擎可能會優先返回「有意義」的葉子節點(Leaf Nodes)。


2. By.XPATH 的實作:路徑規範 (Tree Walking)

XPath 的實作邏輯完全不同,它是一套嚴格的 W3C 標準演算法

  • 實作方式:

    XPath 引擎會強迫進行一次完整的 DOM Tree Walker。它必須解析整個樹狀結構,以確保符合所有路徑約束(例如 // 代表任何深度,.. 代表父級)。

  • 排序特點:

    根據 XPath 規範,結果集(Node-set)必須按照 Document Order(文件順序) 排列。

    文件順序定義: 節點的出現順序與它們在 XML / HTML 源碼中「起始標籤」出現的順序一致。

  • 結果:

    因為父標籤 <android.view.View> 絕對出現在子標籤之前,所以 XPath 返回的列表第一個元素 百分之百 會是父元素。


3. 實作方式與排序對照表

特性 By.ID / By.ResourceIDBy.XPATH
底層原理索引查詢 (Lookup / Index) 樹狀遍歷 (Tree Traversal)
執行速度極快(直接定位)較慢(需要解析整個 DOM)
順序保證弱(取決於底層 OS 註冊順序)(嚴格遵循文件 DFS 順序)
適用場景元素 ID 唯一且明確時需要處理複雜層級或重複 ID 時