GitHub Actions 自动化测试:Push 就跑测试,PR 不达标不让合并

小飞兽 Python 7 次阅读 2026-07-24

Introduction

代码提交了,测试忘跑了——这种事谁都遇到过。GitHub Actions 让代码仓库与自动化测试无缝集成:每次 push、每次 PR 自动跑测试,结果直接显示在 PR 里,不达标就阻止合并。

本文手把手配一个 Python + pytest + pytest-cov 的 CI 流程。

---

基础语法

1. 创建 workflow 文件

在仓库根目录新建 .github/workflows/ci.yml

name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: 安装依赖
        run: |
          python -m pip install --upgrade pip
          pip install pytest pytest-cov pytest-html

      - name: 跑测试(带覆盖率)
        run: |
          pytest tests/             --cov=myproject             --cov-report=xml             --cov-report=html             --html=report.html --self-contained-html

      - name: Upload 测试报告
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: test-report
          path: report.html

      - name: Upload 覆盖率报告
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage.xml

2. 在 Pull Request 里设置覆盖率卡点

pytest 命令加 --cov-fail-under=80,覆盖率低于80%时测试直接失败:

- name: 跑测试
  run: |
    pytest tests/ --cov=myproject --cov-fail-under=80

3. 多版本 Python 同时测试

strategy:
  matrix:
    python-version: ['3.9', '3.10', '3.11', '3.12']

---

运行效果

每次 push/PR 自动在 GitHub Actions 页面看到:

  • ✅ 所有测试通过

  • 📊 覆盖率百分比

  • ⏱️ 执行时间

  • 📎 可下载的 HTML 测试报告

如果覆盖率不达标,PR 页面会显示红色 ❌,阻止合并:

Failed — 1 test failed, Coverage: 72% (minimum: 80%)

---

常见问题

Q1: GitHub Actions 跑得很慢?

把 pip 缓存起来:
- name: Cache pip packages
  uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}

Q2: 不想把 coverage 上传到 codecov?

删掉 codecov 那一步,已生成的 HTML 报告通过 actions/upload-artifact 下载即可。

Q3: 需要测试多个数据库(MySQL、PostgreSQL)?

services 字段启动 Docker 容器:
services:
  mysql:
    image: mysql:8.0
    env:
      MYSQL_ROOT_PASSWORD: test
      MYSQL_DATABASE: testdb
    options: >-
      --health-cmd="mysqladmin ping"
      --health-interval=10s
      --health-timeout=5s
      --health-retries=5
    ports:
      - 3306:3306

Q4: 想在 PR 评论里看到测试结果?

安装 Codecov 或 Coveralls GitHub App,PR 自动评论覆盖率变化。

---

延伸阅读

  • [[GitHub Actions 定时任务]] — 定时跑健康检查
  • [[Docker + GitHub Actions]] — 构建镜像并推送到 Registry
  • [[pytest 覆盖率最佳实践]] — 覆盖率阈值怎么定合理

---
有问题欢迎在评论区交流!