用於前端測試的測試管道 101

已發表: 2022-03-10
快速總結 ↬自動化測試可以讓您對合併更改充滿信心,尤其是在廣泛重構或與您的團隊合作時。 因此,您可能已經考慮將測試作為構建例程的一部分,以從中獲得最大價值。 不知道從哪裡開始? 讓我們從頭開始一起實施您的測試管道。

想像一下這種情況:您正在快速接近最後期限,並且您正在利用每一分鐘來實現完成這個複雜重構的目標,並在您的 CSS 文件中進行大量更改。 您甚至可以在乘坐公共汽車期間完成最後的步驟。 但是,您的本地測試似乎每次都失敗,並且您無法讓它們正常工作。 你的壓力水平正在上升

在某知名劇集中確實有類似的場景:出自Netflix的電視劇《如何在網上賣藥(快速)》第三季:

好吧,你可能會想,他至少在使用測試。 你可能想知道,為什麼他仍然處於困境中? 即使您編寫測試,仍有很大的改進空間和避免這種情況。 您如何看待從一開始就監控您的代碼庫和所有更改? 這樣一來,您就不會遇到如此令人討厭的驚喜了,對吧? 包含這樣的自動化測試例程並不難:讓我們從頭到尾一起創建這個測試管道。

我們走吧!

首先要做的事情:基本術語

構建例程可以幫助您對更複雜的重構保持信心,即使在您的小型副項目中也是如此。 但是,這並不意味著您需要成為 DevOps 工程師。 學習一些術語和策略很重要,這就是你來這裡的目的,對吧? 幸運的是,您來對地方了! 讓我們從處理前端項目的測試管道時很快會遇到的基本術語開始。

如果你用谷歌搜索整個測試世界,你可能已經偶然發現“CI/CD”這個術語是第一個術語之一。 它是“Continuous Integration、Continuous Delivery”和“Continuous Deployment”的縮寫,準確地描述為:您可能已經聽說過,它是開發團隊用來更頻繁、更可靠地部署代碼更改的一種軟件分發方法。 CI/CD 涉及兩種互補的方法,它們在很大程度上依賴於自動化。

  • 持續集成
    這是自動化措施的一個術語,用於實現小的、常規的代碼更改並將它們合併到共享存儲庫中。 持續集成包括構建和測試代碼的步驟。

CD 是“Continuous Delivery”和“Continuous Deployment”的首字母縮寫詞,這兩個概念彼此相似,但有時在不同的上下文中使用。 兩者的區別在於自動化的範圍:

  • 持續交付
    它指的是之前已經測試過的代碼過程,運營團隊現在可以將它們部署到實時生產環境中。 這最後一步可能是手動的。
  • 持續部署
    顧名思義,它側重於“部署”方面。 這是一個術語,用於開發人員更改從存儲庫到生產的全自動發布過程,客戶可以直接使用它們。

這些流程旨在使開發人員和團隊能夠擁有一個產品,如果他們願意,您可以隨時發布該產品: 對持續監控、測試和部署的應用程序充滿信心。

為了實現精心設計的 CI/CD 策略,大多數人和組織都使用稱為“管道”的流程。 “管道”是我們在本指南中已經使用的一個詞,沒有解釋它。 如果您考慮這樣的管道,那麼將管道作為長途線路來運輸天然氣等東西並不是太牽強。 DevOps 領域的管道功能非常相似:它們正在“傳輸”要部署的軟件。

管道形式的管道圖,包含三個部分:構建、測試、部署
“真正的”CI/CD 管道包括部署新軟件版本必須執行的幾個步驟,從而使軟件交付過程自動化。 (大預覽)

等等,這聽起來需要學習和記住很多東西,對吧? 我們不是討論過測試嗎? 你是對的:涵蓋 CI/CD 管道的完整概念將為多篇文章提供足夠的內容,我們希望為小型前端項目提供測試管道。 或者您只是缺少管道的測試方面,因此只專注於持續集成過程。 因此,我們將特別關注管道的“測試”部分。 因此,我們將在本指南中創建一個“小型”測試管道。

