iT邦幫忙

2026 iThome 鐵人賽

DAY 25
1
Software Development

從脆弱腳本到可信任測試平台:自動化測試架構30天系列 第 25

Day 25|測試失敗後,報告要提供什麼資訊?打造高品質的排查報告

  • 分享至 

  • xImage
  •  

「一份好的測試失敗報告,就像是鑑識現場的黑色盒子——它能讓工程師在不用重新本地重現(Local Replay)的情況下,3 分鐘內精準鎖定產品 Bug 還是環境問題。」

大家好,我是 Jane,一個每天在第一線處理跨平台(Web & App)自動化測試、跟 CI/CD Pipeline 失敗報告與 Issue 排查奮戰的自動化測試工程師(SDET)。

在上集 Day 23 與 Day 24 中,我們成功將測試改造成極速且抗併發衝突的平行測試體系。

但當自動化測試在 CI/CD 上高速運行、並在某個深夜跳出紅燈時,SDET 與開發團隊面臨的下一個考驗就是:

  • 「報告只印出 AssertionError: assert False,畫面截圖沒有、API Request/Response 沒抓、DOM State 也看不到……這到底要怎麼排查?」

如果每次 CI 測試失敗,工程師都必須親自把 Code checkout 到 Local 電腦、建環境、重跑一次腳本才能知道壞在哪裡,自動化測試帶來的效率就會大打折扣。

今天這篇文章,我們就來好好拆解:一份『可落地排查』的高品質測試失敗報告,至少要提供哪 9 大關鍵資訊?以及如何在 Python / pytest 中自動打包這些現場證據!

一、 第一線 SDET 的診斷現場:失敗報告的 9 大必備元素

                    ┌─────────────────────────┐
                    │  失敗報告 9 大診斷要素   │
                    └────────────┬────────────┘
                                 │
     ┌───────────────────────────┼───────────────────────────┐
     ▼                           ▼                           ▼
【視覺與軌跡現場】            【網路與系統狀態】          【環境與脈絡資訊】
1. 失敗當下的螢幕截圖        4. HTTP Request / Response 7. 測試案例名稱與 Intent
2. 操作錄影 (Video)         5. 前端/App Console Log    8. 執行環境 (Env / OS)
3. DOM 樹 snapshot / Trace  6. 後端 Trace ID / DB Log  9. 帶入的測試資料 (Data)

1. 視覺與操作現場 (Visual Context)

  • 最後畫面的螢幕截圖 (Screenshot):一眼看出是跳出錯的 Toast、按鈕被遮蔽、還是畫面整個白屏 (Blank Page)。
  • 測試過程錄影 (Video):觀察失敗前 5 秒的 UI 動畫或跳轉軌跡,捕捉瞬間消失的 Error Message。
  • Playwright Trace (ZIP 檔):包含完整 DOM 樹狀態、滑鼠軌跡與時間軸,可在 Local 隨意穿梭失敗現場。

2. 網路與系統 Log 現場 (System Logs)

  • 完整 HTTP 網路請求紀錄 (Network Logs):包含失敗當下的 API URL、Status Code、Request Payload 與 Response Body。這是判斷「前端 UI 壞掉還是後端 API 噴 500」最關鍵的依據。
  • 前端 Console Log / App Logcat:捕捉 Javascript Uncaught Exception 或 App 崩潰 StackTrace。
  • 後端 Trace ID (Correlation ID):將測試帶入的 X-Trace-ID 附在報告上,方便後端工程師直接去 Datadog / Kibana 抓對應的後端 Log。

3. 環境與測試脈絡 (Context Metadata)

  • 測試意圖(Docstring / Intent):這條案例到底在驗什麼?
  • 測試資料(Test Data Used):當下帶入的動態帳號、UUID 或商品 ID。
  • 環境變數 (Build & Env Info):哪個 Git Commit Hash、哪台 CI Runner、哪個 Staging 環境。

二、 Python / pytest 實戰:自動化打包失敗證據鏈

我們利用 pytest 的 Hook 機制與 Playwright,打造自動在報告中附加「截圖、Trace 與 API Log」的通用 conftest.py

Python

