test-writer
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSkill: Test Writer for Concept Pages
技能:概念页面测试用例编写器
Use this skill to generate comprehensive Vitest tests for all code examples in a concept documentation page. Tests verify that code examples in the documentation are accurate and work as described.
使用此技能为概念文档页面中的所有代码示例生成全面的Vitest测试。测试可验证文档中的代码示例是否准确且符合描述的运行效果。
When to Use
适用场景
- After writing a new concept page
- When adding new code examples to existing pages
- When updating existing code examples
- To verify documentation accuracy through automated tests
- Before publishing to ensure all examples work correctly
- 编写新的概念页面后
- 为现有页面添加新代码示例时
- 更新现有代码示例时
- 通过自动化测试验证文档准确性
- 发布前确保所有示例均可正常运行
Test Writing Methodology
测试用例编写方法
Follow these four phases to create comprehensive tests for a concept page.
遵循以下四个阶段为概念页面创建全面的测试。
Phase 1: Code Example Extraction
阶段1:代码示例提取
Scan the concept page for all code examples and categorize them:
| Category | Characteristics | Action |
|---|---|---|
| Testable | Has | Write tests |
| DOM-specific | Uses | Write DOM tests (separate file) |
| Error examples | Intentionally throws errors, demonstrates failures | Write tests with |
| Conceptual | ASCII diagrams, pseudo-code, incomplete snippets | Skip (document why) |
| Browser-only | Uses browser APIs not available in jsdom | Skip or mock |
扫描概念页面中的所有代码示例并进行分类:
| 类别 | 特征 | 操作 |
|---|---|---|
| 可测试 | 包含带输出注释的 | 编写测试用例 |
| DOM专属 | 使用 | 编写DOM测试(单独文件) |
| 错误示例 | 故意抛出错误,演示失败场景 | 使用 |
| 概念性 | ASCII图、伪代码、不完整代码片段 | 跳过(记录原因) |
| 仅浏览器可用 | 使用jsdom不支持的浏览器API | 跳过或进行模拟 |
Phase 2: Determine Test File Structure
阶段2:确定测试文件结构
tests/
├── fundamentals/ # Concepts 1-6
├── functions-execution/ # Concepts 7-8
├── web-platform/ # Concepts 9-10
├── object-oriented/ # Concepts 11-15
├── functional-programming/ # Concepts 16-19
├── async-javascript/ # Concepts 20-22
├── advanced-topics/ # Concepts 23-31
└── beyond/ # Extended concepts
└── {subcategory}/File naming:
- Standard tests:
{concept-name}.test.js - DOM tests:
{concept-name}.dom.test.js
tests/
├── fundamentals/ # 概念1-6
├── functions-execution/ # 概念7-8
├── web-platform/ # 概念9-10
├── object-oriented/ # 概念11-15
├── functional-programming/ # 概念16-19
├── async-javascript/ # 概念20-22
├── advanced-topics/ # 概念23-31
└── beyond/ # 扩展概念
└── {subcategory}/文件命名规则:
- 标准测试:
{concept-name}.test.js - DOM测试:
{concept-name}.dom.test.js
Phase 3: Convert Examples to Tests
阶段3:将示例转换为测试用例
For each testable code example:
- Identify the expected output (from comments or documented behavior)
console.log - Convert to assertions
expect - Add source line reference in comments
- Group related tests in blocks matching documentation sections
describe
针对每个可测试的代码示例:
- 确定预期输出(来自注释或文档描述的行为)
console.log - 转换为断言
expect - 在注释中添加源代码行引用
- 按照文档章节,将相关测试用例分组到块中
describe
Phase 4: Handle Special Cases
阶段4:处理特殊情况
| Case | Solution |
|---|---|
| Browser-only APIs | Use jsdom environment or skip with note |
| Timing-dependent code | Use |
| Side effects | Capture output or test mutations |
| Intentional errors | Use |
| Async code | Use |
| 情况 | 解决方案 |
|---|---|
| 仅浏览器可用API | 使用jsdom环境或添加说明后跳过 |
| 依赖时序的代码 | 使用 |
| 副作用 | 捕获输出或测试变更 |
| 故意错误 | 使用 |
| 异步代码 | 使用 |
Project Test Conventions
项目测试约定
Import Pattern
导入模式
javascript
import { describe, it, expect } from 'vitest'For DOM tests or tests needing mocks:
javascript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'javascript
import { describe, it, expect } from 'vitest'对于DOM测试或需要模拟的测试:
javascript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'DOM Test File Header
DOM测试文件头部
javascript
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'javascript
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'Describe Block Organization
Describe块组织
Match the structure of the documentation:
javascript
describe('Concept Name', () => {
describe('Section from Documentation', () => {
describe('Subsection if needed', () => {
it('should [specific behavior]', () => {
// Test
})
})
})
})与文档结构保持一致:
javascript
describe('Concept Name', () => {
describe('Section from Documentation', () => {
describe('Subsection if needed', () => {
it('should [specific behavior]', () => {
// Test
})
})
})
})Test Naming Convention
测试用例命名约定
- Start with "should"
- Be descriptive and specific
- Match the documented behavior
javascript
// Good
it('should return "object" for typeof null', () => {})
it('should throw TypeError when accessing property of undefined', () => {})
it('should resolve promises in order they were created', () => {})
// Bad
it('test typeof', () => {})
it('works correctly', () => {})
it('null test', () => {})- 以"should"开头
- 描述性强且具体
- 与文档描述的行为匹配
javascript
// 规范示例
it('should return "object" for typeof null', () => {})
it('should throw TypeError when accessing property of undefined', () => {})
it('should resolve promises in order they were created', () => {})
// 不规范示例
it('test typeof', () => {})
it('works correctly', () => {})
it('null test', () => {})Source Line References
源代码行引用
Always reference the documentation source:
javascript
// ============================================================
// SECTION NAME FROM DOCUMENTATION
// From {concept}.mdx lines XX-YY
// ============================================================
describe('Section Name', () => {
// From lines 45-52: Basic typeof examples
it('should return correct type strings', () => {
// Test
})
})始终关联文档源代码:
javascript
// ============================================================
// DOCUMENTATION SECTION NAME
// From {concept}.mdx lines XX-YY
// ============================================================
describe('Section Name', () => {
// From lines 45-52: Basic typeof examples
it('should return correct type strings', () => {
// Test
})
})Test Patterns Reference
测试模式参考
Pattern 1: Basic Value Assertion
模式1:基础值断言
Documentation:
javascript
console.log(typeof "hello") // "string"
console.log(typeof 42) // "number"Test:
javascript
// From lines XX-YY: typeof examples
it('should return correct type for primitives', () => {
expect(typeof "hello").toBe("string")
expect(typeof 42).toBe("number")
})文档示例:
javascript
console.log(typeof "hello") // "string"
console.log(typeof 42) // "number"测试用例:
javascript
// From lines XX-YY: typeof examples
it('should return correct type for primitives', () => {
expect(typeof "hello").toBe("string")
expect(typeof 42).toBe("number")
})Pattern 2: Multiple Related Assertions
模式2:多相关断言
Documentation:
javascript
let a = "hello"
let b = "hello"
console.log(a === b) // true
let obj1 = { x: 1 }
let obj2 = { x: 1 }
console.log(obj1 === obj2) // falseTest:
javascript
// From lines XX-YY: Primitive vs object comparison
it('should compare primitives by value', () => {
let a = "hello"
let b = "hello"
expect(a === b).toBe(true)
})
it('should compare objects by reference', () => {
let obj1 = { x: 1 }
let obj2 = { x: 1 }
expect(obj1 === obj2).toBe(false)
})文档示例:
javascript
let a = "hello"
let b = "hello"
console.log(a === b) // true
let obj1 = { x: 1 }
let obj2 = { x: 1 }
console.log(obj1 === obj2) // false测试用例:
javascript
// From lines XX-YY: Primitive vs object comparison
it('should compare primitives by value', () => {
let a = "hello"
let b = "hello"
expect(a === b).toBe(true)
})
it('should compare objects by reference', () => {
let obj1 = { x: 1 }
let obj2 = { x: 1 }
expect(obj1 === obj2).toBe(false)
})Pattern 3: Function Return Values
模式3:函数返回值
Documentation:
javascript
function greet(name) {
return "Hello, " + name + "!"
}
console.log(greet("Alice")) // "Hello, Alice!"Test:
javascript
// From lines XX-YY: greet function example
it('should return greeting with name', () => {
function greet(name) {
return "Hello, " + name + "!"
}
expect(greet("Alice")).toBe("Hello, Alice!")
})文档示例:
javascript
function greet(name) {
return "Hello, " + name + "!"
}
console.log(greet("Alice")) // "Hello, Alice!"测试用例:
javascript
// From lines XX-YY: greet function example
it('should return greeting with name', () => {
function greet(name) {
return "Hello, " + name + "!"
}
expect(greet("Alice")).toBe("Hello, Alice!")
})Pattern 4: Error Testing
模式4:错误测试
Documentation:
javascript
// This throws an error!
const obj = null
console.log(obj.property) // TypeError: Cannot read property of nullTest:
javascript
// From lines XX-YY: Accessing property of null
it('should throw TypeError when accessing property of null', () => {
const obj = null
expect(() => {
obj.property
}).toThrow(TypeError)
})文档示例:
javascript
// This throws an error!
const obj = null
console.log(obj.property) // TypeError: Cannot read property of null测试用例:
javascript
// From lines XX-YY: Accessing property of null
it('should throw TypeError when accessing property of null', () => {
const obj = null
expect(() => {
obj.property
}).toThrow(TypeError)
})Pattern 5: Specific Error Messages
模式5:特定错误消息
Documentation:
javascript
function divide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero")
return a / b
}Test:
javascript
// From lines XX-YY: divide function with error
it('should throw error when dividing by zero', () => {
function divide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero")
return a / b
}
expect(() => divide(10, 0)).toThrow("Cannot divide by zero")
expect(divide(10, 2)).toBe(5)
})文档示例:
javascript
function divide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero")
return a / b
}测试用例:
javascript
// From lines XX-YY: divide function with error
it('should throw error when dividing by zero', () => {
function divide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero")
return a / b
}
expect(() => divide(10, 0)).toThrow("Cannot divide by zero")
expect(divide(10, 2)).toBe(5)
})Pattern 6: Async/Await Testing
模式6:Async/Await测试
Documentation:
javascript
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`)
return response.json()
}Test:
javascript
// From lines XX-YY: async fetchUser function
it('should fetch user data asynchronously', async () => {
// Mock fetch for testing
global.fetch = vi.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ id: 1, name: 'Alice' })
})
)
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`)
return response.json()
}
const user = await fetchUser(1)
expect(user).toEqual({ id: 1, name: 'Alice' })
})文档示例:
javascript
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`)
return response.json()
}测试用例:
javascript
// From lines XX-YY: async fetchUser function
it('should fetch user data asynchronously', async () => {
// Mock fetch for testing
global.fetch = vi.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ id: 1, name: 'Alice' })
})
)
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`)
return response.json()
}
const user = await fetchUser(1)
expect(user).toEqual({ id: 1, name: 'Alice' })
})Pattern 7: Promise Testing
模式7:Promise测试
Documentation:
javascript
const promise = new Promise((resolve) => {
resolve("done")
})
promise.then(result => console.log(result)) // "done"Test:
javascript
// From lines XX-YY: Basic Promise resolution
it('should resolve with correct value', async () => {
const promise = new Promise((resolve) => {
resolve("done")
})
await expect(promise).resolves.toBe("done")
})文档示例:
javascript
const promise = new Promise((resolve) => {
resolve("done")
})
promise.then(result => console.log(result)) // "done"测试用例:
javascript
// From lines XX-YY: Basic Promise resolution
it('should resolve with correct value', async () => {
const promise = new Promise((resolve) => {
resolve("done")
})
await expect(promise).resolves.toBe("done")
})Pattern 8: Promise Rejection
模式8:Promise拒绝
Documentation:
javascript
const promise = new Promise((resolve, reject) => {
reject(new Error("Something went wrong"))
})Test:
javascript
// From lines XX-YY: Promise rejection
it('should reject with error', async () => {
const promise = new Promise((resolve, reject) => {
reject(new Error("Something went wrong"))
})
await expect(promise).rejects.toThrow("Something went wrong")
})文档示例:
javascript
const promise = new Promise((resolve, reject) => {
reject(new Error("Something went wrong"))
})测试用例:
javascript
// From lines XX-YY: Promise rejection
it('should reject with error', async () => {
const promise = new Promise((resolve, reject) => {
reject(new Error("Something went wrong"))
})
await expect(promise).rejects.toThrow("Something went wrong")
})Pattern 9: Floating Point Comparison
模式9:浮点数比较
Documentation:
javascript
console.log(0.1 + 0.2) // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3) // falseTest:
javascript
// From lines XX-YY: Floating point precision
it('should demonstrate floating point imprecision', () => {
expect(0.1 + 0.2).not.toBe(0.3)
expect(0.1 + 0.2).toBeCloseTo(0.3)
expect(0.1 + 0.2 === 0.3).toBe(false)
})文档示例:
javascript
console.log(0.1 + 0.2) // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3) // false测试用例:
javascript
// From lines XX-YY: Floating point precision
it('should demonstrate floating point imprecision', () => {
expect(0.1 + 0.2).not.toBe(0.3)
expect(0.1 + 0.2).toBeCloseTo(0.3)
expect(0.1 + 0.2 === 0.3).toBe(false)
})Pattern 10: Array Method Testing
模式10:数组方法测试
Documentation:
javascript
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
console.log(doubled) // [2, 4, 6, 8, 10]Test:
javascript
// From lines XX-YY: Array map example
it('should double all numbers in array', () => {
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
expect(doubled).toEqual([2, 4, 6, 8, 10])
expect(numbers).toEqual([1, 2, 3, 4, 5]) // Original unchanged
})文档示例:
javascript
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
console.log(doubled) // [2, 4, 6, 8, 10]测试用例:
javascript
// From lines XX-YY: Array map example
it('should double all numbers in array', () => {
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
expect(doubled).toEqual([2, 4, 6, 8, 10])
expect(numbers).toEqual([1, 2, 3, 4, 5]) // Original unchanged
})Pattern 11: Object Mutation Testing
模式11:对象变更测试
Documentation:
javascript
const obj = { a: 1 }
obj.b = 2
console.log(obj) // { a: 1, b: 2 }Test:
javascript
// From lines XX-YY: Object mutation
it('should allow adding properties to objects', () => {
const obj = { a: 1 }
obj.b = 2
expect(obj).toEqual({ a: 1, b: 2 })
})文档示例:
javascript
const obj = { a: 1 }
obj.b = 2
console.log(obj) // { a: 1, b: 2 }测试用例:
javascript
// From lines XX-YY: Object mutation
it('should allow adding properties to objects', () => {
const obj = { a: 1 }
obj.b = 2
expect(obj).toEqual({ a: 1, b: 2 })
})Pattern 12: Closure Testing
模式12:闭包测试
Documentation:
javascript
function counter() {
let count = 0
return function() {
count++
return count
}
}
const increment = counter()
console.log(increment()) // 1
console.log(increment()) // 2
console.log(increment()) // 3Test:
javascript
// From lines XX-YY: Closure counter example
it('should maintain state across calls via closure', () => {
function counter() {
let count = 0
return function() {
count++
return count
}
}
const increment = counter()
expect(increment()).toBe(1)
expect(increment()).toBe(2)
expect(increment()).toBe(3)
})
it('should create independent counters', () => {
function counter() {
let count = 0
return function() {
count++
return count
}
}
const counter1 = counter()
const counter2 = counter()
expect(counter1()).toBe(1)
expect(counter1()).toBe(2)
expect(counter2()).toBe(1) // Independent
})文档示例:
javascript
function counter() {
let count = 0
return function() {
count++
return count
}
}
const increment = counter()
console.log(increment()) // 1
console.log(increment()) // 2
console.log(increment()) // 3测试用例:
javascript
// From lines XX-YY: Closure counter example
it('should maintain state across calls via closure', () => {
function counter() {
let count = 0
return function() {
count++
return count
}
}
const increment = counter()
expect(increment()).toBe(1)
expect(increment()).toBe(2)
expect(increment()).toBe(3)
})
it('should create independent counters', () => {
function counter() {
let count = 0
return function() {
count++
return count
}
}
const counter1 = counter()
const counter2 = counter()
expect(counter1()).toBe(1)
expect(counter1()).toBe(2)
expect(counter2()).toBe(1) // Independent
})Pattern 13: DOM Event Testing
模式13:DOM事件测试
Documentation:
javascript
const button = document.getElementById('myButton')
button.addEventListener('click', function(event) {
console.log('Button clicked!')
console.log(event.type) // "click"
})Test (in .dom.test.js file):
javascript
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
describe('DOM Event Handlers', () => {
let button
beforeEach(() => {
button = document.createElement('button')
button.id = 'myButton'
document.body.appendChild(button)
})
afterEach(() => {
document.body.innerHTML = ''
})
// From lines XX-YY: Button click event
it('should fire click event handler', () => {
const output = []
button.addEventListener('click', function(event) {
output.push('Button clicked!')
output.push(event.type)
})
button.click()
expect(output).toEqual(['Button clicked!', 'click'])
})
})文档示例:
javascript
const button = document.getElementById('myButton')
button.addEventListener('click', function(event) {
console.log('Button clicked!')
console.log(event.type) // "click"
})测试用例(位于.dom.test.js文件):
javascript
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
describe('DOM Event Handlers', () => {
let button
beforeEach(() => {
button = document.createElement('button')
button.id = 'myButton'
document.body.appendChild(button)
})
afterEach(() => {
document.body.innerHTML = ''
})
// From lines XX-YY: Button click event
it('should fire click event handler', () => {
const output = []
button.addEventListener('click', function(event) {
output.push('Button clicked!')
output.push(event.type)
})
button.click()
expect(output).toEqual(['Button clicked!', 'click'])
})
})Pattern 14: DOM Manipulation Testing
模式14:DOM操作测试
Documentation:
javascript
const div = document.createElement('div')
div.textContent = 'Hello'
div.classList.add('greeting')
document.body.appendChild(div)Test:
javascript
// From lines XX-YY: Creating and appending elements
it('should create element with text and class', () => {
const div = document.createElement('div')
div.textContent = 'Hello'
div.classList.add('greeting')
document.body.appendChild(div)
const element = document.querySelector('.greeting')
expect(element).not.toBeNull()
expect(element.textContent).toBe('Hello')
expect(element.classList.contains('greeting')).toBe(true)
})文档示例:
javascript
const div = document.createElement('div')
div.textContent = 'Hello'
div.classList.add('greeting')
document.body.appendChild(div)测试用例:
javascript
// From lines XX-YY: Creating and appending elements
it('should create element with text and class', () => {
const div = document.createElement('div')
div.textContent = 'Hello'
div.classList.add('greeting')
document.body.appendChild(div)
const element = document.querySelector('.greeting')
expect(element).not.toBeNull()
expect(element.textContent).toBe('Hello')
expect(element.classList.contains('greeting')).toBe(true)
})Pattern 15: Timer Testing
模式15:定时器测试
Documentation:
javascript
console.log('First')
setTimeout(() => console.log('Second'), 0)
console.log('Third')
// Output: First, Third, SecondTest:
javascript
// From lines XX-YY: setTimeout execution order
it('should execute setTimeout callback after synchronous code', async () => {
const output = []
output.push('First')
setTimeout(() => output.push('Second'), 0)
output.push('Third')
// Wait for setTimeout to execute
await new Promise(resolve => setTimeout(resolve, 10))
expect(output).toEqual(['First', 'Third', 'Second'])
})文档示例:
javascript
console.log('First')
setTimeout(() => console.log('Second'), 0)
console.log('Third')
// Output: First, Third, Second测试用例:
javascript
// From lines XX-YY: setTimeout execution order
it('should execute setTimeout callback after synchronous code', async () => {
const output = []
output.push('First')
setTimeout(() => output.push('Second'), 0)
output.push('Third')
// Wait for setTimeout to execute
await new Promise(resolve => setTimeout(resolve, 10))
expect(output).toEqual(['First', 'Third', 'Second'])
})Pattern 16: Strict Mode Behavior
模式16:严格模式行为
Documentation:
javascript
// In strict mode, this throws
"use strict"
x = 10 // ReferenceError: x is not definedTest:
javascript
// From lines XX-YY: Strict mode variable declaration
it('should throw ReferenceError in strict mode for undeclared variables', () => {
// Vitest runs in strict mode by default
expect(() => {
// Using eval to test strict mode behavior
"use strict"
eval('undeclaredVar = 10')
}).toThrow()
})文档示例:
javascript
// In strict mode, this throws
"use strict"
x = 10 // ReferenceError: x is not defined测试用例:
javascript
// From lines XX-YY: Strict mode variable declaration
it('should throw ReferenceError in strict mode for undeclared variables', () => {
// Vitest runs in strict mode by default
expect(() => {
// Using eval to test strict mode behavior
"use strict"
eval('undeclaredVar = 10')
}).toThrow()
})Complete Test File Template
完整测试文件模板
javascript
import { describe, it, expect } from 'vitest'
describe('[Concept Name]', () => {
// ============================================================
// [FIRST SECTION NAME FROM DOCUMENTATION]
// From [concept].mdx lines XX-YY
// ============================================================
describe('[First Section]', () => {
// From lines XX-YY: [Brief description of example]
it('should [expected behavior]', () => {
// Code from documentation
expect(result).toBe(expected)
})
// From lines XX-YY: [Brief description of next example]
it('should [another expected behavior]', () => {
// Code from documentation
expect(result).toEqual(expected)
})
})
// ============================================================
// [SECOND SECTION NAME FROM DOCUMENTATION]
// From [concept].mdx lines XX-YY
// ============================================================
describe('[Second Section]', () => {
// From lines XX-YY: [Description]
it('should [behavior]', () => {
// Test
})
})
// ============================================================
// EDGE CASES AND COMMON MISTAKES
// From [concept].mdx lines XX-YY
// ============================================================
describe('Edge Cases', () => {
// From lines XX-YY: [Edge case description]
it('should handle [edge case]', () => {
// Test
})
})
describe('Common Mistakes', () => {
// From lines XX-YY: Wrong way example
it('should demonstrate the incorrect behavior', () => {
// Test showing why the "wrong" way fails
})
// From lines XX-YY: Correct way example
it('should demonstrate the correct behavior', () => {
// Test showing the right approach
})
})
})javascript
import { describe, it, expect } from 'vitest'
describe('[Concept Name]', () => {
// ============================================================
// [FIRST SECTION NAME FROM DOCUMENTATION]
// From [concept].mdx lines XX-YY
// ============================================================
describe('[First Section]', () => {
// From lines XX-YY: [Brief description of example]
it('should [expected behavior]', () => {
// Code from documentation
expect(result).toBe(expected)
})
// From lines XX-YY: [Brief description of next example]
it('should [another expected behavior]', () => {
// Code from documentation
expect(result).toEqual(expected)
})
})
// ============================================================
// [SECOND SECTION NAME FROM DOCUMENTATION]
// From [concept].mdx lines XX-YY
// ============================================================
describe('[Second Section]', () => {
// From lines XX-YY: [Description]
it('should [behavior]', () => {
// Test
})
})
// ============================================================
// EDGE CASES AND COMMON MISTAKES
// From [concept].mdx lines XX-YY
// ============================================================
describe('Edge Cases', () => {
// From lines XX-YY: [Edge case description]
it('should handle [edge case]', () => {
// Test
})
})
describe('Common Mistakes', () => {
// From lines XX-YY: Wrong way example
it('should demonstrate the incorrect behavior', () => {
// Test showing why the "wrong" way fails
})
// From lines XX-YY: Correct way example
it('should demonstrate the correct behavior', () => {
// Test showing the right approach
})
})
})Complete DOM Test File Template
完整DOM测试文件模板
javascript
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
// ============================================================
// DOM EXAMPLES FROM [CONCEPT NAME]
// From [concept].mdx lines XX-YY
// ============================================================
describe('[Concept Name] - DOM', () => {
// Shared setup
let container
beforeEach(() => {
// Create a fresh container for each test
container = document.createElement('div')
container.id = 'test-container'
document.body.appendChild(container)
})
afterEach(() => {
// Clean up after each test
document.body.innerHTML = ''
vi.restoreAllMocks()
})
// ============================================================
// [SECTION NAME]
// From lines XX-YY
// ============================================================
describe('[Section Name]', () => {
// From lines XX-YY: [Example description]
it('should [expected DOM behavior]', () => {
// Setup
const element = document.createElement('div')
container.appendChild(element)
// Action
element.textContent = 'Hello'
// Assert
expect(element.textContent).toBe('Hello')
})
})
// ============================================================
// EVENT HANDLING
// From lines XX-YY
// ============================================================
describe('Event Handling', () => {
// From lines XX-YY: Click event example
it('should handle click events', () => {
const button = document.createElement('button')
container.appendChild(button)
let clicked = false
button.addEventListener('click', () => {
clicked = true
})
button.click()
expect(clicked).toBe(true)
})
})
})javascript
/**
* @vitest-environment jsdom
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
// ============================================================
// DOM EXAMPLES FROM [CONCEPT NAME]
// From [concept].mdx lines XX-YY
// ============================================================
describe('[Concept Name] - DOM', () => {
// Shared setup
let container
beforeEach(() => {
// Create a fresh container for each test
container = document.createElement('div')
container.id = 'test-container'
document.body.appendChild(container)
})
afterEach(() => {
// Clean up after each test
document.body.innerHTML = ''
vi.restoreAllMocks()
})
// ============================================================
// [SECTION NAME]
// From lines XX-YY
// ============================================================
describe('[Section Name]', () => {
// From lines XX-YY: [Example description]
it('should [expected DOM behavior]', () => {
// Setup
const element = document.createElement('div')
container.appendChild(element)
// Action
element.textContent = 'Hello'
// Assert
expect(element.textContent).toBe('Hello')
})
})
// ============================================================
// EVENT HANDLING
// From lines XX-YY
// ============================================================
describe('Event Handling', () => {
// From lines XX-YY: Click event example
it('should handle click events', () => {
const button = document.createElement('button')
container.appendChild(button)
let clicked = false
button.addEventListener('click', () => {
clicked = true
})
button.click()
expect(clicked).toBe(true)
})
})
})Running Tests
运行测试
bash
undefinedbash
undefinedRun all tests
运行所有测试
npm test
npm test
Run tests for specific concept
运行特定概念的测试
npm test -- tests/fundamentals/primitive-types/
npm test -- tests/fundamentals/primitive-types/
Run tests for specific file
运行特定文件的测试
npm test -- tests/fundamentals/primitive-types/primitive-types.test.js
npm test -- tests/fundamentals/primitive-types/primitive-types.test.js
Run DOM tests only
仅运行DOM测试
npm test -- tests/fundamentals/primitive-types/primitive-types.dom.test.js
npm test -- tests/fundamentals/primitive-types/primitive-types.dom.test.js
Run with watch mode
监听模式运行
npm run test:watch
npm run test:watch
Run with coverage
生成覆盖率报告
npm run test:coverage
npm run test:coverage
Run with verbose output
详细输出模式
npm test -- --reporter=verbose
---npm test -- --reporter=verbose
---Quality Checklist
质量检查清单
Completeness
完整性
- All testable code examples have corresponding tests
- Tests organized by documentation sections
- Source line references included in comments (From lines XX-YY)
- DOM tests in separate file
.dom.test.js - Edge cases and error examples tested
- 所有可测试的代码示例均有对应的测试用例
- 测试用例按文档章节组织
- 注释中包含源代码行引用(From lines XX-YY)
- DOM测试位于单独的文件
.dom.test.js - 边界情况和错误示例已测试
Correctness
正确性
- Tests verify the actual documented behavior
- Output comments in docs match test expectations
- Async tests properly use async/await
- Error tests use correct pattern
toThrow - Floating point comparisons use
toBeCloseTo - Object comparisons use (not
toEqual)toBe
- 测试验证的是文档实际描述的行为
- 文档中的输出注释与测试预期一致
- 异步测试正确使用async/await
- 错误测试使用正确的模式
toThrow - 浮点数比较使用
toBeCloseTo - 对象比较使用(而非
toEqual)toBe
Convention
规范性
- Uses explicit imports from vitest
- Follows describe/it nesting pattern
- Test names start with "should"
- Proper file naming ()
{concept}.test.js - DOM tests have jsdom environment directive
- 从vitest导入明确的成员
- 遵循describe/it嵌套模式
- 测试用例名称以"should"开头
- 文件命名规范()
{concept}.test.js - DOM测试包含jsdom环境指令
Verification
验证
- All tests pass:
npm test -- tests/{category}/{concept}/ - No skipped tests without documented reason
- No false positives (tests that pass for wrong reasons)
- 所有测试通过:
npm test -- tests/{category}/{concept}/ - 跳过的测试均有文档说明原因
- 无假阳性(因错误原因通过的测试)
Test Report Template
测试报告模板
Use this template to document test coverage for a concept page.
markdown
undefined使用此模板记录概念页面的测试覆盖情况。
markdown
undefinedTest Coverage Report: [Concept Name]
测试覆盖报告: [Concept Name]
Concept Page:
Test File:
DOM Test File: (if applicable)
Date: YYYY-MM-DD
Author: [Name/Claude]
/docs/concepts/[slug].mdx/tests/{category}/{concept}/{concept}.test.js/tests/{category}/{concept}/{concept}.dom.test.js概念页面:
测试文件:
DOM测试文件: (如适用)
日期: YYYY-MM-DD
作者: [Name/Claude]
/docs/concepts/[slug].mdx/tests/{category}/{concept}/{concept}.test.js/tests/{category}/{concept}/{concept}.dom.test.jsSummary
摘要
| Metric | Count |
|---|---|
| Total Code Examples in Doc | XX |
| Testable Examples | XX |
| Tests Written | XX |
| DOM Tests Written | XX |
| Skipped (with reason) | XX |
| 指标 | 数量 |
|---|---|
| 文档中代码示例总数 | XX |
| 可测试示例数 | XX |
| 已编写测试用例数 | XX |
| 已编写DOM测试用例数 | XX |
| 已跳过示例数(含原因) | XX |
Tests by Section
各章节测试情况
| Section | Line Range | Examples | Tests | Status |
|---|---|---|---|---|
| [Section 1] | XX-YY | X | X | ✅ |
| [Section 2] | XX-YY | X | X | ✅ |
| [Section 3] | XX-YY | X | X | ⚠️ (1 skipped) |
| 章节 | 行范围 | 示例数 | 测试用例数 | 状态 |
|---|---|---|---|---|
| [Section 1] | XX-YY | X | X | ✅ |
| [Section 2] | XX-YY | X | X | ✅ |
| [Section 3] | XX-YY | X | X | ⚠️ (1 skipped) |
Skipped Examples
已跳过示例
| Line | Example Description | Reason |
|---|---|---|
| XX | ASCII diagram of call stack | Conceptual, not executable |
| YY | Browser fetch example | Requires network, mocked instead |
| 行号 | 示例描述 | 原因 |
|---|---|---|
| XX | 调用栈ASCII图 | 概念性内容,不可执行 |
| YY | 浏览器fetch示例 | 需要网络连接,已模拟实现 |
Test Execution
测试执行结果
bash
npm test -- tests/{category}/{concept}/Result: ✅ XX passing | ❌ X failing | ⏭️ X skipped
bash
npm test -- tests/{category}/{concept}/结果: ✅ XX通过 | ❌ X失败 | ⏭️ X跳过
Notes
备注
[Any special considerations, mock requirements, or issues encountered]
---[任何特殊注意事项、模拟需求或遇到的问题]
---Common Issues and Solutions
常见问题与解决方案
Issue: Test passes but shouldn't
问题:测试本应失败却通过
Problem: Test expectations don't match documentation output
Solution: Double-check the expected value matches the comment exactly
console.logjavascript
// Documentation says: console.log(result) // [1, 2, 3]
// Make sure test uses:
expect(result).toEqual([1, 2, 3]) // NOT toBe for arrays问题描述: 测试预期与文档输出不匹配
解决方案: 仔细检查预期值是否与文档中的注释完全一致
console.logjavascript
// 文档说明:console.log(result) // [1, 2, 3]
// 确保测试使用:
expect(result).toEqual([1, 2, 3]) // 数组比较请勿使用toBeIssue: Async test times out
问题:异步测试超时
Problem: Async test never resolves
Solution: Ensure all promises are awaited and async function is marked
javascript
// Bad
it('should fetch data', () => {
const data = fetchData() // Missing await!
expect(data).toBeDefined()
})
// Good
it('should fetch data', async () => {
const data = await fetchData()
expect(data).toBeDefined()
})问题描述: 异步测试从未完成
解决方案: 确保所有Promise都已await,且函数标记为async
javascript
// 错误示例
it('should fetch data', () => {
const data = fetchData() // Missing await!
expect(data).toBeDefined()
})
// 正确示例
it('should fetch data', async () => {
const data = await fetchData()
expect(data).toBeDefined()
})Issue: DOM test fails with "document is not defined"
问题:DOM测试提示"document is not defined"
Problem: Missing jsdom environment
Solution: Add environment directive at top of file
javascript
/**
* @vitest-environment jsdom
*/问题描述: 缺少jsdom环境
解决方案: 在文件顶部添加环境指令
javascript
/**
* @vitest-environment jsdom
*/Issue: Test isolation problems
问题:测试隔离问题
Problem: Tests affect each other
Solution: Use beforeEach/afterEach for cleanup
javascript
afterEach(() => {
document.body.innerHTML = ''
vi.restoreAllMocks()
})问题描述: 测试之间相互影响
解决方案: 使用beforeEach/afterEach进行清理
javascript
afterEach(() => {
document.body.innerHTML = ''
vi.restoreAllMocks()
})Summary
总结
When writing tests for a concept page:
- Extract all code examples from the documentation
- Categorize as testable, DOM, error, or conceptual
- Create test file in correct location with proper naming
- Convert each example to test using appropriate pattern
- Reference source lines in comments for traceability
- Run tests to verify all pass
- Document coverage using the report template
Remember: Tests serve two purposes:
- Verify documentation is accurate
- Catch regressions if code examples are updated
Every testable code example in the documentation should have a corresponding test. If an example can't be tested, document why.
为概念页面编写测试用例时:
- 提取所有代码示例 从文档中提取所有代码示例
- 分类 分为可测试、DOM、错误或概念性示例
- 创建测试文件 放置在正确位置并使用规范命名
- 转换示例为测试用例 使用合适的测试模式
- 关联源代码行 在注释中添加引用以确保可追溯
- 运行测试 验证所有测试通过
- 记录覆盖情况 使用报告模板记录
注意: 测试有两个核心目的:
- 验证文档内容的准确性
- 当代码示例更新时捕获回归问题
文档中所有可测试的代码示例都应有对应的测试用例。如果某个示例无法测试,请记录原因。