☰
Toga 代码贡献实操指南:编写、运行与测试的完整工作流
2026/10/13 6:54:43 网站建设 项目流程
  • 跨平台
  • UI组件
  • 桌面应用

【免费下载链接】toga

A Python native, OS native GUI toolkit.

项目地址:https://gitcode.com/gh_mirrors/to/toga
点击查看免费下载

本篇指南面向想要为 Toga(Python 原生、操作系统原生 GUI 工具包)贡献代码的开发者,系统讲解从搭建开发环境、创建分支,到运行toga-core与 Travertino 测试套件、驱动跨平台 Testbed 应用进行真实 GUI 验证,直至提交 Pull Request 的完整流程。读完本文,你将掌握tox标签化测试命令、Briefcase 开发者测试模式、slow mode 等核心工具,并理解测试覆盖率为 100% 这一项目硬性要求背后的实现机制。

开始之前:开发环境与分支约定

动手写代码之前,请先确认两件事:

  1. 开发环境已就绪:参考 dev-environment.md 完成环境搭建。不同平台需要安装对应的原生 GUI 依赖——macOS 需要 macOS 前置依赖,Linux 需要 GTK 或 Qt 开发依赖,Windows 需要 Windows 前置依赖,并执行类似python -m pip install -e ./core -e ./dummy -e ./cocoa -e ./travertino --group dev(平台不同,后端包不同)的 editable 安装。
  2. 工作分支已创建:Toga 明确要求从 feature 分支工作,而不是直接在main分支上开发,具体约定见 branches.md。

完成上述准备后,你才能进入代码的编写、运行与测试环节。

测试套件全景:两条测试主线

Toga 仓库的测试体系分为两条主线:

  • 核心库(toga-core):即core/目录下的toga包,测试位于 core/tests,覆盖 app、window、widgets、command、sources、style 等全部核心 API;
  • Travertino:travertino/目录下的独立包,定义了核心库所依赖的底层布局机制与样式定义(layout 与 style),测试位于 travertino/tests。

这两条测试主线由仓库根目录 tox.ini 统一编排。tox.ini 中通过labels定义了一组语义化的测试入口:

labels = test = py-cov{,-trav},coverage{,-trav} test-core = py-cov,coverage test-trav = py-cov-trav,coverage-trav

也就是说,test-core会运行核心测试并在最后输出覆盖率报告;test-trav对应 Travertino;test则两者都跑,依次输出两份覆盖率结果。这些标签正是下文所有tox -m ...命令的入口。

运行完整测试套件

只测核心库(toga-core)

在项目根目录((.venv)虚拟环境中)执行:

(.venv) $ tox -m test-core

该命令对应test-core = py-cov,coverage标签:先以coverage run方式执行 pytest,再合并并输出覆盖率报告。与完整测试套件一致,核心库测试应报告100% 测试覆盖率。tox 环境中还通过TOGA_BACKEND = toga_dummy指定了toga_dummy作为测试后端(见 tox.ini),所有核心测试均在无头(dummy)后端上运行,不依赖任何真实 GUI 环境。

只测 Travertino

(.venv) $ tox -m test-trav

与核心库一样,Travertino 的测试也应报告100% 测试覆盖率。执行时 tox 会将工作目录切换到travertino(tox.ini 中changedir = travertino),并仅安装 Travertino 及其测试依赖。

同时测试核心与 Travertino

(.venv) $ tox -m test

这会依次运行两套测试,并在最后先后输出两份覆盖率结果(核心一份、Travertino 一份),两者同样都应达到 100%。

只运行某个测试子集

当你只需要针对某个特定文件或用例做快速迭代时,不必跑完整套件。核心库的 pytest 参数可以直接透传给py-cov环境,例如只运行test_command.py:

(.venv) $ tox -e py-cov -- tests/command/test_command.py

而如果目标是 Travertino 的某个测试,则在环境名后追加-trav,并把测试路径换成 Travertino 的tests目录:

(.venv) $ tox -e py-trav -- tests/path_to_test_file/test_some_test.py