# tests/conftest.py
import os
import pytest
from playwright.sync_api import Page

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    """
    pytest 鉤子函式:在測試案例執行完畢後,自動攔截失敗狀態並附加證據
    """
    outcome = yield
    report = outcome.get_result()

    # 僅針對測試執行階段 (call) 且結果為失敗 (failed) 的案例進行處置
    if report.when == "call" and report.failed:
        # 1. 獲取案例的 Playwright page 物件
        page: Page = item.funcargs.get("page")

        if page:
            # 建立報告專屬目錄
            os.makedirs("reports/artifacts", exist_ok=True)
            test_name = item.name.replace("/", "_")

            # A. 自動抓取當下螢幕截圖
            screenshot_path = f"reports/artifacts/{test_name}.png"
            page.screenshot(path=screenshot_path, full_page=True)

            # B. 自動匯出 Playwright Trace (包含 DOM 樹與 Network 軌跡)
            trace_path = f"reports/artifacts/{test_name}_trace.zip"
            page.context.tracing.stop(path=trace_path)

            # C. 將截圖與 Trace 連結注入至 HTML Report 中 (搭配 pytest-html)
            if hasattr(report, "extra"):
                import pytest_html
                report.extra.append(pytest_html.extras.image(screenshot_path))
                report.extra.append(pytest_html.extras.url(trace_path, name="下載 Playwright Trace 檔案"))

        # 2. 獲取案例 Docstring 並作為「測試意圖」附加至報告
        test_doc = item.function.__doc__ or "無文字說明"
        print(f"\n[Failure Diagnostics] 案例: {item.name}")
        print(f"[Test Intent]: {test_doc.strip()}")

conftest.py 中全域開啟 Trace 監聽

為了讓失敗當下能順利匯出 trace.zip,我們需在 Browser Context 階段開啟Tracing:

Python

# tests/conftest.py (續)
@pytest.fixture(scope="function", autouse=True)
def auto_tracing(page: Page):
    """
    自動為每個 Web UI 案例開啟 Playwright 軌跡錄製
    """
    # 開啟追蹤:包含 Screenshots, DOM Snapshots, Network
    page.context.tracing.start(screenshots=True, snapshots=True, sources=True)
    yield
    # 如果案例成功過關,直接關閉不存檔,節省 CI 磁碟空間
    try:
        page.context.tracing.stop()
    except Exception:
        pass

三、 第一線 SDET 的失敗排查 SOP

擁有了這份高資訊量的測試報告後,第一線 SDET 排查 CI 失敗的標準順序為:

┌─────────────────────────────────────────────────────────────┐
│                 SDET 3 分鐘排查 S.O.P.                       │
├─────────────────────────────────────────────────────────────┤
│ Step 1. 看截圖/影片  ──▶ 判斷是 UI 跑版/跳 Toast 還是頁面空白 │
│ Step 2. 看 Network   ──▶ 檢查背景 API 是否噴 40x / 500 錯誤  │
│ Step 3. 看 Trace/Log ──▶ 確認是否為 Locator 超時或元件未顯現  │
└─────────────────────────────────────────────────────────────┘
  1. Step 1:看截圖(5 秒鐘)
    如果截圖顯示「502 Bad Gateway」,直接判定為測試環境 (Infra) 崩潰,不用查 Code;如果顯示「按鈕變成灰色停用狀態」,進入 Step 2。
  2. Step 2:看 Network Request/Response(30 秒鐘)
    檢查按鈕變灰色的原因:發現前一個 /api/v1/user/status 回傳了 500 Internal Error。複製報告中的 X-Trace-ID: trace_abc123,直接轉貼給後端工程師。
  3. Step 3:載入 Playwright Trace(1 分鐘)
    如果是前端 UI 沒反應,將報告附帶的 trace.zip 拖入 trace.playwright.dev,精準查看 DOM 樹在第 3.2 秒時的元素狀態,確認是否為前端 DOM 改版造成。

結語與第五部分總結

恭喜你!到今天 Day 25 為止,我們完成了整個系列的《第五部分:讓測試真正進入 CI/CD》!

我們解決了:

  • Day 21:CI/CD 測試管道的 5 大分層配置
  • Day 22:Pytest Markers 與 Git Diff 變更影響分析 (TIA)
  • Day 23:pytest-xdist 平行執行與極速優化
  • Day 24:平行測試的 Race Condition 與共享資源解鎖
  • Day 25:包含 9 大診斷要素的高品質失敗報告

從明天開始,我們將邁入整條自動化測試旅程的最精華、也最考驗資深價值的最終篇章:
《第六部分:資深測試工程師真正需要處理的問題》

明天 Day 26,我們將一起來探討第一線 SDET 每天被問到的經典難題:
《 Day 26|如何判斷失敗是產品 bug 還是測試 bug?排查順序與邏輯 》


上一篇
Day 24|平行測試為什麼一開就全部壞掉?共享資源與 Race Condition 解決指南
系列文
從脆弱腳本到可信任測試平台:自動化測試架構30天25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言