跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
JavaScript单元测试
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= JavaScript单元测试 = '''JavaScript单元测试'''是一种软件开发实践,用于验证代码中最小可测试单元(通常是函数或方法)的行为是否符合预期。通过编写测试用例,开发者可以确保代码在不同场景下的正确性,并在修改代码时快速发现错误。 == 介绍 == 单元测试是自动化测试的一种形式,它专注于隔离代码的单个部分并验证其功能。在JavaScript中,单元测试通常针对函数或模块进行,确保它们在各种输入条件下产生正确的输出。 单元测试的主要优点包括: * '''早期错误检测''':在开发过程中及时发现错误 * '''代码质量提升''':迫使开发者编写更模块化和可测试的代码 * '''文档作用''':测试用例可作为代码行为的活文档 * '''重构安全性''':确保修改代码不会破坏现有功能 == 测试框架 == JavaScript有多种流行的单元测试框架,最常用的包括: === Jest === Jest是Facebook开发的一个零配置测试框架,内置断言库和模拟功能。 === Mocha === Mocha是一个灵活的测试框架,通常与断言库(如Chai)和模拟库(如Sinon)一起使用。 === Jasmine === Jasmine是一个行为驱动的开发(BDD)测试框架,内置断言功能。 == 基本测试结构 == 以下是使用Jest编写的基本测试示例: <syntaxhighlight lang="javascript"> // 被测试的函数 function sum(a, b) { return a + b; } // 测试用例 test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); }); </syntaxhighlight> 输出: <pre> PASS ./sum.test.js ✓ adds 1 + 2 to equal 3 (2 ms) </pre> == 测试生命周期 == 测试框架通常提供生命周期钩子,允许在测试前后执行设置和清理操作: <mermaid> flowchart LR A[beforeAll] --> B[beforeEach] B --> C[test] C --> D[afterEach] D --> E[afterAll] </mermaid> 示例: <syntaxhighlight lang="javascript"> describe('测试数据库连接', () => { beforeAll(() => { // 在所有测试之前运行 initializeDatabase(); }); afterAll(() => { // 在所有测试之后运行 closeDatabase(); }); test('查询用户数据', () => { expect(queryUser(1)).toBeDefined(); }); }); </syntaxhighlight> == 断言 == 断言是测试的核心部分,用于验证代码行为。常见的断言类型包括: * 相等性检查:<code>expect(a).toBe(b)</code> * 真实性检查:<code>expect(a).toBeTruthy()</code> * 异常检查:<code>expect(() => {...}).toThrow()</code> == 模拟(Mocking) == 模拟允许你替换依赖项,专注于测试当前单元: <syntaxhighlight lang="javascript"> // 模拟一个API调用 jest.mock('./api'); test('获取用户数据', async () => { const getUser = require('./api').getUser; getUser.mockResolvedValue({ id: 1, name: 'John' }); const user = await fetchUser(1); expect(user.name).toBe('John'); }); </syntaxhighlight> == 测试覆盖率 == 测试覆盖率衡量有多少代码被测试覆盖。Jest等工具可以生成覆盖率报告: <pre> ----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|------------------- All files | 100 | 100 | 100 | 100 | sum.js | 100 | 100 | 100 | 100 | ----------|---------|----------|---------|---------|------------------- </pre> == 实际案例 == 考虑一个购物车功能的测试: <syntaxhighlight lang="javascript"> class ShoppingCart { constructor() { this.items = []; } addItem(item, quantity) { if (quantity <= 0) throw new Error('数量必须大于0'); this.items.push({ item, quantity }); } getTotal() { return this.items.reduce( (total, { item, quantity }) => total + item.price * quantity, 0 ); } } describe('ShoppingCart', () => { let cart; const testItem = { id: 1, name: '商品A', price: 100 }; beforeEach(() => { cart = new ShoppingCart(); }); test('添加商品到购物车', () => { cart.addItem(testItem, 2); expect(cart.items.length).toBe(1); }); test('计算总价', () => { cart.addItem(testItem, 2); expect(cart.getTotal()).toBe(200); }); test('不允许添加数量为0的商品', () => { expect(() => cart.addItem(testItem, 0)).toThrow(); }); }); </syntaxhighlight> == 数学公式示例 == 在测试涉及数学计算的函数时,可能需要验证公式的正确性。例如,测试一个计算圆面积的函数: <math> A = \pi r^2 </math> 对应的测试: <syntaxhighlight lang="javascript"> function circleArea(radius) { return Math.PI * radius * radius; } test('计算圆面积', () => { expect(circleArea(1)).toBeCloseTo(Math.PI); expect(circleArea(2)).toBeCloseTo(4 * Math.PI); }); </syntaxhighlight> == 最佳实践 == 1. '''测试命名''':使用描述性名称,如"当用户未登录时应该重定向到登录页面" 2. '''单一职责''':每个测试只验证一个行为 3. '''独立测试''':测试不应依赖其他测试的状态 4. '''测试边界条件''':包括有效输入、无效输入和边缘情况 5. '''保持测试快速''':避免慢速测试阻碍开发流程 == 高级主题 == 对于更复杂的场景,你可能需要了解: * 快照测试(Snapshot Testing) * 端到端测试(End-to-End Testing) * 测试驱动开发(Test-Driven Development, TDD) * 行为驱动开发(Behavior-Driven Development, BDD) == 结论 == JavaScript单元测试是现代Web开发的重要组成部分。通过采用良好的测试实践,你可以构建更可靠、更易维护的应用程序。从简单的函数测试开始,逐步扩展到更复杂的场景,最终实现全面的测试覆盖。 [[Category:编程语言]] [[Category:JavaScript]] [[Category:Javascript测试]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)