好的,所以“測試部分”是我們的主要關注點。 在這種情況下,您已經知道哪些測試並第一眼就浮現在您的腦海中? 如果我以這種方式考慮測試,這些是我自發想到的測試類型:

  • 單元測試是一種測試,其中應用程序的次要可測試部分或單元(稱為單元)被單獨和獨立地測試以確保正確運行。
  • 集成測試關注組件或系統之間的交互。 這種測試意味著我們正在檢查單元的相互作用以及它們如何協同工作。
  • 端到端測試,或 E2E 測試,意味著實際的用戶交互由計算機​​模擬; 為此,E2E 測試應包括應用程序中使用的盡可能多的功能區域和技術堆棧部分。
  • 可視化測試是檢查應用程序的可見輸出並將其與預期結果進行比較的過程。 換句話說,它有助於在頁面或屏幕的外觀中發現與純粹功能性錯誤不同的“視覺錯誤”。
  • 靜態分析並不是精確的測試,但我認為這裡有必要提一下。 你可以想像它像拼寫更正一樣工作:它在不運行程序的情況下調試你的代碼並檢測代碼樣式問題。 這個簡單的措施可以防止許多錯誤。

為了有信心在我們獨特的項目中合併大規模重構,我們應該考慮在我們的測試管道中使用所有這些測試類型。 但是先入為主會很快導致挫敗感:評估這些測試類型時您可能會感到迷茫。 我應該從哪裡開始? 哪些類型的測試有多少是合理的?

跳躍後更多! 繼續往下看↓

戰略:金字塔和獎杯

在開始構建我們的管道之前,我們需要製定測試策略。 之前搜索所有這些問題的答案,您可能會在一些隱喻中找到可能的解決方案:在網絡和測試社區中,人們傾向於使用類比來讓您了解應該使用哪種類型的測試。

您可能會遇到的第一個比喻是測試自動化金字塔。 Mike Cohn 在他的著作《Succeeding with Agile》中提出了這個概念,Martin Fowler 將其進一步發展為“實際測試金字塔”。 它看起來像這樣:

測試金字塔
Martin Fowler 的“實際測試金字塔”(大預覽)

