QA 該懂的 CI/CD 基礎 — Pipeline 階段、Quality Gate、QA 的位置
「CI 跑紅了,誰處理?」這句話如果你聽不懂,這篇就是給你的。QA 不會寫 pipeline,但要會讀、會喊停、會幫忙修,才能真的把品質守住。
為什麼 QA 要懂 CI/CD
| 情境 | 不懂的話 | 懂的話 |
|---|---|---|
| 開發說「CI 過了」 | 你相信 → 上線爆炸 | 你會去看哪些 stage 被跳過 |
| 自動化 fail 找上你 | 你只能說「測試壞了」 | 你能說「step 3 fail 因為 env 變數沒注入」 |
| 你要加新測試 | 等開發幫你接 | 自己寫 yml PR |
| Bug 上 prod | 「為什麼測試沒抓到」回答不出 | 能指出 coverage gap + 補強建議 |
懂 CI/CD ≠ 變 DevOps,最低標:能看懂 yml、能讀 log、能加 step。
CI vs CD vs CD
- CI(Continuous Integration):合 code 時自動跑 build + test
- CD(Continuous Delivery):自動 build artifact,人工按鈕 deploy
- CD(Continuous Deployment):完全自動 deploy 到 prod,沒人工
多數公司是 CI + Delivery。Deployment 要等品質非常成熟才敢全自動。
Pipeline 七階段(QA 視角)
[1 Lint] → [2 Unit] → [3 Build] → [4 Integration] → [5 E2E] → [6 Deploy] → [7 Smoke]
1. Lint / Static Analysis(< 1 min)
跑:ESLint、Pylint、Ruff、TypeScript check。抓語法、格式、明顯 bug。
QA 關注:不關注。但 lint fail 表示開發習慣不好,間接影響品質。
2. Unit Test(1-5 min)
跑:Jest、pytest、Go test。測單一函式、純邏輯。
QA 關注:
- Coverage % 是多少?目標 ≥ 70-80%
- 哪些檔案 coverage 低?通常是 high-risk 區域
- 有沒有 skip 掉的測試?(it.skip、@pytest.mark.skip)
3. Build(2-10 min)
跑:webpack、vite、Docker build。打包 artifact。
QA 關注:build 出來的 artifact 要被後面 stage 用。不要讓開發 build 一次、QA 再 build 一次,會有版本不一致。
4. Integration Test(5-15 min)
跑:測試多元件互動,常常需要 DB / Redis / mock 服務。
QA 關注: - DB schema 是否每次 reset?(避免 test data 殘留) - 第三方依賴怎麼 mock?(不要打 prod API) - 哪些 service 是 docker compose 起來的?
5. E2E Test(10-60 min)
跑:Playwright、Cypress。最像真實使用者。
QA 關注: - 跑哪些瀏覽器?只 Chromium?要不要加 Firefox / WebKit - 平行幾條?太少跑很久、太多 flaky - Failure artifact 有沒有存?(screenshot、video、trace)
6. Deploy(1-10 min)
CD 到 staging / preview / prod。
QA 關注: - Deploy 是 atomic 嗎?(一次成功 or 一次回滾) - Rollback 多久?(< 1 min 才安全) - 有沒有 canary?10% 流量先看
7. Smoke Test(1-5 min)
Deploy 後跑:登入、首頁、購買流程「能不能用」。
QA 關注: - Smoke 失敗會自動 rollback 嗎? - Smoke 是真的打 prod 還是 staging?
Quality Gate(你 QA 最關心的)
Quality gate = pipeline 在某個 stage 強制檢查,不過就擋下。
常見 quality gate 設定
# 範例
quality_gate:
- unit_test_pass_rate: 100% # 一個 fail 就擋
- unit_coverage: >= 80%
- e2e_pass_rate: >= 95% # 容忍 5% flaky
- lint_warnings: 0
- security_scan_critical: 0
- bundle_size: <= 500KB
- lighthouse_performance: >= 80
我的建議(依嚴格度)
| Gate | P0 必設 | P1 建議 | P2 加分 |
|---|---|---|---|
| Unit pass rate | 100% | - | - |
| Lint | 0 errors | 0 warnings | - |
| Critical security | 0 | - | - |
| Unit coverage | ≥ 60% | ≥ 80% | ≥ 90% |
| E2E pass rate | ≥ 90% | ≥ 95% | 100% |
| Bundle size | - | 設上限 | regression alarm |
| Performance | - | LCP < 3s | Core Web Vitals |
新 repo 先嚴後鬆:一開始嚴格,慢慢 tune。舊 repo 先鬆後嚴:先把現狀 lock 住,再逐步提高。
QA 在 CI/CD 真正該做的 5 件事
1. 看懂 yml
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm test
- run: npx playwright install --with-deps
- run: npx playwright test
懂這個 = 你能加 step、能 debug。
2. 失敗時看 log + artifact
- CI 紅了 → 第一步看哪個 step fail
- 看完 log 看 artifact:screenshot、video、trace、JUnit XML
- 不要直接喊「重跑看看」,先看是不是真 bug
3. 加自己的測試到 pipeline
- name: API smoke test
run: pytest tests/smoke/test_api.py -v
QA 自己加,不靠 dev。
4. 設 quality gate
去跟 dev / DevOps 談:要不要把 E2E pass rate < 95% 設成擋 merge?
5. 觀察 pipeline 時長 + 穩定度
- 每週看 CI 平均時長 → 太久要砍 / 平行化
- 每週看 flaky rate → 高的話排修 sprint
常見坑
- Pipeline 越加越慢 — 從 5 分鐘變 40 分鐘 → 開發不想等 → 開始 skip CI → 防線崩潰 - 解法:拆 stage,只有 main 跑 full E2E,PR 跑 smoke
- 環境變數沒注入 — CI 跑 fail,本機跑 pass → secrets 沒設
- 快取沒設好 — 每次重裝 deps 浪費 5 分鐘 →
actions/cache - Flaky test 沒人修 — Pass rate 從 99% 掉到 85% → 信心崩盤
- 同個 job 太多 step — Fail 看不出哪個 → 拆 step
- 跨 PR 共用 DB — Test data 互相污染 → 每次 spin up 新 DB
進階:CI/CD 工具地圖
| 工具 | 用途 | 何時用 |
|---|---|---|
| GitHub Actions | CI/CD | GitHub 上首選、yml 簡單 |
| GitLab CI | CI/CD | GitLab、可自架 runner |
| Jenkins | CI/CD | 老牌、彈性最高、UI 不友善 |
| CircleCI | CI/CD | 需要平行 / 大規模 |
| Argo CD / Flux | GitOps deploy | Kubernetes |
| Codecov / Coveralls | Coverage 報告 | 補 GitHub Actions 看 coverage |
| Allure / ReportPortal | 測試報告 | 集中看多 job 結果 |
| Sentry / Datadog | 上線後監控 | 不是 CI 但跟 smoke 連 |
下一步
- 看一份你公司 repo 的 CI yml,把每個 step 解釋給自己聽
- 加一個你自己的 test step 進去
- 下次 CI fail,自己 debug 完再喊人
懂 CI/CD 之後,你會發現「QA 的工作」會從「測完跟你說」變成「自動化抓不到的,我幫你看」— 角色升級。