試實(shí)踐指南:基于 Cypress 的 E2E 測(cè)試體系全解析)
Metabase 端到端測(cè)試實(shí)踐指南基于 Cypress 的 E2E 測(cè)試體系全解析【免費(fèi)下載鏈接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:項(xiàng)目地址: https://gitcode.com/GitHub_Trending/me/metabaseMetabase 使用 Cypress 構(gòu)建了一套完整的端到端E2E測(cè)試體系用于對(duì)整個(gè)應(yīng)用——包括前端、后端和應(yīng)用數(shù)據(jù)庫(kù)——進(jìn)行整體驗(yàn)證。本文基于 Metabase 官方開(kāi)發(fā)者指南docs/developers-guide/e2e-tests.md結(jié)合倉(cāng)庫(kù)中的真實(shí)源碼e2e/目錄下的 runner、support、scenarios 等實(shí)現(xiàn)系統(tǒng)講解 E2E 測(cè)試的啟動(dòng)方式、測(cè)試結(jié)構(gòu)、輔助機(jī)制、快照體系、Snowplow/SMTP/翻譯字典等特殊場(chǎng)景以及 CI 與調(diào)試技巧幫助你快速上手并為 Metabase 編寫(xiě)高質(zhì)量的端到端測(cè)試。什么是 Metabase 的 E2E 測(cè)試端到端測(cè)試是運(yùn)行在真實(shí) Web 瀏覽器中的 JavaScript 腳本訪問(wèn)不同的 URL、點(diǎn)擊各種 UI 元素、輸入文本并斷言預(yù)期行為是否發(fā)生例如界面上出現(xiàn)某個(gè)元素或發(fā)生了某個(gè)網(wǎng)絡(luò)請(qǐng)求。與單元測(cè)試不同E2E 測(cè)試面向的是完整應(yīng)用——前端、后端和應(yīng)用數(shù)據(jù)庫(kù)同時(shí)參與最接近真實(shí)用戶的使用路徑。在 Metabase 中E2E 測(cè)試源碼位于e2e/test/scenarios目錄其目錄結(jié)構(gòu)大致鏡像 Metabase 的 URL 結(jié)構(gòu)。例如Admin 后臺(tái) datamodel數(shù)據(jù)模型頁(yè)面的測(cè)試位于e2e/test/scenarios/admin/datamodel對(duì)應(yīng)文件如 datamodel.cy.spec.ts、segments.cy.spec.ts。Metabase 的 E2E runner 會(huì)自行構(gòu)建后端并創(chuàng)建臨時(shí)的 H2 應(yīng)用數(shù)據(jù)庫(kù)進(jìn)程被殺死時(shí)兩者都會(huì)被銷(xiāo)毀。默認(rèn)保留端口為本地主機(jī)的4000。你完全可以同時(shí)在localhost:3000運(yùn)行自己的本地 Metabase 實(shí)例這在調(diào)試時(shí)非常有用。提示動(dòng)手之前建議先熟悉 Cypress 官方的最佳實(shí)踐Best Practices本文假定讀者已具備 Cypress 基礎(chǔ)??焖匍_(kāi)始標(biāo)準(zhǔn)開(kāi)發(fā)流程Metabase 的 E2E 測(cè)試標(biāo)準(zhǔn)開(kāi)發(fā)流程分兩步1. 持續(xù)構(gòu)建前端如果只需要前端運(yùn)行bun run build-hot如果希望在 Cypress 旁邊同時(shí)運(yùn)行一個(gè)本地 Metabase 實(shí)例最簡(jiǎn)單的方式是bun run dev或bun run dev-ee兩者底層都依賴前端熱重載。dev-ee會(huì)以 Enterprise Edition 模式啟動(dòng)后端并以MB_EDITIONee構(gòu)建前端資源見(jiàn) package.json 中dev/dev-ee腳本定義。2. 在另一個(gè)終端會(huì)話中運(yùn)行測(cè)試不要?dú)⒌羟耙粋€(gè)終端另開(kāi)一個(gè)會(huì)話運(yùn)行bun run test-cypress這會(huì)打開(kāi) Cypress GUI讓你選擇要運(yùn)行的測(cè)試。查看e2e/runner/run_cypress_local.ts和e2e/test/scenarios/docker-compose.yml可以了解所有可用的選項(xiàng)。runner 啟動(dòng)鏈路從package.json可以看到test-cypress腳本實(shí)際執(zhí)行的是tsx ./e2e/runner/run_cypress_local.ts。這個(gè) TypeScript runner 承擔(dān)了完整的初始化工作解析環(huán)境變量與命令行參數(shù)MB_EDITION、CYPRESS_TESTING_TYPE、CYPRESS_GUI、GENERATE_SNAPSHOTS、JAR_PATH啟動(dòng) Docker 容器docker compose -f ./e2e/test/scenarios/docker-compose.yml up -d根據(jù)是否提供JAR_PATH選擇從預(yù)構(gòu)建 JAR 啟動(dòng)后端或從源碼啟動(dòng)帶熱重載的后端CypressBackend.runFromSource()生成應(yīng)用數(shù)據(jù)庫(kù)快照默認(rèn)開(kāi)啟GENERATE_SNAPSHOTS會(huì)先清空e2e/support/cypress_sample_instance_data.json緩存再以無(wú) GUI 模式運(yùn)行快照生成測(cè)試檢查前端是否運(yùn)行在8080端口MB_FRONTEND_DEV_PORT若未運(yùn)行會(huì)給出警告提示最后以e2e/support/cypress.config.js作為配置啟動(dòng) Cypress。進(jìn)程退出、收到SIGTERM/SIGINT時(shí)runner 會(huì)清理后端進(jìn)程而 Docker 容器會(huì)保留在后臺(tái)可按提示用docker compose -f ./e2e/test/scenarios/docker-compose.yml down手動(dòng)停止。運(yùn)行選項(xiàng)無(wú)頭模式運(yùn)行全部測(cè)試CYPRESS_GUIfalse bun run test-cypress只運(yùn)行單個(gè)文件使用官方--spec標(biāo)志可以快速測(cè)試單個(gè)文件也支持運(yùn)行一個(gè)文件夾內(nèi)的所有 specs 或多個(gè) specCYPRESS_GUIfalse bun run test-cypress --spec e2e/test/scenarios/question/new.cy.spec.js指定瀏覽器使用--browser標(biāo)志指定執(zhí)行瀏覽器CYPRESS_GUIfalse bun run test-cypress --browser chrome指定瀏覽器在run 模式無(wú)頭執(zhí)行下最有意義而在open 模式GUI下可以方便地在系統(tǒng)所有可用瀏覽器之間切換不過(guò)也可以預(yù)先指定一個(gè)初始瀏覽器——此時(shí)它只是預(yù)選你仍然可以切換到其他瀏覽器。其他啟動(dòng)選項(xiàng)MB_EDITIONee默認(rèn)或oss控制以哪個(gè)版本啟動(dòng)后端CYPRESS_TESTING_TYPEe2e默認(rèn)或componentJAR_PATH指向預(yù)構(gòu)建的 Metabase JAR跳過(guò)源碼構(gòu)建直接對(duì) JAR 運(yùn)行測(cè)試GENERATE_SNAPSHOTS是否在測(cè)試前生成快照默認(rèn)為 true關(guān)閉時(shí)需留意快照緩存是否過(guò)期。這些選項(xiàng)都可以通過(guò)環(huán)境變量或命令行參數(shù)覆蓋見(jiàn) run_cypress_local.ts。測(cè)試文件結(jié)構(gòu)解剖Cypress 測(cè)試文件的結(jié)構(gòu)與 Mocha 一致describe塊用于分組it塊是具體的測(cè)試用例describe(homepage, () { it(should load the homepage and..., () { cy.visit(/metabase/url); // ... }); });推薦的元素選擇方式Metabase 強(qiáng)烈推薦使用testing-library/cypress提供的cy.findByText()和cy.findByLabelText()這類(lèi)選擇器該庫(kù)已在 package.json 的 devDependencies 中聲明版本為^10.1.0。這類(lèi)選擇器鼓勵(lì)寫(xiě)出不依賴實(shí)現(xiàn)細(xì)節(jié)如 CSS 類(lèi)名的測(cè)試健壯性更好。避免順帶重復(fù)測(cè)試盡量通過(guò) helper 直接跳轉(zhuǎn)到目標(biāo)功能而不是從首頁(yè)一路點(diǎn)擊過(guò)去。例如要測(cè)試查詢構(gòu)建器應(yīng)直接使用openOrdersTable()這樣的 helper 跳到 Orders 表而不是從首頁(yè)開(kāi)始依次點(diǎn)擊 New、Question 等。測(cè)試編寫(xiě)技巧與常見(jiàn)坑containsvsfindvsgetCypress 提供了一組功能相近的元素選擇命令Metabase 團(tuán)隊(duì)給出了以下使用建議contains默認(rèn)對(duì) DOM 中的文本區(qū)分大小寫(xiě)。如果匹配不到預(yù)期文本檢查 CSS 是否改變了大小寫(xiě)可以用{ matchCase: false }選項(xiàng)顯式忽略大小寫(xiě)。contains匹配的是子串。對(duì)于 filter by 和 Add a filter 兩個(gè)字符串cy.contains(filter)會(huì)同時(shí)匹配兩者。要避免這種誤匹配可以傳入固定首尾的正則表達(dá)式或?qū)⒆址薅ǖ教囟ㄟx擇器cy.contains(selector, content)。find在前一個(gè)選擇的結(jié)果范圍內(nèi)繼續(xù)搜索。get即使被鏈?zhǔn)秸{(diào)用也默認(rèn)搜索整個(gè)頁(yè)面除非顯式配置withinSubject選項(xiàng)。如何獲取 Sample Database 的表與字段 IDE2E 測(cè)試使用的 Sample Database 隨時(shí)可能變化表與字段的引用 ID 也隨之變化。永遠(yuǎn)不要硬編碼數(shù)字 ID。倉(cāng)庫(kù)提供了一套保證正確的機(jī)制每次啟動(dòng) Cypress 時(shí)runner 都會(huì)獲取 Sample Database 的信息提取表與字段 ID并寫(xiě)入e2e/support/cypress_sample_database.json隨后通過(guò) cypress_sample_database.js 重新導(dǎo)出供所有測(cè)試使用。// 不要這樣寫(xiě) const query { source-table: 1, aggregation: [[count]], breakout: [[field, 7, null]], }; // 應(yīng)該這樣寫(xiě) import { SAMPLE_DATABASE } from e2e/support/cypress_sample_database; const { PRODUCTS, PRODUCTS_ID } SAMPLE_DATABASE; const query { source-table: PRODUCTS_ID, aggregation: [[count]], breakout: [[field, PRODUCTS.CATEGORY, null]], };該 JSON 文件在每次 Cypress 啟動(dòng)時(shí)重新生成見(jiàn) default.cy.snap.js 中通過(guò)cy.writeFile(e2e/support/cypress_sample_database.json, SAMPLE_DATABASE)寫(xiě)入因此已被加入.gitignore。與之相關(guān)的還有 e2e/support/cypress_data.js它維護(hù)了SAMPLE_DB_TABLES表 ID 常量、USER_GROUPS與USERS測(cè)試賬號(hào)等常用引用。注意該文件中的 ID 是硬編碼的因此快照生成測(cè)試default.cy.snap.js中專門(mén)有ensureTableIdsAreCorrect()斷言一旦實(shí)際 ID 與期望不符就會(huì)立即失敗報(bào)警。加大視口避免滾動(dòng)Metabase 的部分視圖超過(guò) Cypress 默認(rèn)的 1280x800 視口需要滾動(dòng)才能完成測(cè)試。例如虛擬化表格不會(huì)渲染視口外的內(nèi)容。除非專門(mén)測(cè)試窗口 resize 行為否則不要在測(cè)試中途調(diào)用cy.viewport(width, height)而應(yīng)通過(guò) Cypress 測(cè)試配置設(shè)置視口寬高——該配置對(duì)describe和it塊都生效describe(foo, { viewportWidth: 1400 }, () {}); it(bar, { viewportWidth: 1600, viewportHeight: 1200 }, () {});代碼重載 vs 測(cè)試重載編輯 Cypress 測(cè)試文件時(shí)測(cè)試會(huì)自動(dòng)刷新并重新運(yùn)行但編輯代碼文件時(shí) Cypress 不會(huì)感知到變化。如果運(yùn)行的是bun run build-hot代碼會(huì)在構(gòu)建后自動(dòng)更新到 Cypress 中此時(shí)需要手動(dòng)點(diǎn)擊重新運(yùn)行才能執(zhí)行新代碼。contains helper 打開(kāi)時(shí)無(wú)法檢查 DOMCypress 支持在測(cè)試的每一步之后使用 Chrome 檢查器inspector并提供了一個(gè)輔助工具來(lái)測(cè)試contains和get調(diào)用。但該 helper 創(chuàng)建的新 UI 會(huì)妨礙檢查器定位正確元素。如果你想在 Chrome 中檢查 DOM請(qǐng)先關(guān)閉這個(gè) helper。誤將錯(cuò)誤的 HTML 模板打進(jìn) Uberjarbun run build和bun run build-hot都會(huì)覆蓋一個(gè) HTML 模板以引用正確的 JavaScript 文件。如果先運(yùn)行了bun run build再構(gòu)建用于 Cypress 測(cè)試的 Uberjar之后即使啟動(dòng)bun run build-hot也看不到 JavaScript 的變更。Apple Silicon 上的問(wèn)題在 Apple Silicon 處理器上運(yùn)行 Cypress 可能遇到問(wèn)題根因是bahmutov/cypress-esbuild-preprocessor依賴的esbuild。解決方案是使用nvm或n等 Node 版本管理器安裝 NodeJS。另一個(gè)幾乎必然會(huì)遇到的問(wèn)題是無(wú)法連接 Mongo QA 數(shù)據(jù)庫(kù)——官方支持的 Docker 鏡像是 AMD64 架構(gòu)與 Apple Silicon 不兼容??赏ㄟ^(guò)設(shè)置以下環(huán)境變量解決export EXPERIMENTAL_DOCKER_DESKTOP_FORCE_QEMU1注意即便設(shè)置了這個(gè)變量部分用戶仍會(huì)遇到 Mongo 連接超時(shí)。此時(shí)可以嘗試改用 OrbStack 代替 Docker Desktop。依賴 Docker 鏡像的測(cè)試由于托管環(huán)境中部分測(cè)試需要使用特權(quán)端口因此不能使用 podman 或 rootless Docker請(qǐng)使用經(jīng)典 Docker 或 OrbStack。Metabase 有相當(dāng)一部分測(cè)試依賴外部服務(wù)這些服務(wù)通過(guò) Docker 鏡像提供目前包括三個(gè)受支持的 QA 外部數(shù)據(jù)庫(kù)Postgres、Mongo、MySQL、Webmail、Snowplow 和 LDAP 服務(wù)器詳見(jiàn) e2e/test/scenarios/docker-compose.yml。默認(rèn)的 Cypress 命令會(huì)自動(dòng)拉起測(cè)試所需的全部 Docker 容器你也可以手動(dòng)搭建 E2E 環(huán)境但需注意會(huì)因此遇到測(cè)試失敗。該 compose 文件還展示了各服務(wù)的端口映射postgres-sample5404:5432、mongo-sample27004:27017、mysql-sample3304:3306、webhook-tester9080:8080、maildev1180:1080、1125:1025、ldap389:389并額外提供了一個(gè)啟用 SSL 的maildev-ssl服務(wù)需要向 Java keystore 添加根 CA 證書(shū)見(jiàn)maildev-keys/README.md。涉及 Snowplow 的測(cè)試依賴 Snowplow 的測(cè)試需要一個(gè)運(yùn)行中的 Snowplow 服務(wù)默認(rèn)已啟用。你也可以手動(dòng)啟動(dòng) Snowplow micro Docker 容器并設(shè)置環(huán)境變量docker-compose -f ./snowplow/docker-compose.yml up -d export MB_SNOWPLOW_AVAILABLEtrue export MB_SNOWPLOW_URLhttp://localhost:9090與 Snowplow 協(xié)同測(cè)試Metabase 提供了一組處理 Snowplow 事件的測(cè)試助手源碼見(jiàn) e2e/support/helpers/e2e-snowplow-helpers.js每個(gè)測(cè)試前使用resetSnowplow()清空已處理事件的隊(duì)列實(shí)際調(diào)用 Snowplow micro 的micro/reset接口使用expectSnowplowEvent({ ...payload }, countn)斷言恰好有count個(gè) Snowplow 事件部分匹配給定 payloadcount默認(rèn)為 1使用expectUnstructuredSnowplowEvent斷言恰好有count個(gè)非結(jié)構(gòu)化unstructured事件部分匹配給定 payload。這是event.unstruct_event.data.data與整個(gè)event比較的便捷封裝——Metabase 的絕大多數(shù)事件都是非結(jié)構(gòu)化事件使用assertNoUnstructuredSnowplowEvent({ ...eventData })即expectUnstructuredSnowplowEvent(eventData, 0)斷言沒(méi)有非結(jié)構(gòu)化事件匹配該 payload每個(gè)測(cè)試后使用expectNoBadSnowplowEvents()斷言沒(méi)有發(fā)送非法事件。從實(shí)現(xiàn)看expectSnowplowEvent會(huì)輪詢 Snowplow micro 的micro/good接口間隔 100ms、超時(shí) 1000ms并做深度部分匹配倉(cāng)庫(kù)中大量測(cè)試文件如 search-snowplow.cy.spec.js、instance-stats-snowplow.cy.spec.js都在使用這套助手。需要 SMTP 服務(wù)器的測(cè)試部分測(cè)試依賴郵件功能需要本地 SMTP 服務(wù)器。Metabase 使用maildevDocker 鏡像當(dāng)前使用的鏡像為maildev/maildev:2.2.1與e2e/test/scenarios/docker-compose.yml中的版本一致。默認(rèn)的本地開(kāi)發(fā) Cypress 配置會(huì)自動(dòng)處理手動(dòng)搭建可使用docker run -d -p 1180:1080 -p 1125:1025 maildev/maildev:2.2.1E2E 使用的 maildev 刻意發(fā)布在宿主端口 1180Web UI和 1125SMTP上與開(kāi)發(fā)環(huán)境使用的 1080/1025 故意不同。需要翻譯字典的測(cè)試與偽語(yǔ)言環(huán)境翻譯字典部分測(cè)試會(huì)檢查內(nèi)容翻譯content translation功能運(yùn)行這些測(cè)試前需要先執(zhí)行以下命令預(yù)編譯帶翻譯的 JSON 文件./bin/i18n/build-translation-resources偽語(yǔ)言環(huán)境en_ZZMetabase 提供了一個(gè)偽語(yǔ)言環(huán)境en_ZZ它會(huì)給所有翻譯字符串加上[zz]前綴例如My text會(huì)變成[zz] My text。這在編寫(xiě)斷言翻譯工作正常的 E2E 測(cè)試時(shí)非常方便且不依賴可能隨時(shí)間變化的真實(shí)翻譯文本。偽語(yǔ)言環(huán)境的 PO 文件在構(gòu)建時(shí)生成要在 UI 中使用它需以MB_ENABLE_TEST_LOCALEStrue啟動(dòng)后端然后在 Admin Settings Localization 中選擇 English (ZZ)。善用 Cypress 內(nèi)置的 LodashCypress 自帶 Lodash無(wú)需將其加入直接依賴。它以下劃線別名暴露方法可通過(guò)Cypress._.method()調(diào)用??梢杂胈.times在本地對(duì)某個(gè)測(cè)試或一組測(cè)試進(jìn)行壓力測(cè)試// 將測(cè)試運(yùn)行 N 次 Cypress._.times(N, () { it(should foo, () { // ... }); });DB 快照機(jī)制每個(gè)測(cè)試套件開(kāi)始時(shí)Metabase 會(huì)清空后端的數(shù)據(jù)庫(kù)與設(shè)置緩存確保測(cè)試套件從可預(yù)測(cè)的狀態(tài)開(kāi)始。通常在第一個(gè)describe塊內(nèi)添加before(restore)即可在運(yùn)行整個(gè)測(cè)試套件前恢復(fù)默認(rèn)快照。如果要使用默認(rèn)快照之外的快照將名稱作為參數(shù)傳給restorebefore(() restore(blank));也可以在beforeEach()內(nèi)調(diào)用restore()以在每個(gè)測(cè)試前重置或在特定測(cè)試內(nèi)調(diào)用。restore與snapshot的底層實(shí)現(xiàn)見(jiàn) e2e-setup-helpers.jssnapshot(name)調(diào)用POST /api/testing/snapshot/{name}restore(name default)調(diào)用POST /api/testing/restore/{name}且對(duì)-writable后綴的快照會(huì)自動(dòng)重置可寫(xiě)數(shù)據(jù)庫(kù)postgres/mysql并先調(diào)用/api/testing/reset-throttlers重置限流器。當(dāng)前支持的快照名包括blank、setup、without-models、default、mongo-5、postgres-12、postgres-writable、mysql-8、mysql-writable??煺帐侨绾蝿?chuàng)建的快照由一組獨(dú)立的 Cypress 測(cè)試創(chuàng)建。這些測(cè)試從空白數(shù)據(jù)庫(kù)開(kāi)始通過(guò)執(zhí)行具體操作將數(shù)據(jù)庫(kù)置于可預(yù)測(cè)狀態(tài)。例如以 bobmetabase.com 注冊(cè)、添加一個(gè)問(wèn)題、打開(kāi)設(shè)置 ABC 等。這些生成快照的測(cè)試擴(kuò)展名為.cy.snap.js。運(yùn)行時(shí)會(huì)生成數(shù)據(jù)庫(kù) dump 到frontend/tests/snapshots/*.sql。它們?cè)跍y(cè)試開(kāi)始前運(yùn)行且不會(huì)提交到 git。以 default.cy.snap.js 為例它依次生成blank快照 → 執(zhí)行 setup通過(guò)/api/setup接口完成站點(diǎn)初始化并緩存 admin 憑據(jù)→ 更新一系列設(shè)置如synchronous-batch-updates、enable-public-sharing、enable-embedding-sdk、embedding-secret-key等→ 生成setup快照 → 創(chuàng)建用戶與權(quán)限組、配置權(quán)限圖 → 創(chuàng)建集合與問(wèn)題/儀表板 → 生成without-models快照 → 創(chuàng)建模型 → 生成default快照最后恢復(fù)blank快照。其中還包含對(duì)表 ID 正確性的斷言以及將 Sample Database 元數(shù)據(jù)寫(xiě)入e2e/support/cypress_sample_database.json的邏輯。在 CI 中運(yùn)行Cypress 會(huì)記錄每次測(cè)試運(yùn)行的視頻便于調(diào)試此外失敗的測(cè)試會(huì)保存更高質(zhì)量的截圖。這些文件可以在 GitHub Actions 中每次運(yùn)行的 Artifacts 部分找到。針對(duì) Enterprise Edition 運(yùn)行在針對(duì) Metabase Enterprise Edition 運(yùn)行 Cypress 之前需要設(shè)置環(huán)境變量MB_EDITIONee。注意Enterprise 實(shí)例會(huì)在沒(méi)有 premium token 的情況下啟動(dòng)如果想測(cè)試 premium 功能feature flags需要為所有 Cypress 測(cè)試提供有效 token。需要提供 4 個(gè) tokenMB_ALL_FEATURES_TOKEN啟用所有功能包括尚未向客戶發(fā)布的新功能MB_STARTER_CLOUD_TOKEN僅啟用 hosting 功能模擬云上的 Starter 計(jì)劃MB_PRO_CLOUD_TOKEN啟用 PRO 功能并加上 hosting模擬云上的 Pro 計(jì)劃MB_PRO_SELF_HOSTED_TOKEN啟用 PRO 功能但不含 hosting模擬 Pro 自托管計(jì)劃??梢酝ㄟ^(guò)環(huán)境變量或cypress.env.json文件配置參考倉(cāng)庫(kù)中的cypress.env.json.example示例。runner 在MB_EDITIONee且缺少這些 token 時(shí)會(huì)給出警告見(jiàn) run_cypress_local.ts。幾個(gè)注意點(diǎn)如果測(cè)試開(kāi)始運(yùn)行但缺少 enterprise 功能請(qǐng)確認(rèn)所用 token 已啟用相應(yīng)的 feature flags導(dǎo)航到/admin/settings/license頁(yè)面時(shí)license 輸入框會(huì)顯示當(dāng)前生效的 token分享截圖時(shí)要小心泄露如果 token 看起來(lái)沒(méi)問(wèn)題但仍然異??梢院藦椉?jí)處理運(yùn)行killall java終止所有 Java 進(jìn)程后重啟 Cypress。測(cè)試報(bào)告每個(gè) spec 會(huì)自動(dòng)生成獨(dú)立的 Mocha 報(bào)告存放在cypress/reports/mochareports。注意根級(jí)別的cypress/目錄已被 git 忽略在 CI 中運(yùn)行時(shí)Metabase 會(huì)做額外處理使用mochawesome-merge合并各報(bào)告、格式化并生成定制化的 GitHub Actions job summary。如果在本地也需要統(tǒng)一的測(cè)試報(bào)告可以調(diào)用bun run generate-cypress-html-report該腳本在 package.json 中定義為mochawesome-merge cypress/reports/mochareports/*.json cypress/reports/cypress-test-report.json marge cypress/reports/cypress-test-report.json -o cypress/reports --inline。測(cè)試標(biāo)簽TagsCypress 允許為測(cè)試打標(biāo)簽便于快速篩選某一類(lèi)測(cè)試。例如可以給所有需要外部數(shù)據(jù)庫(kù)的測(cè)試打上external標(biāo)簽然后只運(yùn)行這些測(cè)試bun run test-cypress --env grepTagsexternal標(biāo)簽應(yīng)以開(kāi)頭以便在搜索時(shí)與其他字符串區(qū)分。當(dāng)前倉(cāng)庫(kù)使用的標(biāo)簽有external— 需要外部 Docker 容器才能運(yùn)行的測(cè)試actions— 使用 Metabase actions 并在數(shù)據(jù)源中修改數(shù)據(jù)的測(cè)試。如何對(duì) flaky 修復(fù)進(jìn)行壓力測(cè)試在本地修復(fù)一個(gè) flaky不穩(wěn)定測(cè)試并不代表該修復(fù)在 GitHub 的 CI 環(huán)境中有效。確保修復(fù)有效的唯一方式是在 CI 中做壓力測(cè)試。這正是.github/workflows/e2e-stress-test-flake-fix.yml工作流存在的目的——它允許你在分支上快速測(cè)試修復(fù)而無(wú)需等待完整構(gòu)建完成。準(zhǔn)備創(chuàng)建包含修復(fù)方案的新分支并推送到遠(yuǎn)端要么完全跳過(guò) PR要么打開(kāi)一個(gè)draft草稿PR。手動(dòng)觸發(fā)壓力測(cè)試工作流在 Use workflow from 第一個(gè)字段中選擇你自己的分支這一步至關(guān)重要復(fù)制粘貼要測(cè)試的 spec 的相對(duì)路徑例如e2e/test/scenarios/onboarding/urls.cy.spec.js無(wú)需加引號(hào)設(shè)置期望運(yùn)行的測(cè)試次數(shù)可選按文檔提供 grep 過(guò)濾條件點(diǎn)擊綠色 Run workflow 按鈕等待結(jié)果。使用該工作流的注意事項(xiàng)它會(huì)自動(dòng)嘗試查找并下載之前構(gòu)建好的 Metabase uberjar以 artifact 形式存儲(chǔ)在過(guò)去的某個(gè) commit/CI run 中它只適用于純 E2E 修復(fù)——不需要新的 Metabase uberjar如果修復(fù)涉及源碼改動(dòng)前端或后端請(qǐng)先開(kāi)普通 PR 讓 CI 跑完所有測(cè)試之后可以按上述說(shuō)明手動(dòng)觸發(fā)壓力測(cè)試工作流它會(huì)自動(dòng)下載這次 CI 運(yùn)行新構(gòu)建的 artifact。注意 CI 必須完全跑完因?yàn)楣ぷ髁魍ㄟ^(guò) GitHub REST API 獲取 artifact否則看不到。小結(jié)Metabase 的 E2E 測(cè)試體系是一套高度工程化的完整方案e2e/runner負(fù)責(zé)后端構(gòu)建、Docker 容器、快照生成與 Cypress 啟動(dòng)的全流程編排e2e/support提供數(shù)據(jù)引用、命令助手、Snowplow/SMTP/翻譯等特殊場(chǎng)景支持e2e/test/scenarios以鏡像 URL 結(jié)構(gòu)的目錄組織數(shù)百個(gè)場(chǎng)景測(cè)試快照機(jī)制保證了測(cè)試的確定性與可預(yù)測(cè)性。本文覆蓋了從本地開(kāi)發(fā)、運(yùn)行選項(xiàng)、測(cè)試編寫(xiě)規(guī)范到 CI、Enterprise 支持、flaky 修復(fù)的完整路徑。掌握這套體系后你既可以快速跑通并定位失敗測(cè)試也能為 Metabase 的前端功能貢獻(xiàn)高質(zhì)量的端到端測(cè)試。深入研讀 e2e-tests.md、run_cypress_local.ts、cypress_data.js 與 default.cy.snap.js 等文件將幫助你進(jìn)一步理解其設(shè)計(jì)精髓?!久赓M(fèi)下載鏈接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:項(xiàng)目地址: https://gitcode.com/GitHub_Trending/me/metabase創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考