如您所見,它由三個級別組成,對應於所呈現的三個測試級別。 金字塔旨在闡明不同測試的正確組合,以指導您制定測試策略:

  1. 單元
    您可以在金字塔的基礎層找到這些測試,因為它們執行速度快且易於維護。 這是由於它們的孤立以及它們針對最小單位的事實。 有關測試非常小的產品的典型單元測試示例,請參閱此示例。
  2. 一體化
    這些處於金字塔的中間,因為它們在執行速度方面仍然可以接受,但仍然讓您有信心比單元測試更接近用戶。 集成類型測試的一個例子是 API 測試,組件測試也可以被認為是這種類型。
  3. E2E 測試(也稱為UI 測試
    正如我們所看到的,這些測試模擬了真正的用戶及其交互。 這些測試需要更多時間來執行,因此成本更高——被放置在金字塔的頂部。 如果您想查看 E2E 測試的典型示例,請查看此示例。

然而,近年來,這種比喻感覺已經過時了。 特別是它的一個缺陷對我來說至關重要:在這個策略中,靜態分析被繞過了。 在我看來,這個比喻沒有考慮使用代碼風格的修復程序或其他 linting 解決方案,這是一個巨大的缺陷。 Lint 和其他靜態分析工具是使用中管道的一個組成部分,不容忽視。

所以,讓我們簡而言之:我們應該使用更新的策略。 但是缺少 linting 工具並不是唯一的缺陷——還有一個更重要的問題需要考慮。 相反,我們可能會稍微轉移注意力:以下引用總結得很好:

“寫測試。 不是很多。 主要是整合。”

— 吉列爾莫·勞赫

讓我們分解這句話來了解它:

  • 編寫測試
    不言自明——你應該總是寫測試。 測試對於在您的應用程序中灌輸信任至關重要——對於用戶和開發人員都是如此。 甚至為自己!
  • 不是很多
    隨意編寫測試不會讓你有任何收穫; 測試金字塔在其聲明中仍然有效,以保持測試優先。
  • 主要是集成
    金字塔忽略的更“昂貴”測試的一張王牌是,隨著您向上移動金字塔,對測試的信心就會增加。 這種增加意味著作為開發人員的用戶和您自己最有可能信任這些測試。

這意味著我們應該按照設計進行更接近用戶的測試。 結果,您可能會支付更多費用,但您會獲得很多回報。 您可能想知道為什麼不選擇 E2E 測試? 因為他們在模仿用戶,他們不是最接近用戶的嗎? 確實如此,但它們的執行速度仍然慢得多,並且需要完整的應用程序堆棧。 因此,這種投資回報比集成測試更晚實現:因此,集成測試在一方面的信任與另一方面的速度和努力之間提供了公平的平衡。

如果您關注 Kent C.Dodds,這些論點對您來說可能聽起來很熟悉,尤其是當您特別閱讀他的這篇文章時。 這些論點並非巧合:他在工作中提出了一個新策略。 我非常同意他的觀點,並將此處最重要的觀點和資源部分中的其他觀點聯繫起來。 他建議的方法源於測試金字塔,但通過改變其形狀以反映集成測試的更高優先級,將其提升到另一個層次。 它被稱為“測試獎杯”。

測試獎杯
我做了一個速寫筆記,它的比例可能不准確,但會讓人明白。 (大預覽)

測試獎杯是一個隱喻,以稍微不同的方式描述測試的粒度; 您應該將測試分配到以下測試類型:

  • 靜態分析在這個比喻中起著至關重要的作用。 這樣,您只需運行提到的調試步驟即可發現拼寫錯誤、類型錯誤和其他錯誤。
  • 單元測試應確保您的最小單元得到適當的測試,但測試獎杯不會像測試金字塔那樣強調它們。
  • 集成是主要關注點,因為它是平衡成本和提高置信度的最佳方式。
  • UI 測試,包括 E2E 和視覺測試,位於測試獎杯的頂端,類似於它們在測試金字塔中的作用。

我在大多數項目中都採用了這種測試獎杯策略,我將在本指南中繼續這樣做。 但是,我需要在這裡給出一點免責聲明:當然,我的選擇是基於我在日常生活中所做的項目。 因此,匹配測試策略的好處和選擇始終取決於您正在處理的項目。 所以,如果它不符合您的需求,請不要難過,我會在相應段落中為其他策略添加資源。

輕微劇透警告:在某種程度上,我也需要稍微偏離這個概念,你很快就會看到。 但是,我認為這很好,但我們稍後會討論。 我的觀點是在規劃和實施管道之前考慮測試類型的優先級和分佈。

如何在線構建這些管道(快速)

Netflix 的電視劇《如何在網上賣藥(快速)》第三季中的主角在接近截止日期時使用 Cypress 進行 E2E 測試,然而,這實際上只是本地測試。 沒有看到 CI/CD,這給他帶來了不必要的壓力。 我們應該用我們學到的理論來避免給定的主角在相應的情節中的壓力。 但是,我們如何將這些知識應用到現實中呢?

首先,我們需要一個代碼庫作為測試基礎。 理想情況下,它應該是我們許多前端開發人員都會遇到的項目。 它的用例應該是一個常見的用例,非常適合動手方法,並使我們能夠從頭開始實施測試管道。 這樣的項目會是什麼?

我對主管道的建議

我想到的第一件事是不言而喻的:我的網站,即我的投資組合頁面,非常適合被視為示例代碼庫,由我們有抱負的管道進行測試。 它在 Github 上開源,因此您可以自由查看和使用它。 關於該網站的技術棧的幾句話:基本上,我在 Vue.js 上構建了這個網站(不幸的是,當我寫這篇文章時,它仍然是第 2 版)作為一個 JavaScript 框架,而 Nuxt.js 作為一個額外的 Web 框架。 您可以在其 GitHub 存儲庫中找到完整的實現示例。

選擇我們的示例代碼庫後,我們應該開始應用我們的學習。 鑑於我們希望使用測試獎杯作為我們測試策略的起點,我提出了以下概念:

作者對主要管道的建議
您是否注意到我的管道描述中的一個括號具有透明顏色? 我有目的地著色; 這就是我之前的小免責聲明的來源。 (大預覽)

由於我們正在處理一個相對較小的代碼庫,我將合併單元測試和集成測試的各個部分。 然而,這只是這樣做的一小部分原因。 其他更重要的原因是:

  • 單元的定義通常是“有待討論的”:如果你讓一群開發人員定義一個單元,你會得到各種各樣的、不同的答案。 正如一些人提到的功能、類或服務——次要單元——另一個開發人員將計入完整的組件。
  • 除了那些定義上的困難之外,在單元和集成之間劃一條線可能很棘手,因為它非常模糊。 這種鬥爭是真實的,尤其是對於前端,因為我們經常需要 DOM 來成功驗證測試基礎。
  • 通常可以使用相同的工具和庫來編寫兩個集成測試。 因此,我們也許可以通過合併它們來節省資源。

首選工具:GitHub Actions

我們知道我們想要在管道中描繪什麼,接下來是選擇持續集成和交付 (CI/CD) 平台。 在為我們的項目選擇這樣的平台時,我會考慮我已經獲得的經驗:

  • GitLab,在我工作場所的日常工作中,
  • 我的大多數輔助項目中的 GitHub Actions。

但是,還有許多其他平台可供選擇。 考慮到所使用的技術和框架,我建議您始終根據項目及其特定要求進行選擇——這樣就不會出現兼容性問題。 請記住,我們使用了一個已經在 GitHub 上發布的 Vue 2 項目,恰好符合我之前的經驗。 另外,上面提到的 GitHub Actions 只需要你項目的 GitHub 倉庫作為起點即可; 專門為其創建和運行 GitHub Actions 工作流。 因此,我將在本指南中使用 GitHub Actions。

因此,如果發生某些給定事件,這些 GitHub 操作為您提供了一個運行專門定義的工作流的平台。 這些事件是我們存儲庫中觸發工作流的特定活動,例如,將更改推送到分支。 在本指南中,這些事件與 CI/CD 相關聯,但此類工作流程也可以自動化其他工作流程,例如為拉取請求添加標籤。 GitHub 可以在 Windows、Linux 和 macOS 虛擬機上執行它們。

為了可視化這樣的工作流程,它看起來像這樣:

GitHub Action 工作流程的圖示
Github Action 的工作流程是一個可配置的自動化過程(因此整個過程以綠色表示)。 (大預覽)

在本文中,我將使用一個工作流程來描繪一個管道; 這意味著一個工作流程將包含我們所有的測試步驟,從靜態分析到各種 UI 測試。 該管道,或在以下段落中稱為“工作流”,將由一個甚至多個作業組成,這些作業是在同一個運行器上執行的一組步驟。

這個工作流程正是我想在上圖中繪製的結構。 在其中,我們仔細研究了這樣一個包含多個工作的跑步者; 作業本身的步驟由不同的步驟組成。 這些步驟可以是以下兩種類型之一:

  1. 一個步驟可以運行一個簡單的腳本。
  2. 一個步驟可以運行一個動作。 此類操作是可重用的擴展,通常是完整的自定義應用程序。

記住這一點,GitHub 操作的實際工作流程如下所示:

GitHub 操作的工作流程,作者有一些解釋
語法的第一眼——全在一個。 (大預覽)

編寫我們的第一個 GitHub Action

最後,我們可以編寫自己的第一個 Github 動作並編寫一些代碼! 我們將從我們的基本工作流程和我們想要描述的工作的第一個大綱開始。 記住我們的測試獎杯,每項工作都將類似於測試獎杯中的一層。 這些步驟將是我們需要做的事情來自動化這些層。

因此,我首先創建.github/workflows/目錄來存儲我們的工作流。 我們將創建一個名為tests.yml的新文件,以在此目錄中包含我們的測試工作流程。 除了上圖中看到的標準工作流語法外,我將繼續進行如下操作:

  1. 我將把我們的工作流程命名為Tests CI
  2. 因為我想在每次推送到遠程分支時執行我的工作流並提供手動選項來啟動我的管道,所以我將配置我的工作流以在pushworkflow_dispatch上運行。
  3. 最後但同樣重要的是,如“我對基本管道的建議”段落所述,我的工作流程將包含三個工作:
    • static-eslint用於靜態分析;
    • unit-integration-jest用於將單元和集成測試合併到一項工作中;
    • ui-cypress作為 UI 階段,包括基本的 E2E 測試和視覺回歸測試。
  4. 基於 Linux 的虛擬機應該執行所有作業,所以我將使用ubuntu-latest

輸入正確的YAML文件語法,我們工作流程的第一個大綱可能如下所示:

 name: Tests CI on: [push, workflow_dispatch] # On push and manual jobs: static-eslint: runs-on: ubuntu-latest steps: # 1 steps unit-integration-jest: runs-on: ubuntu-latest steps: # 1 step ui-cypress: runs-on: ubuntu-latest steps: # 2 steps: e2e and visual

如果您想深入了解 GitHub 操作中的工作流程的詳細信息,請隨時訪問其文檔。 無論哪種方式,您無疑都知道這些步驟仍然缺失。 別擔心——我也知道。 因此,要使這個工作流程大綱充滿活力,我們需要定義這些步驟並決定將哪些測試工具和框架用於我們的小型投資組合項目。 所有接下來的段落都將描述各自的工作,並包含使所述測試的自動化成為可能的幾個步驟。

靜態分析

正如測試獎杯所暗示的,我們將從工作流程中的 linter 和其他代碼風格的修復程序開始。 在這種情況下,您可以從許多工具中進行選擇,其中一些示例包括:

  • Eslint 作為 Javascript 代碼樣式修復器。
  • 用於 CSS 代碼修復的 Stylelint。
  • 我們可以考慮更進一步,例如,要分析代碼複雜性,您可以查看像審查器這樣的工具。

這些工具的共同點是它們指出了模式和約定中的錯誤。 但是,請注意,其中一些規則是個人喜好問題。 由您決定執行它們的嚴格程度。 舉個例子,如果您要容忍兩個或四個製表符的縮進。 更重要的是專注於要求一致的代碼風格和捕捉更關鍵的錯誤原因,例如使用“==”與“===”。

對於我們的投資組合項目和本指南,我想開始安裝 Eslint,因為我們使用了大量的 Javascript。 我將使用以下命令安裝它:

 npm install eslint --save-dev

當然,如果我不想使用 NPM,我也可以使用 Yarn 包管理器的替代命令。 安裝後,我需要創建一個名為.eslintrc.json的配置文件。 現在讓我們使用基本配置,因為本文不會首先教您如何配置 Eslint:

 { "extends": [ "eslint:recommended", ] }

如果您想詳細了解 Eslint 配置,請參閱本指南。 接下來,我們要做第一步來自動化 Eslint 的執行。 首先,我想將命令設置為將 Eslint 作為 NPM 腳本執行。 我通過在script部分的package.json文件中使用此命令來實現此目的:

 "scripts": { "lint": "eslint --ext .js .", },

然後我可以在我們的 GitHub 工作流程中執行這個新創建的腳本。 但是,在這樣做之前,我們需要確保我們的項目可用。 因此,我們使用預配置的 GitHub Action actions/checkout@v2來執行此操作:簽出我們的項目,以便您的 GitHub 操作的工作流程可以訪問它。 下一步是安裝我的投資組合項目所需的所有 NPM 依賴項。 在那之後,我們終於準備好運行我們的 eslint 腳本了! 我們使用 linting 的最後一項工作現在看起來像這樣:

 static-eslint: runs-on: ubuntu-latest steps: # Action to check out my codebase - uses: actions/checkout@v2 # install NPM dependencies - run: npm install # Run lint script - run: npm run lint

你現在可能想知道:當我們的npm run lint時,這個管道會自動“失敗”嗎? 是的,這確實是開箱即用的。 一旦我們完成了工作流程的編寫,我們將在 Github 上查看屏幕截圖。

單元與集成

接下來,我想創建包含單元和集成步驟的作業。 關於本文使用的框架,我想給大家介紹一下用於前端測試的 Jest 框架。 當然,如果您不想使用 Jest,則無需使用 - 有許多替代方案可供選擇:

  • 賽普拉斯還提供非常適合集成測試的組件測試。
  • Jasmine 也是另一個值得研究的框架。
  • 還有更多; 我只是想列舉幾個。

Jest 由 Facebook 開源提供。 該框架歸功於其對簡單性的關注,同時與許多 JavaScript 框架和項目兼容,包括 Vue.js、React 或 Angular。 我還可以將 jest 與 TypeScript 結合使用。 這使得該框架非常有趣,特別是對於我的小型投資組合項目,因為它兼容且非常適合。

我們可以通過輸入以下命令直接從我的投資組合項目的這個根文件夾開始安裝 Jest:

 npm install --save-dev jest

安裝後,我已經可以開始編寫測試了。 但是,本文重點介紹使用 Github 操作自動化這些測試。 因此,要了解如何編寫單元或集成測試,請參閱以下指南。 在我們的工作流程中設置作業時,我們可以與static-eslint作業類似地進行。 所以,第一步是再次創建一個小的 NPM 腳本,以便稍後在我們的工作中使用:

 "scripts": { "test": "jest", },

之後,我們將定義名為unit-integration-jest的工作,類似於我們之前為 linter 所做的工作。 因此,工作流程將檢查我們的項目。 除此之外,我們將使用與我們的第一個static-eslint作業的兩個細微差別:

  1. 我們將使用一個操作作為安裝 Node.js 的步驟。
  2. 之後,我們將使用我們新創建的 npm 腳本來運行我們的 Jest 測試。

這樣,我們的unit-integration-jest工作將如下所示:

 unit-integration-jest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # Set up node - name: Run jest uses: actions/setup-node@v1 with: node-version: '12' - run: npm install # Run jest script - run: npm test

UI 測試:E2E 和可視化測試

最後但同樣重要的是,我們將編寫我們的ui-cypress Job,其中將包含 E2E 測試和視覺測試。 將這兩者結合在一項工作中很聰明,因為我將同時使用 Cypress 框架。 當然,您可以考慮其他框架,例如下面的 NightwatchJS 和 CodeceptJS。

同樣,我們將僅介紹在 GitHub 工作流程中進行設置的基礎知識。 如果你想詳細了解如何編寫 Cypress 測試,我的另一本指南正好解決了這個問題。 本文將指導您完成定義 E2E 測試步驟所需的一切。 好的,首先我們將安裝 Cypress,就像我們安裝其他框架一樣,在我們的根文件夾中使用以下命令:

 npm install --save-dev cypress

這一次,我們不需要定義 NPM 腳本。 賽普拉斯已經為我們提供了自己的 GitHub 操作cypress-io/github-action@v2 。 在那裡,我們只需要配置一些東西來讓它運行:

  • 我們需要確保我們的應用程序已完全設置並正常工作,因為 E2E 測試需要完整的應用程序堆棧可用。
  • 我們需要命名我們在其中運行 E2E 測試的瀏覽器。
  • 我們需要等待網絡服務器完全運行,這樣計算機才能像真正的用戶一樣工作。

幸運的是,我們的 Cypress 操作幫助我們使用with區域存儲所有這些配置。 這樣,我們當前的 GitHub 作業看起來是這樣的:

 steps: - name: Checkout uses: actions/checkout@v2 # Install NPM dependencies, cache them correctly # and run all Cypress tests - name: Cypress Run uses: cypress-io/github-action@v2 with: browser: chrome headless: true # Setup: Nuxt-specific things build: npm run generate start: npm run start wait-on: 'http://localhost:3000'

視覺測試:為您的測試提供一些關注

記住我們編寫本指南的初衷:我對 SCSS 文件進行了大量更改,進行了重大重構——我想在構建例程中添加測試,以確保不會破壞其他任何內容。 有了靜態分析、單元、集成和端到端測試,我們應該很有信心,對吧? 沒錯,但我仍然可以做一些事情來使我的管道更加防彈和完美。 你可以說它正在變成奶精。 尤其是在處理 CSS 重構時,E2E 測試只能提供有限的幫助,因為它只能通過在測試中寫下來完成您所說的事情。

幸運的是,除了書面命令之外,還有另一種捕獲錯誤的方法,因此,除了概念之外。 這叫做視覺測試:你可以把這種測試想像成一個找不同的謎題。 從技術上講,可視化測試是一種屏幕截圖比較,它將截取您的應用程序的屏幕截圖並將其與現狀進行比較,例如,來自項目的主分支。 這樣一來,任何意外的樣式問題都不會被忽視——至少在您使用可視化測試的領域是這樣。 至少在我的經驗中,這可以將可視化測試變成大型 CSS 重構的救星。

有許多可視化測試工具可供選擇,值得一看:

  • Percy.io,我在本指南中使用的 Browserstack 工具;
  • 如果您不想使用 SaaS 解決方案並同時完全開源,則可以使用 Visual Regression Tracker;
  • 具有 AI 支持的 Applitools。 在 Smashing 雜誌上有一個關於這個工具的令人興奮的指南;
  • 彩色故事書。

對於本指南以及基本上對於我的投資組合項目,重用我現有的賽普拉斯測試進行可視化測試至關重要。 如前所述,由於集成簡單,我將在此示例中使用 Percy。 雖然它是一個 SaaS 解決方案,但仍然有很多部分是開源的,並且有一個免費計劃,對於許多開源或其他副項目來說應該足夠了。 但是,如果您覺得在使用開源工具的同時完全自託管更自在,您可以試試 Visual Regression Tracker。

本指南將只為您提供 Percy 的簡要概述,否則將為全新文章提供內容。 但是,我會為您提供幫助您入門的信息。 如果您現在想深入了解細節,我建議您查看 Percy 的文檔。 那麼,我們怎樣才能讓我們的測試眼睛,可以這麼說呢? 假設我們現在已經編寫了一兩個 Cypress 測試。 想像它們看起來像這樣:

 it('should load home page (visual)', () => { cy.get('[data-cy=Polaroid]').should('be.visible'); cy.get('[data-cy=FeaturedPosts]').should('be.visible'); });

當然,如果我們想安裝 Percy 作為我們的可視化測試解決方案,我們可以使用 cypress 插件來實現。 所以,就像我們今天做了幾次一樣,我們使用 NPM 將它安裝在我們的根文件夾中:

 npm install --save-dev @percy/cli @percy/cypress

之後,您只需要將percy/cypress包導入到您的cypress/support/index.js索引文件中:

 import '@percy/cypress';

此導入將使您能夠使用 Percy 的快照命令,該命令將從您的應用程序中獲取快照。 在這種情況下,快照是指從您可以配置的不同視口或瀏覽器截取的一組屏幕截圖。

 it('should load home page (visual)', () => { cy.get('[data-cy=Polaroid]').should('be.visible'); cy.get('[data-cy=FeaturedPosts]').should('be.visible'); // Take a snapshot cy.percySnapshot('Home page'); });

回到我們的工作流程文件,我想將 Percy 測試定義為工作的第二步。 在其中,我們將運行腳本npx percy exec -- cypress run與 Percy 一起運行我們的測試。 要將我們的測試和結果連接到我們的 Percy 項目,我們需要傳遞我們的 Percy 令牌,該令牌被 GitHub 機密隱藏。

 steps: # Before: Checkout, NPM, and E2E steps - name: Percy Test run: npx percy exec -- cypress run env: PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}

為什麼我需要 Percy 令牌? 這是因為 Percy 是用於維護我們的屏幕截圖的 SaaS 解決方案。 它將保留屏幕截圖和現狀以供比較,並為我們提供屏幕截圖審批工作流程。 在那裡,您可以批准或拒絕任何即將發生的更改:

Percy 的審批工作流程
(大預覽)

查看我們的作品:GitHub 集成

恭喜! 我們成功地構建了我們的第一個 GitHub 操作工作流。 讓我們最後看一下我的投資組合頁面存儲庫中的完整工作流程文件。 你不好奇它在實際使用中的樣子嗎? 您可以在存儲庫的“操作”選項卡中找到您正在使用的 GitHub 操作:

GitHub 操作選項卡
(大預覽)

在那裡,您可以找到與您的工作流文件等效的所有工作流。 如果您查看一個工作流程,例如我的“Tests CI”工作流程,您可以檢查它的所有工作:

測試 CI 工作流視圖
(大預覽)

如果您想查看您的一項工作,您也可以在邊欄中選擇它。 在那裡,您可以檢查您的工作日誌:

因錯誤而失敗的工作
(大預覽)

你看,如果錯誤發生在你的管道中,你就能夠檢測到它們。 順便說一句,“操作”選項卡不是您可以檢查 GitHub 操作結果的唯一地方。 您也可以在拉取請求中檢查它們:

GitHub 操作的拉取請求
(大預覽)

I like to configure those GitHub actions the way they need to be executed successfully: Otherwise, it's not possible to merge any pull requests into my repository.

結論

CI/CD helps us perform even major refactorings — and dramatically minimizes the risk of running into nasty surprises. The testing part of CI/CD is taking care of our codebase being continuously tested and monitored. Consequently, we will notice errors very early, ideally before anyone merges them into your main branch. Plus, we will not get into the predicament of correcting our local tests on the way to work — or even worse — actual errors in our application. I think that's a great perspective, right?

To include this testing build routine, you don't need to be a full DevOps engineer: With the help of some testing frameworks and GitHub actions, you're able to implement these for your side projects as well. I hope I could give you a short kick-off and got you on the right track.

I'm looking forward to seeing more testing pipelines and GitHub action workflows out there! ️

資源

  • An excellent guide on CI/CD by GitHub
  • “The practical test pyramid”, Ham Vocke
  • Articles on the testing trophy worth reading, by Kent C.Dodds:
    • “Write tests. Not too many. Mostly integration”
    • “The Testing Trophy and Testing Classifications”
    • “Static vs Unit vs Integration vs E2E Testing for Frontend Apps”
  • I referred to some examples of the Cypress real world app
  • Documentation of used tools and frameworks:
    • GitHub actions
    • Eslint docs
    • 笑話文檔
    • 賽普拉斯文檔
    • Percy documentation