kevintsengtw

dotnet-testing-code-coverage-analysis

8
1
# Install this skill:
npx skills add kevintsengtw/dotnet-testing-agent-skills --skill "dotnet-testing-code-coverage-analysis"

Install specific skill from multi-skill repository

# Description

|

# SKILL.md


name: dotnet-testing-code-coverage-analysis
description: |
程式碼覆蓋率分析完整指南。
涵蓋 Coverlet 設定、報告產生、指標解讀與循環複雜度整合。
包含 Fine Code Coverage、VS Code 內建工具、CI/CD 整合與最佳實踐。

triggers:
# 核心關鍵字
- code coverage
- 程式碼覆蓋率
- 覆蓋率分析
- coverage report

# 工具名稱
- Coverlet
- Fine Code Coverage
- dotnet-coverage
- ReportGenerator
- xunit code coverage

# 技術術語
- line coverage
- branch coverage
- method coverage
- 行覆蓋率
- 分支覆蓋率
- cyclomatic complexity
- 循環複雜度

# 使用情境
- runsettings
- coverage threshold
- 覆蓋率閾值
- 測試盲點
- CI/CD coverage
- cobertura
- opencover

license: MIT
metadata:
author: Kevin Tseng
version: "1.0.0"
tags: "code-coverage, coverlet, testing-metrics, quality, ci-cd, analysis"


程式碼覆蓋率分析指南

適用情境

當被要求執行以下任務時,請使用此技能:

  • 設定與執行程式碼覆蓋率分析
  • 配置 Coverlet 或其他覆蓋率工具
  • 產生與解讀覆蓋率報告
  • 在 Visual Studio 或 VS Code 中檢視覆蓋率
  • 評估測試完整性與品質
  • 結合複雜度指標制定測試策略

Code Coverage 核心概念

定義

程式碼覆蓋率 (Code Coverage) 是一種測量指標,用來統計測試執行時實際執行了多少程式碼。

正確認知

Code Coverage 的實際價值:

  1. 找出測試盲點:快速識別沒有被測試的程式碼
  2. 評估測試完整性:檢查重要邏輯是否都有測試
  3. 輔助重構決策:了解哪些區域需要更多關注
  4. 增加測試信心:確認關鍵路徑都有被驗證

常見誤解(必須避免)

錯誤認知:

  • 涵蓋率 100% 就沒有 Bug
  • 涵蓋率數字越高越好
  • 可以用涵蓋率當作 KPI

正確認知:

  • Code Coverage 只是提醒工具,告訴你哪些程式碼沒被測試
  • 重點是測試的有效性,不是覆蓋率數字
  • 幫助判斷是否需要補充測試案例
  • 絕對不應該當作 KPI 使用

⚠️ 警告:當 Code Coverage 被當作 KPI 時,開發者會為了衝數字而寫沒有 Assert 的測試,完全失去了測試的意義。

.NET 專案的覆蓋率工具選擇

1. Visual Studio Enterprise(僅限企業版)

優點:

  • 內建整合,無需額外設定
  • 完整的 UI 支援
  • 即時結果顯示

限制:

  • 只有 Enterprise 版本才有此功能
  • Professional 和 Community 版本不支援

2. Fine Code Coverage(推薦免費方案)

優點:

  • 完全免費
  • 整合在 Visual Studio 中
  • 即時顯示覆蓋率
  • 程式碼編輯器直接標示

安裝方式:

  1. 開啟 Visual Studio
  2. 延伸模組 → 管理延伸模組
  3. 搜尋 "Fine Code Coverage"
  4. 安裝後重新啟動

必要設定:

  • 工具 → 選項 → Fine Code Coverage
  • Run (Common) → Enable:設為 True
  • Editor Colouring Line Highlighting:設為 True

3. .NET CLI 工具

使用場景:

  • CI/CD 流程整合
  • 命令列自動化
  • 跨平台開發

安裝與使用:

# 安裝工具
dotnet tool install -g dotnet-coverage

# 執行測試並產生報告
dotnet-coverage collect dotnet test

# 或使用 Coverlet(推薦)
dotnet test --collect:"XPlat Code Coverage"

4. VS Code 內建測試覆蓋率

優點:

  • 跨平台支援
  • 內建功能,無需安裝擴充套件
  • 整合式測試管理

使用方式:

  1. 安裝 C# Dev Kit 擴充套件
  2. 開啟測試總管(燒杯圖示)
  3. 點選「執行涵蓋範圍測試」
  4. 查看結果:測試涵蓋範圍視圖、編輯器內顯示、檔案總管顯示

執行覆蓋率分析

方法一:使用 .NET CLI(推薦用於 CI/CD)

# 執行測試並收集覆蓋率
dotnet test --collect:"XPlat Code Coverage"

# 指定輸出格式
dotnet test --collect:"XPlat Code Coverage" --results-directory ./coverage

