writing-dev-server-tests by oven-sh/bun
npx skills add https://github.com/oven-sh/bun --skill writing-dev-server-tests开发服务器测试用于验证热重载的健壮性和可靠性。
test/bake/bake-harness.ts - 共享工具函数:devTest、prodTest、devAndProductionTest、Dev 类、Client 类test/bake/client-fixture.mjs - Client 的子进程(页面加载、IPC 查询)test/bake/dev/*.test.ts - 开发服务器和热重载测试广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
test/bake/dev-and-prod.ts - 在开发和生产模式下运行的测试bundle.test.ts - DevServer 特定的打包错误css.test.ts - CSS 打包问题plugins.test.ts - 开发模式插件ecosystem.test.ts - 库兼容性(优先测试具体错误而非完整包测试)esm.test.ts - 开发中的 ESM 功能html.test.ts - HTML 文件处理react-spa.test.ts - React、react-refresh 转换、服务器组件sourcemap.test.ts - 源码映射正确性import { devTest, emptyHtmlFile } from "../bake-harness";
devTest("html file is watched", {
files: {
"index.html": emptyHtmlFile({
scripts: ["/script.ts"],
body: "<h1>Hello</h1>",
}),
"script.ts": `console.log("hello");`,
},
async test(dev) {
await dev.fetch("/").expect.toInclude("<h1>Hello</h1>");
await dev.patch("index.html", { find: "Hello", replace: "World" });
await dev.fetch("/").expect.toInclude("<h1>World</h1>");
await using c = await dev.client("/");
await c.expectMessage("hello");
await c.expectReload(async () => {
await dev.patch("index.html", { find: "World", replace: "Bar" });
});
await c.expectMessage("hello");
},
});
files : 初始文件系统状态dev.fetch() : HTTP 请求dev.client() : 打开浏览器实例dev.write/patch/delete : 文件系统变更(自动等待热重载)c.expectMessage() : 断言 console.log 输出c.expectReload() : 包装会导致硬重载的代码重要提示 : 使用 dev.write/patch/delete 而非 node:fs - 它们会等待热重载。
devTest("import then create", {
files: {
"index.html": `<!DOCTYPE html><html><head></head><body><script type="module" src="/script.ts"></script></body></html>`,
"script.ts": `import data from "./data"; console.log(data);`,
},
async test(dev) {
const c = await dev.client("/", {
errors: ['script.ts:1:18: error: Could not resolve: "./data"'],
});
await c.expectReload(async () => {
await dev.write("data.ts", "export default 'data';");
});
await c.expectMessage("data");
},
});
使用 errors 选项指定预期错误:
await dev.delete("other.ts", {
errors: ['index.ts:1:16: error: Could not resolve: "./other"'],
});
每周安装量
78
代码仓库
GitHub 星标数
88.6K
首次出现
2026年1月22日
安全审计
安装于
opencode74
codex72
gemini-cli71
cursor70
claude-code70
github-copilot67
Dev server tests validate hot-reloading robustness and reliability.
test/bake/bake-harness.ts - shared utilities: devTest, prodTest, devAndProductionTest, Dev class, Client classtest/bake/client-fixture.mjs - subprocess for Client (page loading, IPC queries)test/bake/dev/*.test.ts - dev server and hot reload teststest/bake/dev-and-prod.ts - tests running on both dev and production modebundle.test.ts - DevServer-specific bundling bugscss.test.ts - CSS bundling issuesplugins.test.ts - development mode pluginsecosystem.test.ts - library compatibility (prefer concrete bugs over full package tests)esm.test.ts - ESM features in developmenthtml.test.ts - HTML file handlingreact-spa.test.ts - React, react-refresh transform, server componentssourcemap.test.ts - source map correctnessimport { devTest, emptyHtmlFile } from "../bake-harness";
devTest("html file is watched", {
files: {
"index.html": emptyHtmlFile({
scripts: ["/script.ts"],
body: "<h1>Hello</h1>",
}),
"script.ts": `console.log("hello");`,
},
async test(dev) {
await dev.fetch("/").expect.toInclude("<h1>Hello</h1>");
await dev.patch("index.html", { find: "Hello", replace: "World" });
await dev.fetch("/").expect.toInclude("<h1>World</h1>");
await using c = await dev.client("/");
await c.expectMessage("hello");
await c.expectReload(async () => {
await dev.patch("index.html", { find: "World", replace: "Bar" });
});
await c.expectMessage("hello");
},
});
files : Initial filesystem statedev.fetch() : HTTP requestsdev.client() : Opens browser instancedev.write/patch/delete : Filesystem mutations (wait for hot-reload automatically)c.expectMessage() : Assert console.log outputc.expectReload() : Wrap code that causes hard reloadImportant : Use dev.write/patch/delete instead of node:fs - they wait for hot-reload.
devTest("import then create", {
files: {
"index.html": `<!DOCTYPE html><html><head></head><body><script type="module" src="/script.ts"></script></body></html>`,
"script.ts": `import data from "./data"; console.log(data);`,
},
async test(dev) {
const c = await dev.client("/", {
errors: ['script.ts:1:18: error: Could not resolve: "./data"'],
});
await c.expectReload(async () => {
await dev.write("data.ts", "export default 'data';");
});
await c.expectMessage("data");
},
});
Specify expected errors with the errors option:
await dev.delete("other.ts", {
errors: ['index.ts:1:16: error: Could not resolve: "./other"'],
});
Weekly Installs
78
Repository
GitHub Stars
88.6K
First Seen
Jan 22, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode74
codex72
gemini-cli71
cursor70
claude-code70
github-copilot67
Vue 3 调试指南:解决响应式、计算属性与监听器常见错误
11,900 周安装
Go依赖注入最佳实践:手动注入与库选择指南,提升代码可测试性与松耦合设计
685 周安装
Rust 所有权与生命周期指南:解决 E0382/E0597 等常见错误,优化内存管理设计
653 周安装
Chrome Bridge 自动化:Midscene 真实浏览器自动化工具,保留登录状态
657 周安装
Rust错误处理最佳实践指南:Result、Option、panic!与thiserror/anyhow使用技巧
663 周安装
iOS 17+ TipKit 框架使用指南:为 SwiftUI 应用添加功能提示与引导
676 周安装
Rust并发编程指南:Send/Sync、线程与异步编程最佳实践
671 周安装