golang在Pull Request中跟踪代码覆盖率并生成精美HTML报告的插件go-beautiful-html-coverage的使用

go-beautiful-html-coverage

一个GitHub Action,用于在Pull Request中跟踪代码覆盖率,并生成精美的HTML报告。

使用方式

要使用这个Action,只需将它添加到现有的CI工作流中。一个最基本的示例如下:

name: Go

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  test:
    name: Build and Test
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write        # 需要写权限来发布评论
      contents: write             # 需要写权限来推送git
    steps:
      - uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v5

      - name: Test                # 这一步应该生成cover.out
        run: make test

      - name: Go Beautiful HTML Coverage
        uses: 'gha-common/go-beautiful-html-coverage@v1'

工作原理

这个GitHub Action期望在运行时你的代码库根目录下存在cover.out文件。cover.out通常是通过go test命令加上-coverprofile=cover.out标志生成的:

go test -coverprofile=cover.out ./...

一旦测试运行完毕并生成了cover.out文件,这个Action会执行以下操作:

  1. 如果不存在,创建并推送一个新的孤立分支
  2. cover.out生成cover.htmlcover.txt
  3. 自定义cover.html并将其重命名为<sha>.html
  4. <sha>.html文件推送到孤立分支,这会触发GitHub Pages部署
  5. 在你的PR中发布一条评论,包含代码覆盖率摘要(cover.txt)和<sha>.html的链接

配置参考

- name: Go Beautiful HTML Coverage
  uses: 'gha-common/go-beautiful-html-coverage@v1'
  with:
    # 仓库名称和所有者。例如:actions/checkout
    # 默认: ${{ github.repository }}
    repository: ''

    # 检出或创建并推送覆盖率报告的分支
    # 默认: 'cover'
    branch: ''

    # 用于推送到仓库的token
    # 默认: ${{ github.token }}
    token: ''

    # go项目的相对路径。对monorepo和自定义文件夹结构很有用
    # 默认: ./
    path: ''

    # 所需的最小覆盖率百分比
    # 默认: 0
    threshold: ''

示例

你可以自定义托管代码覆盖率文件的分支名称

- name: Go Beautiful HTML Coverage
  uses: 'gha-common/go-beautiful-html-coverage@v1'
  with:
    branch: 'my-coverage'

你可以自定义托管代码覆盖率文件的仓库

这在你不想弄乱项目仓库,或者想跨多个仓库集中报告覆盖率,或者无法在项目仓库中启用GitHub Pages时很有帮助。

- name: Go Beautiful HTML Coverage
  uses: 'gha-common/go-beautiful-html-coverage@v1'
  with:
    repository: yourname/coverage
    token: ${{ secrets.GHA_COVERAGE_TOKEN }}

其中GHA_COVERAGE_TOKEN是一个仓库secret,包含一个有写权限的个人token。

你可以自定义项目中go代码的路径

这在你有包含多个应用的monorepo,或者简单地将go文件放在子文件夹中时很有帮助。只需确保在运行这个Action之前为所有应用生成cover.out

- name: Go Beautiful HTML Coverage
  uses: 'gha-common/go-beautiful-html-coverage@v1'
  with:
    path: ./go-app-01

- name: Go Beautiful HTML Coverage
  uses: 'gha-common/go-beautiful-html-coverage@v1'
  with:
    path: ./go-app-02

注意事项

为了使HTML预览链接正常工作,需要在目标仓库中配置GitHub Pages设置 > Pages)为从分支部署,并选择目标分支,默认是cover


更多关于golang在Pull Request中跟踪代码覆盖率并生成精美HTML报告的插件go-beautiful-html-coverage的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang在Pull Request中跟踪代码覆盖率并生成精美HTML报告的插件go-beautiful-html-coverage的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用go-beautiful-html-coverage跟踪PR代码覆盖率

go-beautiful-html-coverage是一个用于在Go项目中生成精美HTML覆盖率报告的插件,特别适合在Pull Request中展示代码覆盖率变化。

安装和使用

首先安装插件:

go install github.com/kelveny/go-beautiful-html-coverage@latest

基本用法

  1. 首先运行测试并生成覆盖率profile文件:
go test -coverprofile=coverage.out ./...
  1. 然后使用插件生成HTML报告:
go-beautiful-html-coverage -coverprofile coverage.out -o coverage.html

在CI/CD中集成

以下是一个GitHub Actions工作流示例,用于在PR中生成和显示覆盖率报告:

name: Test and Coverage

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Set up Go
      uses: actions/setup-go@v2
      with:
        go-version: '1.20'
    
    - name: Run tests with coverage
      run: |
        go test -coverprofile=coverage.out ./...
        go tool cover -func=coverage.out
        
    - name: Generate beautiful HTML coverage report
      run: |
        go install github.com/kelveny/go-beautiful-html-coverage@latest
        go-beautiful-html-coverage -coverprofile coverage.out -o coverage.html
        
    - name: Upload coverage report as artifact
      uses: actions/upload-artifact@v2
      with:
        name: coverage-report
        path: coverage.html

高级功能

  1. 排除目录
go-beautiful-html-coverage -coverprofile coverage.out -o coverage.html -exclude-dirs vendor,testdata
  1. 设置阈值(如果覆盖率低于阈值则失败):
go-beautiful-html-coverage -coverprofile coverage.out -o coverage.html -threshold 80
  1. 与GitHub Pages集成
- name: Deploy to GitHub Pages
  if: github.ref == 'refs/heads/main'
  uses: peaceiris/actions-gh-pages@v3
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    publish_dir: ./
    publish_branch: gh-pages
    keep_files: true

报告特点

生成的HTML报告具有以下特点:

  • 美观的可视化界面
  • 按目录和文件组织的覆盖率数据
  • 彩色编码的覆盖率指标
  • 点击文件可查看详细的覆盖/未覆盖行
  • 支持与历史覆盖率数据对比

示例代码

以下是一个完整的Go测试示例,展示如何获得良好的覆盖率:

// main.go
package main

import "fmt"

func Add(a, b int) int {
    return a + b
}

func Subtract(a, b int) int {
    return a - b
}

func main() {
    fmt.Println("Calculator")
}
// main_test.go
package main

import "testing"

func TestAdd(t *testing.T) {
    tests := []struct {
        name string
        a, b int
        want int
    }{
        {"positive", 2, 3, 5},
        {"negative", -1, -1, -2},
        {"zero", 0, 0, 0},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := Add(tt.a, tt.b); got != tt.want {
                t.Errorf("Add() = %v, want %v", got, tt.want)
            }
        })
    }
}

func TestSubtract(t *testing.T) {
    tests := []struct {
        name string
        a, b int
        want int
    }{
        {"positive", 5, 3, 2},
        {"negative", -1, -1, 0},
        {"zero", 0, 0, 0},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := Subtract(tt.a, tt.b); got != tt.want {
                t.Errorf("Subtract() = %v, want %v", got, tt.want)
            }
        })
    }
}

运行测试并生成报告后,你将得到一个直观的HTML报告,清楚地展示哪些代码被测试覆盖,哪些没有。

回到顶部