# 產生多種格式報告
dotnet test /p:CollectCoverage=true /p:CoverageReportFormat="cobertura;opencover;json"

方法二:使用 Fine Code Coverage

  1. 在 Visual Studio 中執行測試
  2. 檢視 → 其他視窗 → Fine Code Coverage
  3. 自動顯示覆蓋率報告

方法三:使用 VS Code

  1. 開啟測試總管
  2. 點選「執行涵蓋範圍測試」圖示
  3. 查看覆蓋率結果:
  4. 測試涵蓋範圍視圖:樹狀結構
  5. 編輯器內顯示:綠色/紅色標示
  6. 檔案總管:百分比顯示

設定 Coverlet

在 csproj 中配置

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <!-- 測試框架套件 -->
    <PackageReference Include="xunit" Version="2.9.3" />
    <PackageReference Include="xunit.runner.visualstudio" Version="3.0.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />

    <!-- 覆蓋率收集器 -->
    <PackageReference Include="coverlet.collector" Version="6.0.3">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

</Project>

使用 runsettings 檔案

請參考 templates/runsettings-template.xml 檔案,用於更進階的覆蓋率設定:

  • 排除特定檔案或命名空間
  • 設定覆蓋率閾值
  • 自訂報告格式

使用方式:

dotnet test --settings coverage.runsettings

解讀覆蓋率報告

顏色標示說明

在程式碼編輯器中:

  • 綠色:已被測試覆蓋
  • 黃色:部分覆蓋(部分分支未測試)
  • 紅色:未被覆蓋

覆蓋率指標

  1. Line Coverage(行覆蓋率)
  2. 被執行的程式碼行數 / 總程式碼行數
  3. 最基本的指標

  4. Branch Coverage(分支覆蓋率)

  5. 被執行的分支數 / 總分支數
  6. 比行覆蓋率更準確
  7. 確保 if/else、switch 等所有分支都被測試

  8. Method Coverage(方法覆蓋率)

  9. 被執行的方法數 / 總方法數

報告解讀策略

  1. 優先處理紅色區域
  2. 完全沒被測試的程式碼
  3. 可能是關鍵業務邏輯

  4. 檢查黃色區域

  5. 確認所有條件分支都有測試
  6. 特別注意 if/else、try/catch 等

  7. 評估必要性

  8. 簡單的 getter/setter 可能不需要測試
  9. 自動產生的程式碼可以排除
  10. 專注於業務邏輯與複雜運算

結合複雜度指標

循環複雜度(Cyclomatic Complexity)

定義:
程式中獨立邏輯路徑的數量

與測試案例的關係:

  • 循環複雜度 = 至少需要的測試案例數量
  • 每個 if、for、while、case、&&、|| 都會增加複雜度

範例:

public int Max(int[] array)
{
    if (array == null || array.Length == 0)  // +2 (null 判斷 + 長度判斷)
    {
        throw new ArgumentException("array must not be empty.");
    }

    int max = array[0];

    for (int i = 1; i < array.Length; i++)  // +1 (迴圈)
    {
        if (array[i] > max)  // +1 (條件判斷)
        {
            max = array[i];
        }
    }

    return max;  // +1 (方法本身)
}
// 總複雜度 = 5

測試策略:

循環複雜度為 5,至少需要 5 個測試案例:

  1. 傳入 null → 測試 array == null
  2. 傳入空陣列 → 測試 array.Length == 0
  3. 單一元素 → 不進入迴圈
  4. 最大值在開頭 → 迴圈不更新 max
  5. 最大值在中間 → 迴圈更新 max

Visual Studio 擴充套件

CodeMaintainability:

  • 顯示可維護性指標
  • 計算循環複雜度
  • 評估程式碼品質

CodeMaid:

  • Spade 功能:視覺化程式碼結構
  • 顯示每個方法的複雜度
  • 幫助識別需要重構的程式碼

改善覆蓋率的策略

1. 漸進式改善

目前覆蓋率 → 識別關鍵模組 → 補充測試 → 提升至目標值 → 持續監控

建議流程:

  1. 第一階段:覆蓋核心業務邏輯(目標 60-70%)
  2. 第二階段:補充邊界條件測試(目標 70-80%)
  3. 第三階段:處理異常情境(目標 80-85%)
  4. 維持階段:新增功能必須有測試

2. 優先順序排序

高優先級(必須測試):

  • 業務邏輯核心
  • 金融計算
  • 資料驗證
  • 權限控制
  • 異常處理

中優先級(建議測試):

  • 資料轉換
  • 格式化邏輯
  • 查詢邏輯

低優先級(可選測試):

  • 簡單的 getter/setter
  • DTO 類別
  • 自動產生的程式碼

3. 排除不必要的程式碼

在程式碼或 runsettings 中排除:

// 使用屬性排除
[ExcludeFromCodeCoverage]
public class GeneratedCode
{
    // ...
}

實戰建議與最佳實踐