--之后的所有参数都会原样透传给 pytest,所以你可以继续追加-k、-x、--pdb等 pytest 原生选项。需要说明的是,直接运行 pytest 子集时不会生成覆盖率报告,覆盖率仍由coverage环境在完整运行后汇总产出。

Testbed:验证真实后端行为的 GUI 测试应用

上述tox套件只覆盖了toga-core与travertino——它们都在 dummy 后端上运行,不涉及真实 GUI。那么各平台后端(Cocoa、WinForms、GTK、Qt、Android、iOS、Web、Textual)的行为如何验证?答案就是Testbed 应用。

Testbed 的工作原理

Testbed 的核心思路是:用核心 API 编写一套通用的行为测试,再通过"探针"(probe)机制去操作和检查真实后端内部状态。详细设计见 testbed.md:

  • 通用行为测试位于 testbed/tests,它们通过控件的公开 API触发各种边界情况,并在一个真实运行的 App 事件循环上以async方式执行;
  • 每个后端在自己的tests_backend目录中实现 probe(如 cocoa/tests_backend、android/tests_backend)。probe 能访问公开 API 无法触及的内部状态——例如控件的物理尺寸、渲染所用的字体,还能模拟点击等 GUI 事件来验证回调是否正确触发;
  • probe 提供redraw()方法:GUI 框架常将视觉变更批量合并到一次重绘中,测试在断言属性前调用await probe.redraw()可确保所有待处理的重绘事件已被处理;
  • 当某个平台尚未实现某控件/方法时,测试或 probe 应调用pytest.skip()(conftest.py 提供了skip_on_platforms()、skip_on_backends()等辅助函数);若该平台永不支持某特性,则用pytest.xfail()标记预期失败。

Testbed 的运行逻辑集中在 testbed/tests/testbed.py:它负责选择后端、启动 coverage 跟踪(含针对 Wayland/X11、GTK3/GTK4/libadwaita、.NET Framework/Core 等环境的条件覆盖规则)、解析--slow/--coverage/--ci参数,并在 App 主循环中通过后台线程执行 pytest。值得一提的还有toga_dummy之外的后端选择逻辑:TOGA_BACKEND环境变量优先,否则按sys.platform自动映射(darwin→toga_cocoa、linux→toga_gtk、win32→toga_winforms等)。

运行 Testbed 应用(桌面平台)

运行 Testbed 需要 Python 3.12 虚拟环境并安装 Briefcase)。注意:虚拟环境中应只安装一个后端——即你打算测试的那一个。

macOS 下运行(默认使用 Cocoa 后端):

(.venv) $ python -m pip install briefcase (.venv) $ cd testbed (.venv) $ briefcase dev --app testbed --test

Linux 下需要显式指定后端。测试 GTK3 后端:

(.venv) $ python -m pip install briefcase (.venv) $ cd testbed (.venv) $ TOGA_BACKEND=toga_gtk briefcase dev --app testbed --test

测试 GTK4 后端(不使用 libadwaita):

(.venv) $ python -m pip install briefcase (.venv) $ cd testbed (.venv) $ TOGA_BACKEND=toga_gtk TOGA_GTK=4 TOGA_GTKLIB=None briefcase dev --app testbed --test

测试 GTK4 后端(使用 libadwaita):

(.venv) $ python -m pip install briefcase (.venv) $ cd testbed (.venv) $ TOGA_BACKEND=toga_gtk TOGA_GTK=4 TOGA_GTKLIB=Adw briefcase dev --app testbed --test

测试 Qt 后端(注意 app 名不同,为testbed-qt,其 Briefcase 配置定义在 testbed/pyproject.toml 的testbed-qt小节):

(.venv) $ python -m pip install briefcase (.venv) $ cd testbed (.venv) $ TOGA_BACKEND=toga_qt briefcase dev --app testbed-qt --test

Windows 下(默认 WinForms 后端):

(.venv) C:\...>python -m pip install briefcase (.venv) C:\...>cd testbed (.venv) C:\...>briefcase dev --app testbed --test

执行后会出现一个 Toga 应用窗口,它会在执行全部 GUI 测试的过程中不断闪烁,最终在测试全部通过后输出一份已执行代码的覆盖率报告(testbed 同样追求 100% 覆盖率,未覆盖会令返回码非零,见 testbed.py)。

重要提醒:测试期间请远离键盘和鼠标!Testbed 通过真实触发鼠标点击、并检查控件与窗口焦点变化来断言行为,因此必须全程独占输入控制权,测试过程中任何人工输入都会干扰结果。

关于 Python 版本:虽然 Toga 本身支持从最低 Python 版本起的所有版本,但 Testbed 只支持 Python 3.12。这是有意为之的简化——跨 Python 版本的行为一致性由核心测试保证,Testbed 只需验证核心 API 在各平台后端上的表现一致即可。

关于 GTK4 与 Qt:这两个后端目前仍是实验性且仅部分实现的状态,因此运行时会跳过大量测试。补齐这些缺失控件的实现,正是非常受欢迎的贡献方向。

运行 Testbed 子集与 slow mode

Testbed 完整套件运行较慢,你可以用与主测试套件相同的方式透传 pytest 参数来只跑子集。此外 Testbed 还有一个核心测试没有的独特功能——slow mode:它会以同样的顺序执行测试,但在每个 GUI 动作之间刻意暂停 1 秒,方便你亲眼观察测试过程。slow mode 通过--slow启用,而 1 秒延迟正是借由每个redraw()请求实现的(见 testbed.md)。

例如,只以 slow mode 运行 Button 控件的测试:

(.venv) $ briefcase dev --app testbed --test -- tests/widgets/test_button.py --slow

Linux 下 Qt 后端对应:

(.venv) $ briefcase dev --app testbed-qt --test -- tests/widgets/test_button.py --slow

这类测试会耗时明显更长,但你能在屏幕上看到 Button 控件依次经历各种颜色、格式与尺寸变化。注意:运行测试子集或启用 slow mode 时不会输出覆盖率报告。

运行 Testbed 测试(移动平台)

briefcase dev开发者模式只适用于桌面平台(Cocoa、WinForms、GTK)。要测试移动后端,必须改用briefcase run,将应用部署到模拟器或设备上执行。

macOS 下:

(.venv) $ briefcase run android --app testbed --test (.venv) $ briefcase run iOS --app testbed --test

Linux 下只能运行 Android 套件(iOS 测试无法在 Linux 上执行):

(.venv) $ briefcase run android --app testbed --test

Windows 下同样只能运行 Android 套件(iOS 测试无法在 Windows 上执行):

(.venv) C:\...>briefcase run android --app testbed --test

briefcase run同样支持--slow与 pytest 参数透传,语法与开发者模式一致(--之后追加参数)。移动端测试会依赖 testbed/pyproject.toml 中声明的相机、定位等权限(permission.camera、permission.fine_location等),并在 Android 构建中通过build_gradle_extra_content配置了 pytest 断言重写与覆盖率所需的源文件提取。

测试完成之后:提交 Pull Request

当一切就绪,就可以把你的改动提交为 Pull Request,详见 submit-pr.md。提交 PR 通常还需要附带一条 change note(放在changes/目录下的新文件里),经 PR 评审流程 通过后才能合入。

关键源码与配置索引

关注点仓库路径
tox 标签与测试环境定义tox.ini
核心测试套件core/tests
核心 pytest/覆盖率配置core/pyproject.toml
Travertino 测试套件travertino/tests
Testbed 运行逻辑testbed/tests/testbed.py
Testbed 测试辅助与 skip/xfail 工具testbed/tests/conftest.py
Testbed 控件测试示例testbed/tests/widgets/test_button.py
Testbed Briefcase 清单testbed/pyproject.toml
Testbed 工作原理专题docs/en/topics/internal/testbed.md
  • 跨平台
  • UI组件
  • 桌面应用

【免费下载链接】toga

A Python native, OS native GUI toolkit.

项目地址:https://gitcode.com/gh_mirrors/to/toga
点击查看免费下载
上一篇:10分钟上手Django生态最实用工具集:从博客到社交关系全栈开发指南
下一篇:终极指南:如何在FF14中快速上手Dalamud插件开发框架

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询