现象
Tests workflow 保留的 8 次运行全部是 failure(2026-01-07 → 2026-04-18),最近一次跑了 6 小时 5 分。同一次 workflow 里 Lint and Type Check 和 Mesa compat 两个 job 是绿的——红的只有那 9 条 Tests 矩阵腿。
而本地跑 uv run pytest 是 676 passed / 19 秒。也就是说:测试本身没问题,是流水线的入口选错了,而且红灯不产生任何可用信号。
$ gh run list --workflow=tests.yml --limit 8
completed failure ... Tests dev pull_request 24599874652 6h5m5s 2026-04-18
completed failure ... Tests dev pull_request 24087345337 14m57s 2026-04-07
completed failure ... (其余 6 次同样 failure)
根因
.github/workflows/tests.yml 的矩阵入口是:
- name: Run Make test-all (unit + notebooks + tox)
run: |
uv run make test-all
而 makefile 的 test-all 除了单测还要做两件事:
@uv sync --group docs || echo "⚠️ Failed to install docs dependencies"
uv run pytest --nbmake docs/tutorial/**/*.ipynb -v --tb=short || echo "⚠️ ..."
tox -p auto || echo "⚠️ Multi-version tests completed with warnings"
问题有三层:
- 矩阵里嵌套矩阵:矩阵已经是
{ubuntu, macos, windows} × {3.11, 3.12, 3.13} 共 9 条腿,每条腿再跑一次 tox -p auto(py311/py312/py313),等于 27 次嵌套运行。6 小时的运行时长就来自这里。
- tox 在 Linux/Windows 上不可能成功:
tox.ini 写死了 macOS Homebrew 路径
[testenv:py312]
basepython = /opt/homebrew/bin/python3.12
- 失败被吞掉:两个
|| echo 让真正失败的部分不上报,所以即使红了也看不出红在哪。
make test-all 是给本地用的「全都跑一遍」入口,不该当矩阵入口——矩阵本身就是多版本测试。
同一处的第二个问题:coverage.xml 从未被生成
- name: Upload coverage (3.11 on ubuntu)
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: false
file: ./coverage.xml
但 makefile 里的 pytest 命令没有 --cov-report=xml:
uv run pytest tests/ -vs --clean-alluredir --alluredir tmp/allure_results --cov=abses --no-cov-on-fail
叠加 fail_ci_if_error: false,上传每次都静默失败。仓库里也没有 codecov.yml,没有任何 --cov-fail-under,覆盖率完全无门禁(当前实测 80%)。
建议方案
把矩阵入口换成一条普通的 pytest:
- name: Run tests
run: uv run pytest tests/ --cov=abses --cov-report=xml --cov-report=term
一处改动同时解决四件事:去掉嵌套 tox 扇出、绕开写死的 Homebrew 路径、去掉两个吞异常的 || echo、并真正产出 coverage.xml。
配套:
- notebook 测试已有独立的
test-notebooks.yml,不必塞进矩阵;
tox.ini 的 basepython 硬编码要去掉(或干脆废弃 tox,矩阵已经覆盖多版本);
- 定一个
--cov-fail-under 底线(建议先设 78,低于当前的 80 留一点余量),或用 codecov 的 status check;
- CI 的
ruff check 目前只检查 abses/,而 pre-commit 检查全部改动文件,两边不一致,建议对齐为 abses/ tests/;
interrogate(--fail-under=70)只在 pre-commit 里跑,建议也进 CI。
顺带一提 makefile 的 test-parallel 用了 pytest -n auto,但 pytest-xdist 不在 dev 依赖组里,这个 target 开箱即坏。
验收标准
现象
Testsworkflow 保留的 8 次运行全部是 failure(2026-01-07 → 2026-04-18),最近一次跑了 6 小时 5 分。同一次 workflow 里Lint and Type Check和Mesa compat两个 job 是绿的——红的只有那 9 条Tests矩阵腿。而本地跑
uv run pytest是 676 passed / 19 秒。也就是说:测试本身没问题,是流水线的入口选错了,而且红灯不产生任何可用信号。根因
.github/workflows/tests.yml的矩阵入口是:而
makefile的test-all除了单测还要做两件事:问题有三层:
{ubuntu, macos, windows} × {3.11, 3.12, 3.13}共 9 条腿,每条腿再跑一次tox -p auto(py311/py312/py313),等于 27 次嵌套运行。6 小时的运行时长就来自这里。tox.ini写死了 macOS Homebrew 路径|| echo让真正失败的部分不上报,所以即使红了也看不出红在哪。make test-all是给本地用的「全都跑一遍」入口,不该当矩阵入口——矩阵本身就是多版本测试。同一处的第二个问题:
coverage.xml从未被生成但
makefile里的 pytest 命令没有--cov-report=xml:叠加
fail_ci_if_error: false,上传每次都静默失败。仓库里也没有codecov.yml,没有任何--cov-fail-under,覆盖率完全无门禁(当前实测 80%)。建议方案
把矩阵入口换成一条普通的 pytest:
一处改动同时解决四件事:去掉嵌套 tox 扇出、绕开写死的 Homebrew 路径、去掉两个吞异常的
|| echo、并真正产出coverage.xml。配套:
test-notebooks.yml,不必塞进矩阵;tox.ini的basepython硬编码要去掉(或干脆废弃 tox,矩阵已经覆盖多版本);--cov-fail-under底线(建议先设 78,低于当前的 80 留一点余量),或用 codecov 的 status check;ruff check目前只检查abses/,而 pre-commit 检查全部改动文件,两边不一致,建议对齐为abses/ tests/;interrogate(--fail-under=70)只在 pre-commit 里跑,建议也进 CI。顺带一提
makefile的test-parallel用了pytest -n auto,但pytest-xdist不在 dev 依赖组里,这个 target 开箱即坏。验收标准
Testsworkflow 在 dev 上变绿。|| echo形式的失败吞噬。