Cucumber测试报告实战:从Gherkin到CI/CD的完整避坑指南
做自动化测试这么多年我经手最多的就是Cucumber测试报告。很多人跑完一条用例看到控制台飘出一屏幕绿色就觉得万事大吉可真走到CI流水线、走回归、走验收评审的时候报告要么差字段要么打不开要么失败场景根本看不出业务含义。这篇内容我就把从原始Gherkin到正规测试报告的完整链路第三方报告框架怎么选以及流水线集成中踩过的坑一次性整理清楚给正在跟Cucumber报告较劲的人做个参照。1. 先想清楚Cucumber测试报告到底要回答哪些问题1.1 为什么JMeter式报告解决不了BDD的报表需求先说个直觉。很多人最初做接口性能或功能测试用的工具是JMeter比如我在JMeter 5.6.3上生成测试报告时那个HTML报告确实漂亮响应时间曲线、吞吐量、错误率全都有点开每一项都能看到采样数据。于是切到Cucumber以后第一反应是照搬那套思路恨不得Cucumber报告也做出一堆图表。但这里有个明显的错位JMeter报告回答的是“系统扛不扛得住、接口慢不慢”而Cucumber是行为驱动开发的执行器它最该回答的是“业务规则有没有被满足、哪一条验收条件挂了、挂在哪一步”。JMeter那张报告里全是聚合指标而Cucumber测试报告的核心单元是Feature、Scenario、Step粒度根本不一样。举个例子。一个登录功能JMeter报告告诉你登录接口99%请求都在200毫秒内返回看起来“测试报告”很完美但Cucumber的场景会告诉你“当普通用户输入正确账号密码时应该跳转到首页”这条业务规则没通过因为页面断言等了10秒超时。这条信息在JMeter聚合报告里会被埋掉在BDD报告里却必须醒目地出现在第一屏。所以我后来做Cucumber测试报告第一件事就是把报告目标重新定义不能光追求图表华丽先确保每个业务场景的可追溯性。1.2 一份合格的Cucumber报告应该包含哪些内容基于我在多个项目里总结的经验一份能直接拿去跟产品、开发对线的Cucumber测试报告至少应该包含下面几类信息信息类别具体内容为什么重要执行概况测试总时长、Feature总数、Scenario总数、步骤总数让管理层快速看到回归体量结果统计通过的Scenario数、失败的Scenario数、跳过数、重试后通过数判断功能质量是否可发布失败详情失败的Step原始报错信息、堆栈、所在代码文件行号开发不用重新翻日志业务场景上下文对应Feature文件的描述、Scenario名称、Tag保证每条失败都能追溯到需求环境信息执行机、浏览器/调用端信息、配置参数、版本复现问题时少走弯路附件证据失败截图、网络抓包、接口响应体让报告自己会说话有的团队还喜欢在报告里带上代码覆盖率这个如果覆盖工具顺手可以加到单独一栏但不是Cucumber测试报告的必需品。报告字段不是越多越好而是要让阅读者在30秒内定位到“哪里挂了、影响哪条业务流程、为什么挂”。我自己在项目里实际用的做法是报告页面上首屏永远是失败列表通过的内容折叠起来否则几十个Passed场景会把失败信息挤到第N屏评审会上打开报告大家第一眼根本看不清问题。2. Feature到Step的链路报告数据是从哪儿来的2.1 一条Gherkin场景是怎么变成报告行的要搞定Cucumber测试报告必须先理解报告数据在上游是怎么产生的。Cucumber执行时先读取Feature文件解析出Feature、Scenario、Step这些元素然后交给Runtime执行。每执行完一个Step工具会根据执行结果产生事件比如测试步骤开始、测试步骤结束。这些事件不是空壳里面带着大量上下文信息。拿Java生态的cucumber-jvm来说Step结束后产生的事件里包含步骤定义匹配情况、参数类型转换结果、执行的耗时、抛出的异常这些数据最终被格式化器接收才能转变成JSON、HTML、XML等报告。测试报告不是执行完以后变魔术一样出来的而是整个执行过程的事件流被记录下来再经过格式化器二次加工。理解了这一点后续很多排查方向就清晰了报告缺少某条场景通常是事件没有完整写入报告Step数据对不上通常是格式化器订阅的事件类型选择不对。2.2 Step状态和时间耗时到底怎么统计Cucumber的Step状态主要有以下几个Passed、Failed、Skipped、Undefined、Pending、Ambiguous。很多新手看到Skipped和Undefined会慌其实这不是工具坏了而是执行逻辑本身就这么设计的。比如一个Background里有Step失败了后面的Step不会继续执行会被标记为Skipped报告里仍然保留这些步骤便于观察失败的影响范围。时间耗时的统计Cucumber记录的是从Step开始到Step结束的毫秒数但这个时间受到Hook、重试、等待条件的影响。我遇到过一种情况某个Step里内置了30秒轮询等待最后结果是通过的可报告里面这个Step耗时就特别夸张。如果只看Scenario总耗时会误以为整个用例很慢。所以我在做报告汇总时会对步骤耗时做两层记录原始耗时和纯业务耗时。做法是在Hook里记录Step开始时间在Step执行结束后取差值排除等待条件后单独存一份业务耗时。报告里两个耗时对着看能快速判断性能瓶颈是轮询策略问题还是接口本身慢。这两个耗时字段在默认的Cucumber HTML报告里其实没有需要自己做事件监听或者写后置处理脚本但值得做。2.3 Hook和附件是怎么进入报告数据的Cucumber的Hook——Before、After、Around等——会在特定时机执行它们既能操作测试上下文也能往报告里塞数据。最常见的是AfterStep或AfterScenario里判断当前场景失败时截屏把截图通过attach接口挂到当前Step或Scenario的结果里。我最初的误区是以为截图只要保存到文件、把路径输出到控制台就算进了报告。实际上很多报告框架不吃文件路径它需要你主动把附件作为消息推送比如cucumber-jvm里的embed或者attach方法传入字节流、媒体类型和标题。如果你用Allure框架就得调用Allure的addAttachment。这个差异就是为什么很多人明明截了图报告里却看不到图片。另外要注意Hook抛异常的问题。我在项目里就遇到过一次AfterScenario的截图代码本身报错直接把整个Scenario的最终结果从Passed改成了Failed报告统计瞬间多了一批莫须有的失败。排查了半天才意识到不是业务代码问题。所以Hook代码一定要做异常隔离尽量在Hook内部catch住保证报告数据不被附带问题污染。3. 报告形态选型原生HTML、JSON、Allure还是Cucumber Reports3.1 先搞懂原生报告的几种输出方式Cucumber官方生态提供了几种报告输出方式我挑常用的说一下。控制台输出最原始默认的pretty/plugin输出直接看执行过程但不适合作为报告对外展示。JSON/NDJSON输出通过--format json:target/cucumber.json这类参数导出结构化数据这是后续一切报告处理的基础。HTML输出通过cucumber-html-formatter生成官方风格信息全、颜值一般胜在零依赖。Messages协议输出也就是message格式是Cucumber标准化的事件流格式可以接入官方Report Service或其他处理端。在Java项目中我常用的是在junit-platform.properties或者运行器配置里加上cucumber.pluginpretty, json:target/cucumber.json, html:target/cucumber-report.html注意多个插件用逗号分隔目标文件路径要确保目录存在否则某些版本会直接报错。如果只指定json输出却把目录路径写错报告文件根本不会生成但执行本身还是绿杠杠一片特别迷惑。3.2 第三方报告框架怎么选Allure和Cucumber Reports的取舍我实际对比过三类方案简单列成表格。方案优点缺点适合场景官方HTML零额外依赖、升级快、跟Gherkin语义最贴合默认无失败分类、无历史趋势、检索弱小团队快速验证Allure界面现代、历史趋势、环境信息、附件管理强需要额外装allure-commandlineJava/其他语言要引入适配依赖中型以上团队日常回归Cucumber Reports开源插件统计功能强、可多份报告合并旧项目需要维护格式、与新版本Cucumber兼容有延迟已有社区持续集成的老项目我现在的平衡做法是日常开发用官方HTML发布前和迭代验收用Allure。核心原因是Allure的报告结构对Product和Leader更友好按特性维度聚合能看到“本次回归哪个模块失败数量最多”还自带Retries标签能把重试的成功和原始失败分开显示。Cucumber官方HTML在这块差一点它把重试情况混在Scenario列表里不加额外处理很难一眼看出真实成功率。3.3 我的一套可行配置JSON做中间态报告自己渲染不管用哪个前端展示我建议都保留一份JSON中间产物。好处有两个第一JSON是标准结构一旦原报告框架升级导致兼容性问题我们随时可以写脚本读JSON生成自己的HTML不至于被框架绑架第二JSON可以直接喂给数据统计脚本后面做通过率趋势图、失败步骤排行都用得上。实际项目中我用的Java集成方案大概是这种模式RunWith(Cucumber.class) CucumberOptions( features src/test/resources/features, glue com.example.steps, plugin { pretty, json:target/cucumber.json, html:target/cucumber-html-report.html, io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm }, tags Regression ) public class CucumberRegressionRunner { }注意Allure的插件类名会随着Cucumber主版本号不同而变化确实很容易配错常见的是Allure CucumberJVM的包名带了版本后缀。配好以后跑完测试执行一次allure generate target/allure-results --clean -o target/allure-report就能在target/allure-report下看到完整报告。4. CI/CD集成把报告真正变成团队看板4.1 在GitLab CI流水线里生成并部署报告报告如果只躺在本地target目录基本等于没做。我习惯在合并请求和每日回归流水线里都加上报告生成和归档这一步。以GitLab CI为例我的做法是在.gitlab-ci.yml里增加一个测试报告阶段stages: - test - report test: stage: test script: - mvn test -Dcucumber.filter.tagsRegression artifacts: paths: - target/cucumber.json - target/cucumber-html-report.html - target/allure-results when: always expire_in: 7 days report: stage: report script: - npm install -g allure-commandline - allure generate target/allure-results --clean -o public/allure-report - cp target/cucumber-html-report.html public/index.html artifacts: paths: - public when: always expire_in: 14 days这里有几个关键点。第一测试任务的artifacts设置when: always即便有失败用例也要把报告文件保存下来否则流水线中断后报告也跟着丢了。第二把两个阶段的产物分开测试和数据准备归测试任务HTML渲染归报告任务解耦以后报告框架升级不用重新跑一遍用例省非常多时间。第三报告产物里我会把JSON、截图、日志一起放进去因为对外发布的页面如果需要关联失败附件直接从同一个artifacts目录取路径就好。早期我曾把报告生成放在测试同一个Job里节省了一个Stage但后来发现只要测试运行器环境缺了Allure节点整个测试过程也被牵连。所以现在宁可多开一个阶段也不为省执行时间牺牲稳定性。4.2 失败截图和日志挂到报告的实操细节在CI里挂载截图核心还是用附件API。Java生态里我常用的是在AfterStep或AfterScenario中判断失败后截屏通过Allure接口挂进去。举个例子After public void takeScreenshotIfFailed(Scenario scenario) { if (scenario.isFailed()) { byte[] screenshot takeScreenshot(); Allure.addAttachment(失败截图- scenario.getName(), image/png, new ByteArrayInputStream(screenshot), .png); } }这里还要考虑一个并发问题并行执行时多个Hook同时在截图如果用的截图工具本身不是线程安全的会出现截图错乱甚至进程崩溃。我踩过一次同一份截屏方法在10个线程里跑偶发报错最后排查是截图驱动状态被并发覆盖。后来我对截图工具加了全局锁或者通过ThreadLocal存储当前线程的驱动实例问题才彻底解决。日志挂载比截图简单主要是把失败Step的堆栈、请求响应体、当前环境配置以文本附件形式加进报告。我做了个统一方法把每个HTTP请求的方法、URL、请求头、请求体、响应状态码、响应体在断言失败时拼成文本通过Allure.addAttachment挂到对应Step。有了这层数据线上跟开发对问题的时候基本不用再让他翻代码找日志。4.3 并发执行下多份报告的合并Cucumber跑并行用例时每个并行流默认会生成独立的报告文件如果不处理最后要么只看到最后一份要么文件被互相覆盖。我第一次用cucumber.junit.platform.execution.parallel.enabledtrue跑并行的时候就发现JSON报告里Scenario数量比实际少了一大截原因就是多个线程往同一个cucumber.json里写。解决方案通常有两个。一是在并行场景下让每个线程输出独立文件比如通过--format json:target/cucumber-%thread.json的方式跑完后合并二是直接采用Cucumber内置的合并能力某些版本支持多个结果文件合并但效果有限。Allure在这点做得比较好因为Allure结果是以单个UUID命名的文件落到allure-results目录天然支持并行写入最后用allure generate汇总就行。这也是我在并发回归项目里更倾向Allure的原因之一不需要干预合并逻辑生成命令直接处理。如果非要合并官方JSON我写过小工具脚本逻辑就是解析每个JSON的elements字段按Feature文件名归类再把Step数据逐个合并最后重新算统计字段。说实话做过一次就够了能不用手写合并就尽量别写。5. 我在真实项目里踩过的报告坑5.1 中文乱码报告里全是问号这个坑很典型Windows和Linux混跑的项目特别容易中招。Feature文件里写了中文步骤本地跑报告显示正常推到Linux服务器上生成的HTML里全是“”或者方块。排查链路是这样的先用file命令看Feature文件的编码发现是UTF-8再看运行时的默认字符编码发现CI镜像里LANGCJVM默认用了ISO-8859-1读取Feature文件中文自然全烂。解决办法是在运行命令或构建配置里显式指定编码export JAVA_TOOL_OPTIONS-Dfile.encodingUTF-8或者在运行类里加一句System.setProperty(file.encoding, UTF-8)但注意这个只对进程内的后续操作有效最稳妥还是确保环境变量和编译配置一致。处理完以后HTML报告和Allure报告的中文都正常了。5.2 Hook里抛出来的“幽灵失败”我在前面提到过AfterScenario的截图代码本身报错会带偏测试结果。这个坑在报告数据上还有一个隐蔽版本BeforeHook里做了数据准备如果准备失败工具会跳过整个Scenario并标记为失败。但从报告上看失败信息里面根本没有业务Step只有Hook堆栈。不懂的人会以为业务代码cover掉了所有场景。我的排查思路是先把报告里失败项按堆栈来源分组。凡是堆栈顶部能匹配到hook包或Before注解类基本可以判定是准备阶段问题不是业务断言问题。然后再去看Hook代码把环境准备逻辑包起来失败了只打印告警并标记当前环境状态让Scenario继续执行最后在报告里加一个“环境准备”字段标注当前状态。5.3 重试机制让报告统计失真重试是一个特别容易引起统计争议的点。测试脚本里配置了失败重试比如retry 2第一次执行失败的Scenario重试成功了报告里怎么展示默认Cucumber HTML会把多次执行都记录在Scenario执行历史里不做“第一次失败、重试成功”的显式区分。对测试执行者来说是好事但对发布评审来说他们会看到10个失败、但有1个实际已经通过统计口径就被搅浑了。我现在的做法是双维度记录。Allure本身有Retries视图能清晰区分原始失败和重试成功这是选择Allure的一个加分项。如果必须在官方HTML里处理我会在生成报告前跑一段脚本把Scenario中最后一次执行的Result作为最终结果前面的执行记为“重试尝试”统计时分开算。这样报告上第一页的失败数永远是发布真正要关注的净失败数。5.4 时间字段和时区报告汇总的偏差报告执行时间如果只看本地墙钟时间跨时区协作时会出现很奇怪的“今天早上回归的报告时间戳却是昨天下午”。Cucumber生成的JSON里时间戳默认是UTC或本地时间取决于配置但AREA不同展示端如果不做时区转换图上时间轴会和真实执行时间错位。我在做统计脚本时统一按ISO 8601格式存时间并在渲染时标注时区。实际加到CI里以后我在环境变量里固定了TZAsia/Shanghai确保所有执行机生成报告的时间口径一致。这一步虽然不起眼但团队跨时区协作的时候报告上的时间对得上了扯皮少了一多半。6. 把报告当成产品做我沉淀下来的一套检查清单最后分享一个自己沉淀的收尾习惯。每次发一份Cucumber测试报告出去之前我都会套一遍检查清单简单但实用。第一报告首屏必须能回答“这轮测试到底过没过”。不是看百分比而是看发布维度的结论。我会在报告封面留一行结论区人工或脚本写入“允许发布”或“存在阻断缺陷”这一行字比所有图表都重要。第二失败项必须全部有归类。是环境问题、数据问题、脚本问题还是真实业务缺陷每一条失败都打上标签开会时一拉标签就能看出问题集中在哪一块。第三报告附件必须能在新环境打开验证。截图、日志、JSON都放进artifacts统一目录并且路径尽量用相对路径否则CI产物换个存储路径报告里的附件全破图。我在实际项目里最大的体会是Cucumber测试报告不是测试结束后才想的事而是在写Feature、设计Step、注册Hook的那一刻就要同步考虑。你往报告里塞什么附件、用什么格式输出、在哪一步截屏这些决定都比最后敲一行生成命令影响大得多。把这一套跑熟了报告就不再是发完即弃的存档文件而是团队每天都会打开、能直接指导修复优先级的工作台。

相关新闻

大模型工具调用实战:WorkMate内置工具包从设计到落地复盘

大模型工具调用实战:WorkMate内置工具包从设计到落地复盘

做 AI 应用这一年多,我最大的感受是:模型本身的能力早就不是瓶颈,真正拉开差距的,是它“够得着”什么。WorkMate 这个内部助手项目刚起步时,我们只给它接了两三个 API,结果它就像一个刚入职但双手被绑住的新…

2026/10/12 19:49:04 阅读更多 →
2026年亲测AI论文平台榜单(合规高效版):把Base URL改到TaoToken的实测记录

2026年亲测AI论文平台榜单(合规高效版):把Base URL改到TaoToken的实测记录

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

2026/10/13 22:03:52 阅读更多 →
AI原生全栈开发训练营:从写代码到编排AI的实战指南

AI原生全栈开发训练营:从写代码到编排AI的实战指南

最近总有人问我:AI时代还要不要学全栈开发?我的回答很直接——要学,但不能再用原来那套学法。我自己做了好几年传统前后端,后来把AI能力嵌进产品,也在带一个叫“AI原生超级全栈开发工程师训练营”的项目。这个训练营的…

2026/10/13 22:03:55 阅读更多 →

最新新闻

Python Plotly交互式数据可视化:从快速出图到精细定制

Python Plotly交互式数据可视化:从快速出图到精细定制

做数据分析的同学都有一个共同感受:数据算完之后,最头疼的不是处理逻辑,而是怎么把结果变成一张别人一眼能看懂的图。这两年我用得最顺手的工具就是 Plotly,一个典型的 Python 交互式绘图库。用 Plotly 创建交互式图表&#xff0c…

2026/10/13 22:03:47 阅读更多 →
基于Spring Boot和Vue的电影订票管理系统全栈项目

基于Spring Boot和Vue的电影订票管理系统全栈项目

每年做课程设计或者毕业设计的季节,总有人问我"有没有一个既能体现技术栈又不算太复杂、最好还带完整界面的项目"。老实说,这类需求里出镜率最高的就是各种"管理系统",而其中电影订票管理系统又是一直没凉过的经典选题。…

2026/10/13 22:03:47 阅读更多 →
机器学习集成学习实战:三大流派与工程应用

机器学习集成学习实战:三大流派与工程应用

集成学习这几年在机器学习面试和实际工程里都是绕不开的东西。不管你是刚开始学模型,还是已经在跑实验,迟早会遇到一个问题:单个模型的效果到了瓶颈,怎么再往上提一点?很多人第一反应是换更复杂的模型,但更…

2026/10/13 22:03:47 阅读更多 →
WEKA数据挖掘入门:从ARFF格式到J48决策树与交叉验证实战

WEKA数据挖掘入门:从ARFF格式到J48决策树与交叉验证实战

简介:一份面向数据挖掘初学者与课程学习者的WEKA中文详细教程PPT,围绕怀卡托智能分析环境(WEKA)的开源特性、获得ACM SIGKDD奖项的里程碑地位及常见应用场景展开,适合作为高校数据挖掘、机器学习课程的配套讲义或自学入…

2026/10/13 22:03:47 阅读更多 →
支付系统设计与落地:状态机、幂等、对账与避坑指南

支付系统设计与落地:状态机、幂等、对账与避坑指南

线下业务上线支付系统的那段时间,几乎每天都要和数据、异常单、渠道对账单较劲。当时踩过的坑、重构过的状态机、跟渠道商务来回确认的限额规则,后来都沉淀成了这套经验。今天不聊架构图,也不念文档,就实打实拆一下“支付系统”从…

2026/10/13 22:03:47 阅读更多 →
同花顺日线文件解析:从二进制乱码到可回测的OHLCV表

同花顺日线文件解析:从二进制乱码到可回测的OHLCV表

简介:这份资源面向金融数据分析初学者与量化爱好者,聚焦同花顺日线二进制文件(.day)的解析问题。压缩包仅4KB,内含2个文件:一个以600000为代码的日线样本文件,以及一份约20行的Python解析脚本&a…

2026/10/13 22:02:46 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →