將 Cypress 測試與 Docker、Buildkite 和 CICD 集成 #frontend@twiliosendgrid

已發表: 2020-12-30

我們編寫了許多端到端 (E2E) 賽普拉斯測試來驗證我們的 Web 應用程序在後端仍能按預期工作。 在編寫完這些瀏覽器自動化測試之後,我們希望在合併代碼並部署到特定環境之前,始終讓這些 Cypress 測試運行或以某種方式觸發,就像我們的單元測試一樣。 這導致我們希望在 Docker 容器中運行 Cypress 測試,以與我們的持續集成 (CI) 提供商和我們在雲中用於運行這些容器的機器集成。

在部署流程方面,我們使用 Buildkite 作為我們的 CI 提供者。 當我們計劃全面移動代碼時,這使我們能夠在 Buildkite 管道中為我們的應用程序生成自動化步驟。 對於更多上下文,管道是通常與應用程序存儲庫相關聯的地方,當您創建拉取請求、推送新代碼更改、將代碼合併到主服務器以及部署到不同環境時,我們可以在其中查看構建或觸發構建,並執行某些步驟來運行. 我們為不同的目的創建多個管道,例如部署、觸發賽普拉斯測試和按計劃運行的特定賽普拉斯測試。

這篇博文假設您之前已經編寫過 Cypress 測試並運行了一些測試,但想了解如何在您的開發和部署流程中始終運行這些測試。 如果您想了解更多關於編寫賽普拉斯測試的概述,您可以查看這篇較早的博客文章,然後在您有需要運行的內容時重新訪問。

我們的目標是通過了解我們如何在部署管道中使用 Docker Compose 和 Buildkite 來完成有關如何將賽普拉斯測試與您的 CI 提供程序集成到 Docker 容器中的想法。 這些想法可以在您的基礎架構中擴展,以便在觸發賽普拉斯測試時應用策略、命令和環境變量。

我們的標準 CICD 流程

在我們的標准開發和部署流程中,我們設置了兩個管道:

  1. 第一個處理我們推送代碼時的部署步驟。
  2. 第二個觸發我們的賽普拉斯測試並行運行並被記錄。 此操作的成功或失敗會影響部署管道。

在我們的部署管道中,我們構建了我們的 Web 應用程序資產,運行單元測試,並在部署到每個環境之前觸發選定的賽普拉斯測試。 我們確保它們在取消按鈕部署之前通過。 第二個管道中的這些觸發賽普拉斯測試也在 Docker 容器中運行,並通過記錄鍵連接到付費的賽普拉斯儀表板,因此我們可以回顧這些賽普拉斯測試的視頻、屏幕截圖和控制台輸出以調試任何問題。

使用 Buildkite 的選擇輸入,我們設計了一個動態的選擇您自己的冒險,因此用戶可以選擇“是”或“否”來決定在我們推送更多代碼時運行和驗證哪些賽普拉斯規範文件夾。 所有選項的默認答案都是“否”,但“是”的值將是賽普拉斯規範文件夾的全局路徑。

有時,如果我們的代碼更改不影響其他頁面,我們不想運行所有 Cypress 測試。 相反,我們只想觸發我們知道會受到影響的測試。 我們可能還需要為生產中的緊急錯誤問題部署快速修復,因為我們有足夠的信心不運行我們的賽普拉斯測試,這可能需要 0 到 10 分鐘,具體取決於我們觸發的測試數量。 我們在這部分的可視化和 YML 步驟中提供了一個示例。

接下來,我們實現了我們自己的名為runCypress.sh的 Bash 腳本,以便在該選擇步驟之後運行以解析選擇的“是”或“否”值。 我們這樣做是為了形成一個逗號分隔的規範路徑列表,以運行並作為選項--spec附加到我們最終的賽普拉斯命令中,該命令在觸發管道中的 Docker 容器中運行。 我們導出環境變量,例如“CYPRESS_SPECS”中形成的規範列表和“CYPRESS_TEST_ENV”中的當前測試環境,以在腳本末尾使用buildkite-agent pipeline upload "$DIRNAME"/triggerCypress.yml觸發的管道中使用buildkite-agent pipeline upload "$DIRNAME"/triggerCypress.yml

您可能已經註意到我們還如何導出“ASYNC”環境變量。 在 Buildkite 中,您可以根據成功或失敗選擇將觸發的構建步驟設置為阻塞或非阻塞。 如果我們將“ASYNC”設置為 true,我們的主要部署管道步驟將繼續運行,並且不會等待不同管道中觸發的賽普拉斯測試完成。 管道的成功或失敗不影響部署管道的成功或失敗。

如果我們將“ASYNC”設置為 false,我們的主要部署管道步驟將被阻止,直到在不同管道中觸發的賽普拉斯測試完成。 觸發構建的成功或失敗會導致部署管道的整體成功或失敗。

當我們的代碼仍處於打開拉取請求的功能分支中時,我們希望推送更多更改,觸發一些賽普拉斯測試,並查看事情的表現。 但是,如果觸發的測試失敗,我們並不總是希望阻止其餘的部署管道步驟運行,因為在此過程中可能會有更多的變化。 在這種情況下,我們將“ASYNC”設置為 false,以便在賽普拉斯測試失敗時不阻塞。 對於我們已經將拉取請求合併到 master 並部署到 staging 但希望在部署到生產之前觸發 Cypress 測試的情況,我們將“ASYNC”設置為 true,因為我們確實希望 Cypress 測試始終在投入生產之前通過.

回到runCypress.sh ,我們回想起腳本通過調用具有分配的環境變量值的triggerCypress.yml文件來觸發第二個管道運行。 triggerCypress.yml文件看起來像這樣。 您會注意到“觸發”步驟和將值插入到構建消息中有助於調試和動態步驟名稱。

無論我們觸發賽普拉斯測試以從我們的部署管道運行到單獨的觸發管道,還是按計劃在專用管道中運行賽普拉斯測試,我們都遵循並重用相同的步驟,同時僅更改環境變量值。

這些步驟包括:

  1. 使用最新標籤和唯一版本標籤構建 Docker 映像
  2. 將 Docker 鏡像推送到我們的私有註冊表
  3. 根據我們在 Docker 容器中的環境變量值,拉下同一個圖像以運行我們的賽普拉斯測試

這些步驟在pipeline.cypress.yml文件中進行了概述,如下所示:

當我們觸發賽普拉斯測試運行時,它將在賽普拉斯觸發管道中啟動一個單獨的構建。 根據構建的成功或失敗,賽普拉斯測試運行將阻止或允許我們在主分支構建從暫存到生產時部署到生產。

單擊“Triggered cypress/integration/…”步驟將帶您進入觸發管道的構建,並使用類似這樣的視圖查看測試的進展情況。

如果您對 Docker 部分是如何連接的感到好奇,我們的Dockerfile.cypressdocker-compose.cypress.yml使用從我們的管道導出的那些環境變量,然後使用我們應用程序的package.json中指向右側的正確 Cypress 命令測試環境並運行選定的規範文件。 下面的片段顯示了我們可以擴展和改進以更加靈活的一般方法。


除了在我們通常的集成和部署週期中運行的測試之外,我們還創建了專用的 Buildkite 管道。 這些管道按計劃運行,以針對我們的暫存環境進行重要測試,以確保我們的前端和後端服務正常工作。 我們重用了類似的管道步驟,調整了 Buildkite 管道設置中的某些環境變量值,並設置了一個 cron 計劃以在預定時間運行。 這有助於我們在暫存環境中發現許多錯誤和問題,因為我們會繼續監控測試的執行情況,以及下游或我們自己的代碼推送是否可能導致測試失敗。

並行化

我們還利用並行化標誌來利用我們可以從我們的 Ops 團隊設置的構建代理隊列中啟動的 AWS 機器的數量。 有了這個並行化標誌,賽普拉斯會根據我們在 Buildkite 的“並行”屬性中設置的數量自動神奇地啟動一定數量的機器。

我們能夠在大約 5 分鐘內為我們的一個應用程序存儲庫運行 200 多個測試。

然後,它將所有賽普拉斯測試展開,以在這些機器上並行運行,同時為特定構建運行保留每個測試的記錄。 這大大提高了我們的測試運行時間!

以下是並行化賽普拉斯測試時的一些提示:

  • 遵循儀表板服務中的建議以獲得最佳機器數量,並在環境變量中設置機器數量以實現管道的靈活性。
  • 拆分成更小的測試文件,尤其是將運行時間較長的測試分解成塊,我們可以更好地跨機器並行化。
  • 確保您的賽普拉斯測試是獨立的,不會相互影響或相互依賴。 在處理更新、創建或刪除相關的流程時,請使用單獨的用戶和數據資源,以避免測試相互踩踏並陷入競爭條件。 您的測試文件可以按任何順序運行,因此請確保在運行所有測試時這不是問題。
  • 對於 Buildkite,除了parallel選項之外,請記住將 Buildkite 構建 ID 環境變量值傳遞給--ci-build-id選項,以便在跨機器並行測試時知道與哪個唯一構建運行相關聯。

回顧:

為了將您的賽普拉斯測試連接到您的 CI 提供商,例如 Buildkite,您需要:

  1. 使用您的應用程序代碼構建 Docker 映像,使用必要的賽普拉斯基礎映像和在 Node 環境中針對某些瀏覽器運行測試所需的依賴項。
  2. 將您的 Docker 映像推送到帶有特定標籤的註冊表
  3. 在後面的步驟中拉下相同的圖像
  4. 如果您使用的是賽普拉斯儀表板服務,請以無頭模式和記錄鍵運行賽普拉斯測試。
  5. 設置不同的環境變量值並將它們插入您為賽普拉斯運行的命令中,以針對這些 Docker 容器中的特定測試環境觸發選定的賽普拉斯測試。

這些通用步驟可以重複使用並應用於按計劃運行的賽普拉斯測試和其他用例,例如觸發測試以在部署管道之外針對選定的瀏覽器運行。 關鍵是利用 CI 提供者的功能,並根據環境變量值將命令設置為靈活且可配置的。

根據環境變量值將您的命令設置為靈活且可配置的。

一旦您通過 CI 提供商在 Docker 中運行測試(並且如果您為 Dashboard Service 付費),您就可以利用跨多台機器並行化測試的優勢。 您可能必須修改現有的測試和資源,使它們不依賴於另一個,以避免任何測試相互影響。

我們還討論了您可以自己嘗試的想法,例如創建一個測試套件來驗證您的後端 API 或觸發測試以針對您選擇的瀏覽器運行。 在 Cypress 文檔中還有更多設置持續集成的方法

此外,在部署流程或計劃間隔期間運行這些賽普拉斯測試非常重要,以確保您的開發環境始終按預期工作。 無數次,我們的賽普拉斯測試發現了與下游後端服務相關的問題,這些服務以某種方式關閉或更改,表現為前端應用程序錯誤。 在我們推出新的 React 代碼更改後,他們尤其使我們免於網頁中的意外錯誤。

在我們的測試環境中勤奮地維護通過測試並監控失敗的測試運行會導致更少的支持票證和更快樂的生產客戶。 當您推送新的代碼更改時,保持一套健康穩定的賽普拉斯測試運行可以讓您更有信心相信一切正常,我們建議您和您的團隊對賽普拉斯測試也這樣做。

有關賽普拉斯測試的更多資源,請查看以下文章:

  • 編寫 E2E 測試時要考慮什麼
  • 編寫柏樹測試的 1,000 英尺概述
  • TypeScript 包含 Cypress 測試中的所有內容
  • 在 Cypress 測試中處理電子郵件流
  • 配置、組織和整合賽普拉斯測試的想法