教育后端前端【免费下载链接】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),仅供参考