建構 Selenium
分類
我們從 Selenium 專案一開始就知道的一件事是,人們喜歡使用一種以上的語言編碼。有些人喜歡一點 JS,有些人喜歡 Ruby,還有些人偏好 C# 或 Java。
更複雜的是,我們希望在您將使用的語言繫結之間共享許多元件。範例包括「原子」(可重複使用的 javascript 片段,用於執行常見功能 – 例如「isDisplayed」或「getAttribute」– 我們希望無論您喜歡用哪種語言編寫測試,它們的工作方式都相同)、諸如我們的 CDP 支援之類的東西,它使用描述我們可以呼叫的所有可用功能的共享檔案,以及新的 Selenium Manager,它是用 Rust 編寫的,但我們將其與每個語言繫結捆綁在一起。
將原始碼和其他人工產物(例如原子)一起轉換為我們發布的人工產物(例如 Selenium Server 或語言繫結)的過程稱為「建構」。市面上有許多建構工具。如果您是 java 開發人員,您可能已經接觸過 Maven 或 Gradle。如果您是 JS 駭客,那麼 npm 或 yarn 之類的東西可能是您使用過的。如果您是 C 開發人員(仍然有很多!),那麼您很可能正在使用 make 或 CMake。
許多建構工具的問題在於它們專注於一種語言。Npm 很棒,但對於 Java 專案來說是個糟糕的選擇。Gradle 還不錯,但如果您使用 Ruby 就不行了。
為什麼這是個問題?因為在 Selenium 程式碼庫中,我們希望支援多種不同的語言,並且我們希望能夠將它們「縫合」在一起成為一個有凝聚力的整體。例如,Selenium jars 包含相當大量的 JS。Ruby gems 也是如此。
我們想要的是一個可以應對許多不同語言的單一建構工具,以便我們可以將我們的建構編織成我們只需要該工具的東西。
輸入 Bazel。這是一個最初由 Google 開發的建構工具,但現在是開放原始碼且越來越廣泛使用。Bazel 本身的功能相對有限,但它可以使用「規則集」輕鬆擴展,使其能夠支援我們需要的一切,甚至更多!
Bazel 是新一代建構工具之一,專注於揭示建構過程的每個部分如何與其他部分相關。您可以想像繪製一張圖表,其中我們需要編譯的每個項目(例如 Selenium Manager、原子或我們發布的 jar 之一)都透過線條連接到它們所依賴的其他部分。在電腦科學中,該圖表稱為「圖」,並且因為每條線都有方向(「這個東西依賴於那個東西」),我們稱之為有向圖。因為我們不能依賴於依賴於自身的事物,所以我們不能引入「循環」。Bazel 是一個旨在與這些「有向無環圖」一起使用的建構工具。
關於這些圖的一個好處是,有眾所周知的方法可以找出建構的哪些部分可以平行執行。現代電腦的 CPU 具有許多(4、8、16!)核心、大量記憶體和快速 SSD:它可以輕鬆地同時執行許多任務。因此 Bazel 利用了這一點,盡可能同時運行建構的許多部分。這使得我們的建構比過去快得多!
更好的是,Bazel 讓我們列出建構的每個部分所依賴的所有內容。不僅僅是原始碼,還有我們正在使用的工具的版本。這使得專案新手開發人員更容易上手:他們只需要克隆 我們的 repo,確保他們安裝了 Bazel,然後建構過程將負責確保他們擁有所需的一切(雖然第一次建構可能會非常慢,因為需要的一切都將從網路下載)。這不僅對專案新手來說很好,對現有的開發人員來說也很好。他們不再需要知道如何安裝和設定他們可能不熟悉的工具鏈 – 他們只需運行建構即可。
使用「建構圖」,Bazel 能夠判斷 Selenium 原始碼中的哪些程式碼片段依賴於哪些其他部分。這意味著,儘管我們可以告訴 Bazel 在我們進行變更時「運行我們所有的測試」,但它足夠聰明,知道它只需要運行實際受變更影響的那些測試。您可以在 此影片中看到實際運作情況,但不用說,這可以為我們節省大量時間!我們也可以要求 Bazel 重新運行不穩定的測試
但是描述建構所需的所有內容還有另一個優勢。由於我們已向 Bazel 描述了我們需要的一切以及所有組件如何組合在一起,因此無需僅在我們自己的機器上運行建構。我們正在與 EngFlow 合作以使用他們的建構網格。與其僅在我們的機器上同時運行少量項目,我們可以在他們的建構網格上運行多次。我們在那裡的建構速度非常快!
因此,這就是我們在專案中使用 Bazel 的原因:它在單一工具中支援我們想要使用的所有語言,讓我們無需考慮如何設定我們的開發機器,建構運行速度非常快,並且我們可以利用建構網格來更快地建構事物。




