Oppia CI 测试套件配置指南:解读 core/tests/ci-test-suite-configs 的注册机制与运行链路
教育后端前端【免费下载链接】oppiaA free, online learning platform to make quality education accessible for all.项目地址https://gitcode.com/gh_mirrors/op/oppia点击查看免费下载导读core/tests/ci-test-suite-configs是 Oppia 仓库中定义「哪些测试套件需要在 CI 上运行」的单一事实来源single source of truth。本文以该目录下的 README 与acceptance.json为核心结合scripts目录下的 Python 脚本与.github/workflows/full_stack_tests.yml工作流系统讲解配置文件的 JSON 结构、字段含义、新增测试套件的完整操作步骤以及从「配置注册」到「CI 矩阵分发」再到「校验同步」的完整源码级调用链。读完本文你将掌握如何为 Oppia 的 Acceptance 测试注册新套件并理解其背后的自动化保障机制。一、目录定位CI 测试套件配置的集中地在 core/tests/ci-test-suite-configs/README.md 中Oppia 明确说明了该目录的职责This folder contains the CI test suite configs for the different test types. All tests that are to be run on the CI should be added to its corresponding test type JSON config with the name of the specific suite and the module or file path of the script.翻译过来就是所有需要在 CI 上运行的测试都必须以「套件名name 测试脚本路径module」的形式登记到对应测试类型的 JSON 配置中。这是 Oppia 测试基础设施的一条硬性约定——测试代码写好了还不够必须在配置文件中「注册」CI 才会真正调度它。README 中列出的测试类型与对应 JSON 配置如下测试类型对应 JSON 配置E2Ee2e.jsonAcceptanceacceptance.json需要说明的是在当前仓库快照中该目录实际只保留了 acceptance.json 这一个配置文件README 中提到的e2e.json尚未出现在本仓库快照中推测与 E2E 测试套件的迁移或清理有关。因此本文后续将以acceptance.json为主线展开其结构模式对其他测试类型配置文件同样适用。二、配置文件结构acceptance.json 的 Schema 剖析acceptance.json 是一个标准的 JSON 文件顶层只有一个键suites其值为一组测试套件对象数组。每个套件对象包含三个字段字段类型含义示例namestring测试套件的唯一标识通常为「角色/场景描述」的路径风格命名interested-donor/make-a-donationmodulestring该套件对应的测试脚本相对路径相对仓库根目录以.spec.ts结尾core/tests/puppeteer-acceptance-tests/specs/interested-donor/make-a-donation.spec.tsframeworkstring运行该套件所用的自动化测试框架当前取值为puppeteer或playwrightpuppeteer以文件开头的第一个套件为例{ suites: [ { name: tech-team-lead/manages-lesson-and-site-reports, module: core/tests/puppeteer-acceptance-tests/specs/tech-team-lead/manages-lesson-and-site-reports.spec.ts, framework: puppeteer } ] }2.1 从源码看字段的解析方式配置文件在 Python 侧通过标准库json加载。在 scripts/check_ci_test_suites_to_run.py 中get_test_suites_from_config以DEFAULT_SUITE suites该文件第 124 行定义作为键名读取套件列表def get_test_suites_from_config( test_suites_config_file_path: str, ) - List[GenericTestSuiteDict]: with open(test_suites_config_file_path, r, encodingutf-8) as f: test_suites json.load(f) suites: List[GenericTestSuiteDict] test_suites[DEFAULT_SUITE] return suites而 scripts/run_acceptance_tests.py 中的get_suite_framework则按name精确匹配返回对应的framework字段用于决定后续按 Puppeteer 还是 Playwright 流程启动测试for suites in filedata.values(): for suite in suites: if suite[name] suite_name: return suite[framework]这里有一个值得注意的源码细节scripts/check_tests_are_captured_in_ci.py 的类型定义注释framework字段是在 Puppeteer 向 Playwright 迁移过程中引入的用于在增量迁移阶段区分两类 Acceptance 测试。源码中的TODO(#24715)注释明确写着「一旦迁移完成将移除 framework 字段」。2.2 当前配置规模的实测统计基于 acceptance.json 的实际内容统计当前仓库共登记了155 个 Acceptance 测试套件其中framework: puppeteer的套件122 个位于 core/tests/puppeteer-acceptance-tests/specsframework: playwright的套件33 个位于 core/tests/playwright-acceptance-tests/specs。从name的命名前缀可以清晰地看到这些套件覆盖的产品角色与业务场景例如logged-in-learner/*、logged-out-learner/*、logged-out-user/*学习者与匿名用户的核心浏览、播放、反馈、注册、语言切换等流程lesson-creator/*、exploration-editor/*、exploration-creator/*、topic-manager/*、curriculum-admin/*内容创作与管理侧的功能创建探险、编辑故事、管理技能、发布课程等translation-submitter/*、translation-reviewer/*、voiceover-submitter/*、practice-question-submitter/*贡献者与审核者的协作流程super-admin/*、release-coordinator/*、site-moderator/*、blog-admin/*平台运营与后台管理功能interested-donor/*、interested-parent/*、interested-volunteer/*、interested-partner-organization/*面向访客的落地页与转化流程。从module字段还可以观察到一种双目录结构同一业务场景如exploration-editor的套件脚本分散在 Puppeteer 与 Playwright 两个 spec 目录中这正是迁移期「同一测试逐渐从 Puppeteer 迁移到 Playwright」的过渡态体现。三、配置的消费链路从 JSON 到 CI 矩阵的完整调用链配置文件本身不执行任何测试真正驱动它的是 scripts 目录下的一组 Python 脚本与 GitHub Actions 工作流。整条链路可以概括为acceptance.json │ ▼ scripts.check_ci_test_suites_to_run 计算本次要跑的套件输出给 GitHub Actions │ ▼ .github/workflows/full_stack_tests.yml acceptance_test job 的 matrix 展开 │ ▼ .github/actions/run-a-specific-acceptance-test 调用 Python 脚本启动单套件 │ ▼ scripts.run_acceptance_tests 按 framework 字段分流 Puppeteer / Playwright3.1 阶段一check_ci_test_suites_to_run —— 计算待运行套件scripts/check_ci_test_suites_to_run.py 是整个 CI 测试分发的「大脑」。在 full_stack_tests.yml 的check_test_suites_to_runjob 中它被这样调用TEST_SUITES_TO_RUN$(python -m scripts.check_ci_test_suites_to_run \ --github_head_refHEAD \ --github_base_ref${{ needs.setup_merge_sha.outputs.develop_sha }} \ ${{ env.SHOULD_OUTPUT_ALL_TESTS true --output_all_test_suites || }})其核心行为见 get_all_test_suites_by_type读取acceptance.json的全部套件再按framework字段拆分为acceptancePuppeteer Playwright 全量与acceptance_playwright仅 Playwright两组随后通过output_test_suites_to_run_to_github_workflow该文件第 255-274 行将结果序列化为 JSON并写入 GitHub Actions 的$GITHUB_OUTPUT即TEST_SUITES_TO_RUN变量test_suites_to_run_output { acceptance: test_suites_to_run[acceptance], acceptance_playwright: test_suites_to_run[acceptance_playwright], lighthouse: test_suites_to_run[lighthouse], } output_variable_to_github_workflow( GITHUB_OUTPUT_TEST_SUITES_TO_RUN, json.dumps(test_suites_to_run_output) )工作流后续 job 通过fromJSON(needs.check_test_suites_to_run.outputs.TEST_SUITES_TO_RUN)解出套件列表作为矩阵展开的输入。3.2 阶段二full_stack_tests.yml —— 矩阵化调度在 full_stack_tests.yml 中acceptance_testjob 的矩阵策略直接消费该输出acceptance_test: needs: [check_test_suites_to_run, build, setup_merge_sha] if: ${{ fromJSON(needs.check_test_suites_to_run.outputs.TEST_SUITES_TO_RUN).acceptance.count 0 }} strategy: matrix: suite: ${{ github.event_name merge_group \ fromJSON(needs.check_test_suites_to_run.outputs.TEST_SUITES_TO_RUN).acceptance_playwright.suites || \ fromJSON(needs.check_test_suites_to_run.outputs.TEST_SUITES_TO_RUN).acceptance.suites }}matrix.suite.name即为acceptance.json中登记的名字例如interested-donor/make-a-donation。每个套件在 CI 上会被执行两次桌面端与移动端各一次超时上限均为 60 分钟失败后还会自动重跑一次以排查 flakiness详见 full_stack_tests.yml。3.3 阶段三run_acceptance_tests —— 按 framework 分流执行最终的执行入口是 scripts/run_acceptance_tests.py。其run_tests第 172-257 行根据get_suite_framework(args.suite)的返回值决定启动方式suite_framework get_suite_framework(args.suite) ... # Only compile Puppeteer TypeScript for Puppeteer suites. if suite_framework puppeteer: compile_test_ts_files() # Install Playwright deps for Playwright suites. if suite_framework playwright: install_playwright_dependencies()该脚本支持的主要命令行参数如下定义于 run_acceptance_tests.py参数说明--suite必填。指定要运行的测试套件名称须与acceptance.json中的name一致--skip_build跳过前端构建默认 false--prod_env以生产模式运行静态资源从 build 目录提供并使用 cache slugs--server_log_levelAppEngine 服务器日志级别默认error可选critical/error/warning/info--source_maps构建 Angular 时生成 source maps--headless以 headless 模式运行浏览器--mobile以移动端视口运行--update_snapshots更新截图基线而非对比用于快照刷新本地手动运行单个套件的完整命令为python -m scripts.run_acceptance_tests --suite interested-donor/make-a-donation需要注意的是该脚本要求从根目录名必须为oppia的仓库根目录运行且运行期间会依次拉起 Redis、Firebase Auth 模拟器、Cloud Datastore 模拟器与本地 AppEngine dev server端口8181常量定义于 scripts/common.py。3.4 配置路径的常量定义acceptance.json的路径在 scripts/common.py 中被定义为全局常量多个脚本共享引用ACCEPTANCE_TEST_CONFIG_FILE_PATH os.path.join( CURR_DIR, core, tests, ci-test-suite-configs, acceptance.json )四、同步性校验CI 配置与测试文件必须保持一致Oppia 用一层「自动校验」确保acceptance.json不会遗漏或冗余登记任何套件这正是 scripts/check_tests_are_captured_in_ci.py 的职责其模块 docstring 写道A script to check that the CI config files and the test files have the same test suites。4.1 双向比对逻辑该脚本从两个方向收集套件信息check_tests_are_captured_in_ci.py从配置文件收集解析acceptance.json取出每个套件的name、module、framework从测试目录收集用glob.glob(**/*.spec.ts, recursiveTrue)扫描core/tests/puppeteer-acceptance-tests/specs与core/tests/playwright-acceptance-tests/specs两个目录将.spec.ts文件相对路径去掉后缀后作为name并依据所在目录标记framework。随后 compute_test_suites_difference 计算两侧的差集。只要存在任一方向的不一致新增了 spec 文件却没登记或配置里登记了已删除的 spec脚本就会抛出异常并明确提示开发者去更新配置文件Acceptance test suites and CI test suites are not in sync. The following suites are not in sync: [...] Please update the CI config file for acceptance tests at core/tests/ci-test-suite-configs/acceptance.json with the suites listed above.4.2 校验在 CI 中的位置在 full_stack_tests.yml 中这个校验被安排为独立的acceptance_coveragejob名称为 Verify all acceptance tests are included在套件运行之前先执行- name: Check that all acceptance test files are captured in core/tests/ci-test-suite-configs run: python -m scripts.check_tests_are_captured_in_ci也就是说任何新增或删除的 Acceptance 测试 spec如果不更新acceptance.jsonCI 会直接红灯拦截。4.3 本地 pre-push 钩子中的关联检查同步机制在本地也有一层防护。scripts/pre_push_hook.py 的does_diff_include_ci_config_or_test_files会检查提交是否涉及ci-test-suite-configs/.*\.json或puppeteer-acceptance-tests相关文件从而触发对应的校验逻辑让开发者在 push 之前就能发现配置与测试不同步的问题。五、实战如何向 acceptance.json 新增一个测试套件综合上述机制在 Oppia 仓库中让一个新写的 Acceptance 测试进入 CI需要完成以下步骤编写测试脚本在 core/tests/puppeteer-acceptance-tests/specs 或 core/tests/playwright-acceptance-tests/specs 下按「角色/业务场景」的目录结构创建*.spec.ts文件例如logged-out-user/my-new-scenario.spec.ts。登记到配置编辑 core/tests/ci-test-suite-configs/acceptance.json在suites数组中追加一条记录三个字段缺一不可{ name: logged-out-user/my-new-scenario, module: core/tests/puppeteer-acceptance-tests/specs/logged-out-user/my-new-scenario.spec.ts, framework: puppeteer }name必须与 spec 文件相对路径去掉.spec.ts后缀后的字符串完全一致这是check_tests_are_captured_in_ci.py做差集匹配的依据module必须是相对仓库根目录的完整路径check_ci_test_suites_to_run.py 会用它把套件拆分为acceptance/acceptance_playwright两组framework视脚本所在目录填写puppeteer或playwright它决定了run_acceptance_tests.py走哪条启动路径。本地验证先运行python -m scripts.check_tests_are_captured_in_ci确认无差集再执行python -m scripts.run_acceptance_tests --suite logged-out-user/my-new-scenario可加--headless --mobile覆盖两种视口本地跑通。提交并依赖 CI 自动调度push 后acceptance_coveragejob 会先验证同步性随后check_test_suites_to_run会把这个新套件放入TEST_SUITES_TO_RUN的acceptance.suites列表最终acceptance_test的 matrix 会为它展开桌面端 移动端两个执行实例。六、配置与迁移工作的若干工程细节从源码中可以提炼出几条与这份配置相关的工程信息framework 字段的临时性framework字段的设计目的check_tests_are_captured_in_ci.py是在 Puppeteer → Playwright 迁移期间区分两类套件源码中的TODO(#24715)与TODO(#26264)均指向该迁移进程。因此当你在acceptance.json中看到同一业务场景同时存在两个 framework 的套件时这是迁移过渡期的正常形态。配置变更会触发本地钩子由于 pre_push_hook.py 对ci-test-suite-configs/.*\.json敏感任何对acceptance.json的修改都会让 pre-push 钩子执行相关检查。测试类型配置目录是开放扩展点README 将目录定位为「不同测试类型的配置集中地」意味着acceptance.json的模式可以复制用于其他测试类型如 README 提到的 E2E。统一的 JSON 结构suitesname/module/framework与 check_ci_test_suites_to_run.py 的通用读取函数使新增测试类型的配置成本很低。目录归属的协作约定从 .github/CODEOWNERS 可以看到puppeteer-acceptance-tests、playwright-acceptance-tests、test-modules-mappings/acceptance以及run_acceptance_tests.py相关文件统一由oppia/acceptance-test-reviewers团队负责 review这也意味着改动acceptance.json时该团队是默认的评审方。七、小结core/tests/ci-test-suite-configs/acceptance.json是 Oppia CI 全栈测试体系的「注册表」它以name module framework三个字段描述每一个 Acceptance 测试套件向下被 scripts/run_acceptance_tests.py 用于按框架分流执行向上被 scripts/check_ci_test_suites_to_run.py 用于计算 CI 矩阵同时还受到 scripts/check_tests_are_captured_in_ci.py 的差集校验保护。理解了这份配置的结构与其背后的调用链开发者就能准确地为 Oppia 新增、修改或迁移 Acceptance 测试套件并确保它们稳定地进入 CI 执行与质量门禁。延伸阅读仓库内配置目录core/tests/ci-test-suite-configs套件执行器scripts/run_acceptance_tests.pyCI 分发计算scripts/check_ci_test_suites_to_run.py同步校验脚本scripts/check_tests_are_captured_in_ci.pyCI 工作流.github/workflows/full_stack_tests.yml单套件运行 Action.github/actions/run-a-specific-acceptance-test/action.yml赞分享教育后端前端【免费下载链接】oppiaA free, online learning platform to make quality education accessible for all.项目地址https://gitcode.com/gh_mirrors/op/oppia点击查看免费下载相关推荐SGLang 注册式测试体系Registered Tests完全指南目录规划、CI 注册与 run_suite.py 运行机制SGLang 注册式测试体系Registered Tests完全指南目录规划、CI 注册与 run_suite.py 运行机制 导读 本文基于 SGLan模型推理服务推理引擎人工智能大模型本地部署多模态SGLang 测试与 CI 体系实战指南套件结构、测试注册与本地运行SGLang 测试与 CI 体系实战指南套件结构、测试注册与本地运行 本文是 SGLang 仓库 test/README.md https://link.gi模型推理服务推理引擎人工智能大模型本地部署多模态DGL 基准回归测试套件Regression Test Suite全解析task.json 配置、环境变量与 ASV 运行机制DGL 基准回归测试套件Regression Test Suite全解析task.json 配置、环境变量与 ASV 运行机制 本篇文章以 DGL 仓库中人工智能机器学习深度学习图计算创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

iPhoneMirror协议原理:QuickTime私有USB Screen Capture协议逆向解析(H.264/HEVC全链路)

iPhoneMirror协议原理:QuickTime私有USB Screen Capture协议逆向解析(H.264/HEVC全链路)

【免费下载链接】iPhoneMirror Local Windows iPhone/iPad mirroring over USB and AirPlay with D3D11 preview, multi-device sessions, OBS output, and a standalone driver manager. 项目地址: https://gitcode.com/gh_mirrors/ip/iPhoneMirror 点击查看 免费下…

2026/10/16 19:40:28 阅读更多 →
cangjie_stdx 字符串池化缓存指南:使用 string_intern 的 intern 机制降低临时字符串内存开销

cangjie_stdx 字符串池化缓存指南:使用 string_intern 的 intern 机制降低临时字符串内存开销

标准库网络密码学并发编程 【免费下载链接】cangjie_stdx 仓颉编程语言提供了 stdx 模块,该模块提供了网络、安全等领域的通用能力。 项目地址: https://gitcode.com/Cangjie/cangjie_stdx 点击查看 免费下载 导读 string_intern 是仓颉标准扩展库&…

2026/10/15 18:01:15 阅读更多 →
用JavaScript打造可扩展的LIMS:从数据建模到报告生成的完整实践

用JavaScript打造可扩展的LIMS:从数据建模到报告生成的完整实践

简介:实验室信息管理系统(LIMS)是一套以JavaScript为主要技术栈的开源项目源码,面向实验室信息化建设者、Web前端/后端开发人员及质量管理相关从业者。压缩包为zip格式,整体大小52.49MB,包内文件总数暂未单…

2026/10/15 18:01:15 阅读更多 →

最新新闻

惯性导航解算算法实现:从IMU数据到ECEF位置的六步闭环

惯性导航解算算法实现:从IMU数据到ECEF位置的六步闭环

简介:本资源是一套完整的惯性导航解算算法实现工程,面向导航制导、智能无人系统、机器人定位等方向的本科生、研究生及嵌入式开发者,聚焦于INS核心姿态解算、加速度积分与卡尔曼滤波校正等关键环节,解决无GPS环境下自主定位与姿态…

2026/10/17 0:31:59 阅读更多 →
Kube-OVN 安装避坑指南:内核适配、网卡识别与版本兼容三重校验

Kube-OVN 安装避坑指南:内核适配、网卡识别与版本兼容三重校验

简介:本资源是一份面向Kubernetes运维工程师、云原生网络架构师及容器平台开发者的Kube-OVN深度技术文档,系统解析这一CNCF沙盒项目的网络设计哲学与工程实践。文档覆盖其三大核心优势:依托OVN/OVS实现的子网管理、VPC多租户、跨集群互联等丰…

2026/10/17 0:31:59 阅读更多 →
35岁后端转大模型:从零到求职的全路径实战规划

35岁后端转大模型:从零到求职的全路径实战规划

最近有个老同事约我吃饭,聊到一个特别现实的问题:35岁,传统后端开发干了十来年,薪资到顶,业务需求也在收缩,要不要all in大模型?他说自己把网上关于“35岁程序员转行大模型”的文章翻了个遍&…

2026/10/17 0:30:58 阅读更多 →
用户画像构建实战:从标签体系设计到计算存储的完整方案

用户画像构建实战:从标签体系设计到计算存储的完整方案

1. 用户画像构建的整体思路与方案选型用户画像这个词,这几年被提得很多,但真正落地做过的团队都知道,它不是一个“建张表、打几个标签”就完事的活儿。我前后参与过三个不同量级的画像项目,从早期几十万用户的小型推荐系统&#x…

2026/10/17 0:30:58 阅读更多 →
AI工具平权时代,真正拉开差距的是这四种稀缺能力

AI工具平权时代,真正拉开差距的是这四种稀缺能力

最近一段时间,我身边几乎所有人都在讨论AI工具。聊天群里天天有人分享新出的提示词,短视频上不断刷到"三分钟用AI做出爆款",公司内部更夸张,连搞行政的同事都在用AI写周报。一个很现实的问题摆在每个人面前:…

2026/10/17 0:30:58 阅读更多 →
2020春招后端与算法岗面试全攻略:线上笔试、手撕代码与项目深挖

2020春招后端与算法岗面试全攻略:线上笔试、手撕代码与项目深挖

2020年刚开年那阵子,身边准备春招的朋友普遍都有个感受:往年学长学姐留下的面经套路,突然就失效了。线下宣讲、现场笔试、群面大战这些经典环节被彻底重排,大部分流程都搬到了线上,一轮接一轮的视频面、电话面&#xf…

2026/10/17 0:30:58 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →