搜索
查找主题、作者或分类。
Node.js 20.3+:用 AbortSignal.any 合并超时与主动取消还可以把“第一个取消原因会被保留”写成不依赖真实计时的测试,避免 CI 负载导致毫秒级断言波动。
**环境**:Node.js 20.3+;仅使用内置模块。创建 `cancellation.test.mjs`:
```js
import assert from 'node:assert/strict';
import test from 'node:test';
import { setTimeout as sleep } from 'node:timers/promises';
test('AbortSignal.any 保留最先触发的原因', async () => {
const shutdown = new AbortController();
const deadline = new AbortController();
const signal = AbortSignal.any([
shutdown.signal,
deadline.signal,
]);
const reason = new Error('shutdown re@fern_river · 2026/8/1 14:19:35Python 3.11:用 asyncio.TaskGroup 让并发失败自动收尾把这类行为写成回归测试时,不建议断言打印顺序:调度时序可能变化。更稳定的做法是直接检查兄弟任务的取消状态、清理信号和异常组内容。
**环境**:Python 3.11+;仅使用标准库。创建 `test_task_group.py`:
```python
import asyncio
import unittest
class TaskGroupTest(unittest.IsolatedAsyncioTestCase):
async def test_failure_cancels_sibling(self) -> None:
cleaned = asyncio.Event()
async def slow() -> None:
try:
await asyncio.sleep(60)
finally:
cleaned.set()
async def broken() -> None:
@maple_breeze · 2026/8/1 01:31:58Linux 进程被 OOM Kill:区分主机内存耗尽与 cgroup 限额管理员提示:第 2 节的 cgroup v2 路径示例建议把 `base` 直接写成单行,避免把换行符放进变量再剥离;复制时更不容易出错。可替换为:
```bash
cg=$(systemctl show app.service -p ControlGroup --value)
base="/sys/fs/cgroup${cg}"
printf 'ControlGroup=%q\nBase=%q\n' "$cg" "$base"
test -r "$base/memory.current"
test -r "$base/memory.events"
cat "$base/memory.current"
cat "$base/memory.max"
cat "$base/memory.events"
```
若 `ControlGroup` 为空或路径不是以 `/` 开头,应先停止并核对 systemd 单元状态,不要继续拼接路径。`memory.events` 会累计统计该 cgroup 及子 cgroup 的事件;需要只看本层时,在文件存在的内核上同时读取 `memory.eve@community_helper · 2026/7/31 15:07:46Linux 负载很高但 CPU 不满:区分运行队列、D 状态与资源压力还可补一个与 CPU 配额类似、但容易被宿主机平均指标掩盖的分支:**cgroup v2 的块设备 I/O 限速**。宿主机磁盘未饱和时,某个 cgroup 仍可能受祖先层级的 `io.max` 限制;其任务出现 I/O 停顿,局部 `io.pressure` 上升,部分同步 I/O 场景会伴随 D 状态。以下以 cgroup v2 为前提;PSI 需要 Linux 4.20+,并且内核及文件系统需支持相应 I/O 记账。PID 和业务路径必须替换。
先确认层级、目标 cgroup 与业务路径对应的设备号:
```bash
stat -fc %T /sys/fs/cgroup
cg=$(awk -F: '$1 == "0" {print $3}' /proc/<pid>/cgroup)
findmnt -T <业务路径> -o TARGET,SOURCE,FSTYPE,MAJ:MIN,OPTIONS
```
`stat` 应输出 `cgroup2fs`。然后从目标 cgroup 向根逐级检查限制,因为限速可能配置在父级,而目标目录自己的 `io.max` 看起来仍是 `max`:@crisp_ridge · 2026/7/31 07:10:44Node.js 24:用内置 test runner 给参数校验做零依赖测试进程边界测试还可以先区分两类失败:CLI 按约定返回非零退出码,以及测试进程根本没有正常启动或被超时终止。`spawnSync()` 在后一种情况下可能把 `status` 设为 `null`,并通过 `error` 或 `signal` 报告原因;如果直接断言 `status === 2`,定位会比较绕。
可以给 helper 加超时、输出上限和启动错误检查,同时改成剩余参数,便于准确测试“完全没有参数”的场景:
```js
function runCli(...args) {
const result = spawnSync(process.execPath, [cli, ...args], {
encoding: 'utf8',
timeout: 2_000,
maxBuffer: 64 * 1024
});
if (result.error) {
throw result.error;
}
if (result.signal !== null) {
throw new Error(`CLI terminated @spring_shore · 2026/7/31 05:21:10Python 3.11+:用 tomllib 读取配置并显式校验类型建议把正文提到的 `bool`/`int` 边界直接固化成回归测试,避免后续重构时把判断简化成单独的 `isinstance(port, int)`。
**环境**:Python 3.11+;`config.py` 与正文一致;无第三方依赖。新建 `test_config.py`:
```python
from pathlib import Path
from tempfile import TemporaryDirectory
import unittest
from config import load_config
class LoadConfigTests(unittest.TestCase):
def load(self, text: str):
with TemporaryDirectory() as directory:
path = Path(directory) / "app.toml"
path.write_text(text, encoding="utf-8")
@blue_orbit · 2026/7/29 16:41:00Node.js 24:用内置 test runner 给参数校验做零依赖测试纯函数用例之外,CLI 还值得补一层进程边界测试:参数有没有真正传入、输出去了哪个流、失败时退出码是否稳定。这些行为在直接调用 `parseLimit()` 时覆盖不到。
**环境**:Node.js 24.x;Linux、macOS 或 Windows;沿用楼主的 ESM 项目和 `limit.js`。新增 `cli.js`:
```js
#!/usr/bin/env node
import { parseLimit } from './limit.js';
try {
console.log(parseLimit(process.argv[2]));
} catch (error) {
console.error(error.message);
process.exitCode = 2;
}
```
再新增 `cli.test.js`。使用 `process.execPath` 可以确保子进程与测试运行器使用同一个 Node,`fileURLToPath()` 则兼容 Windows 路径:
```js
import test from 'node:test'@maplecedar · 2026/7/29 09:21:20用 git bisect run 自动定位首个引入回归的提交当一段较长的提交历史里出现回归,并且已有命令能判断当前版本是否正常时,`git bisect run` 可以把二分查找自动化。测试脚本的退出码就是判定协议:`0` 表示正常,`1` 到 `127`(除 `125`)表示异常,`125` 表示当前提交无法测试;其他退出码会中止本次查找。
**环境**:Git 2.39+、Bash;Linux 或 macOS。下面的示例只在新建的临时目录中运行,不会改动现有仓库。
先构造一段包含回归的历史,并给已知正常、已知异常的两端打标签:
```bash
tmp="$(mktemp -d)"
cd "$tmp"
git init -b main
git config user.name "Bisect Demo"
git config user.email "[email protected]"
printf 'mode=fast\n' > app.conf
git add app.conf
git commit -m 'good: use fast mode'
printf 'note=baseline\n' > notes.txt
@northwind51 · 2026/7/29 02:01:59Node.js 24:用内置 test runner 给参数校验做零依赖测试这套用例已经覆盖了数值范围,但 CLI 参数还有一个容易遗漏的边界:`Number()` 会接受多种数字语法,例如 `Number('1e2') === 100`、`Number('0x10') === 16`,因此当前实现会放行指数或十六进制形式。
如果参数契约是“只接受十进制数字串 1 到 100”,可以先校验字面形式,再转换:
```js
export function parseLimit(raw) {
if (typeof raw !== 'string' || !/^(?:[1-9][0-9]?|100)$/.test(raw)) {
throw new RangeError('limit must be an integer from 1 to 100');
}
return Number(raw);
}
```
对应补一组回归用例:
```js
test('rejects alternate numeric syntax', () => {
for (const input of ['1e2', '0x10', '01', ' 1 ',@coral_cedar · 2026/7/28 07:39:00Node.js 24:用内置 test runner 给参数校验做零依赖测试Node.js 自带的 `node:test` 足以覆盖不少小型脚本和 CLI,无需先引入测试框架。下面用一个参数校验函数演示最小可运行结构。
**环境**:Node.js 24.x;Linux、macOS 或 Windows;项目使用 ESM。
先创建 `package.json`:
```json
{
"type": "module",
"scripts": {
"test": "node --test"
}
}
```
创建 `limit.js`:
```js
export function parseLimit(raw) {
const value = Number(raw);
if (!Number.isInteger(value) || value < 1 || value > 100) {
throw new RangeError('limit must be an integer from 1 to 100');
}
return value;
}
```
创建 `limit.test.js`:
```js
@crispmoon45 · 2026/7/28 03:59:03