-
Notifications
You must be signed in to change notification settings - Fork 6
90 lines (79 loc) · 3.9 KB
/
Copy pathtests.yml
File metadata and controls
90 lines (79 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
name: Tests
# 触发条件:推主干、开 PR、手动触发,以及被 release.yml 以 workflow_call
# 复用。复用而不是在 release.yml 里再抄一份 pytest 步骤:抄一份意味着两条
# 流水线的测试范围会慢慢分叉,而发布这条恰恰是最不该跑得比主干松的。
on:
push:
branches: ["master", "main"]
pull_request:
workflow_dispatch:
workflow_call:
# 同一分支上新的推送取消尚未跑完的旧任务,省 runner 额度。
concurrency:
group: tests-${{ github.ref }}
cancel-in-progress: true
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
test:
name: pytest (ubuntu, py${{ matrix.python-version }})
runs-on: ubuntu-latest
# 正常一轮 2~4 分钟。不设上限的话,任何一步卡住都会一直烧到 GitHub 的
# 6 小时 job 上限——实测发生过三次(305 / 38 / 362 分钟),全都停在
# apt 那一步,而日志里只有一行「操作已取消」,看不出卡在哪。
# 20 分钟给足余量,又能让卡死在十几分钟内暴露成一条明确的超时失败。
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
# 3.10 是 README 声明的最低版本(用到 match/case 与 PEP 604 union),
# 3.13 是当前开发机版本。两头都跑,中间版本由它们夹逼覆盖。
python-version: ["3.10", "3.13"]
steps:
- uses: actions/checkout@v5
# gui_app.py 顶层就 `import tkinter` + `matplotlib.use("TkAgg")`,
# 所以**全部**测试(包括纯逻辑那批)都需要 _tkinter 能 import。
# actions/setup-python 的 Linux 构建不保证带 Tk,必须先装系统 Tk 库,
# 否则连收集阶段都会 ModuleNotFoundError: No module named '_tkinter'。
# xvfb 用于给建真实 Tk 根窗口的 GUI 测试提供虚拟显示。
- name: Install Tk and virtual display
# apt 默认会无限等一个不响应的镜像。实测卡在 archive.ubuntu.com 的
# 一次 InRelease 抓取上,六小时没有再输出一行。给它显式超时与重试,
# 步骤级上限再兜一道——失败要快,且要指得出是这一步。
timeout-minutes: 6
run: |
set -euo pipefail
apt_get() {
sudo apt-get \
-o Acquire::Retries=3 \
-o Acquire::http::Timeout=20 \
-o Acquire::https::Timeout=20 \
"$@"
}
apt_get update
apt_get install -y --no-install-recommends tk-dev python3-tk xvfb
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: pip
- name: Verify tkinter is importable
# 提前把「Python 构建不带 Tk」这类环境问题暴露成一条清晰的失败,
# 而不是让它伪装成几百条测试的收集错误。
run: python -c "import tkinter; print('tkinter', tkinter.TkVersion)"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest
# 先跑纯逻辑那批。它们不建窗口,失败信息最干净,
# 也让「是不是显示环境问题」一眼可判。
- name: Run non-GUI tests
run: pytest -m "not gui" -q -p no:cacheprovider
# GUI 测试会构造真实 BacktestApp(tk.Tk 子类)。没有窗口服务器时
# Tk 是整进程 abort 而不是抛异常,所以必须包在 xvfb-run 里。
- name: Run GUI tests (xvfb)
# -p no:cacheprovider:CI 每次都是干净 checkout,缓存没有收益;
# 关掉还能顺带避开 .pytest_cache 陈旧 lastfailed 影响用例执行的坑
# (本地实测过:残留缓存会让两条 intraday 用例假失败,删掉即恢复)。
run: xvfb-run -a pytest -m "gui" -q -p no:cacheprovider