測試案例數量決策

  1. 基於需求分析
  2. 列出方法的使用案例
  3. 識別邊界條件和異常情況
  4. 考慮業務邏輯的各種情境

  5. 參考複雜度指標

  6. 循環複雜度提供測試案例下限
  7. 高複雜度方法需要更多測試
  8. 考慮重構降低複雜度

  9. 平衡覆蓋率與品質

  10. 不以 100% 覆蓋率為唯一目標
  11. 專注於關鍵業務邏輯
  12. 確保測試的實際價值

測試策略

四大測試類型:

  1. 邊界測試:測試輸入值的上下限
  2. 異常測試:驗證錯誤處理邏輯
  3. 主流程測試:覆蓋正常的業務流程
  4. 條件分支測試:確保所有分支都有測試

持續改善

  1. 定期檢視報告
  2. 每次提交前檢查涵蓋率變化
  3. Pull Request 時審查覆蓋率

  4. 識別風險區域

  5. 關注未覆蓋的關鍵程式碼
  6. 優先處理高複雜度未測試區域

  7. 漸進式改善

  8. 逐步提升重要模組的測試覆蓋率
  9. 新功能必須包含測試

  10. 團隊協作

  11. 建立測試標準和流程
  12. Code Review 包含測試檢查

CI/CD 整合

GitHub Actions 範例

name: Test with Coverage

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup .NET
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: '9.0.x'

      - name: Run tests with coverage
        run: dotnet test --collect:"XPlat Code Coverage"

      - name: Generate coverage report
        run: |
          dotnet tool install -g dotnet-reportgenerator-globaltool
          reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coverage -reporttypes:Html

      - name: Upload coverage
        uses: codecov/codecov-action@v3

Azure DevOps 範例

- task: DotNetCoreCLI@2
  displayName: 'Run tests with coverage'
  inputs:
    command: 'test'
    arguments: '--collect:"XPlat Code Coverage"'
    publishTestResults: true

- task: PublishCodeCoverageResults@1
  inputs:
    codeCoverageTool: 'Cobertura'
    summaryFileLocation: '$(Agent.TempDirectory)/**/*coverage.cobertura.xml'

常見問題與解決方案

Q1: 覆蓋率顯示 0%?

檢查清單:

  1. 確認已安裝 coverlet.collector 套件
  2. 檢查 runsettings 設定是否正確
  3. 確認測試有實際執行
  4. 查看是否有排除設定過於廣泛

Q2: Visual Studio 看不到覆蓋率?

解決方案:

  • Community/Professional 版本:安裝 Fine Code Coverage 擴充套件
  • Enterprise 版本:使用內建功能
  • 確認已啟用覆蓋率收集

Q3: VS Code 無法顯示覆蓋率?

解決方案:

  1. 確認已安裝 C# Dev Kit
  2. 重新執行「執行涵蓋範圍測試」
  3. 檢查 lcov 檔案是否產生
  4. 嘗試重新載入視窗

Q4: 如何提升覆蓋率?

策略:

  1. 識別未覆蓋的關鍵程式碼(紅色區域)
  2. 補充邊界條件測試
  3. 測試所有條件分支
  4. 加入異常情境測試
  5. 考慮重構過於複雜的方法

範本檔案

請參考同目錄下的範本檔案:

  • templates/runsettings-template.xml - 覆蓋率設定範本
  • templates/coverage-workflow.md - 完整的工作流程說明

檢查清單

設定程式碼覆蓋率時,請確認以下項目:

  • [ ] 已安裝 coverlet.collector 套件
  • [ ] 可以執行 dotnet test --collect:"XPlat Code Coverage"
  • [ ] 工具可以正常顯示覆蓋率結果
  • [ ] 了解覆蓋率數字的真正意義(不是 KPI)
  • [ ] 已排除不必要的程式碼(如自動產生的程式碼)
  • [ ] 團隊理解覆蓋率是輔助工具而非目標
  • [ ] 專注於測試品質而非覆蓋率數字

相關技能

  • unit-test-fundamentals - 單元測試基礎與 FIRST 原則
  • xunit-project-setup - xUnit 測試專案設定
  • test-naming-conventions - 測試命名規範

核心理念

程式碼覆蓋率是手段,不是目的。

重點不在於數字有多高,而在於:

  • 關鍵業務邏輯是否都有測試
  • 測試是否真正驗證了預期行為
  • 是否能在重構時提供信心

參考資源

原始文章

本技能內容提煉自「老派軟體工程師的測試修練 - 30 天挑戰」系列文章:

  • Day 06 - Code Coverage 程式碼涵蓋範圍實戰指南
  • 鐵人賽文章:https://ithelp.ithome.com.tw/articles/10374467
  • 範例程式碼:無(本章節為概念說明)

官方文件

工具

相關技能

  • unit-test-fundamentals - 單元測試基礎與 FIRST 原則
  • xunit-project-setup - xUnit 專案設定

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.