来,加入前端自动化单元测试

简介:


最近闲来无事,开始摸索前端单元测试。一是不备之需,二是确实在实际项目中能够用到单元测试。这样可以提高开发效率,提升代码质量,完全可以单独对 JS 进行测试,无需页面,不依赖其他第三方。

为什么需要单元测试

在这里首先需要知道单元测试的目的及结果:

  • 使代码健壮,质量高,兼容各种临界点;
  • 减少 QA 测试报告的反馈,提高自我影响力;
  • 保证代码的整洁清晰。

如果需要刨根问底追究为什么需要进行单元测试,那我们可以开始讲讲实际项目开发中遇到的一些问题:

  • QA 不断反馈代码有 BUG (此时你正在投入的开发,然后被打扰...);
  • 代码出现 BUG,叠加代码修复 BUG(代码越来越难维护...);
  • 已经开发完成一个模块,但是没有页面提供调试测试;
  • 你开发完成的功能,每次都有许多细小的 BUG(个人影响力下降...)。

好了,列举了这么多原因,相信你也开始心虚了,回去继续搬砖检查检查代码有没有问题,如果你面色从容,大神,请手下我的膝盖。

总结:单元测试的目的只有一个,用来确定是否适合使用

如何进行单元测试

如果明白了为什么要进行单元测试,相信你已经可以开始着手为自己的代码写一些单元测试代码。测试从字面理解就是检验,看对象是否达标,达标就是 pass,不达标就是 fail。产品有这样一个需求,如果结果是 3 达到目标且返回的为有效的数字类型才可以进行比较,下面看个栗子:


 
 
  1. /** 
  2.  * 获取 a 除以 b 的结果 
  3.  * @param  {[Number]} a [数字] 
  4.  * @param  {[Number]} b [数字] 
  5.  * @return {[Number]}   [结果数字] 
  6.  */ 
  7. function division(a, b) { 
  8.     return a / b; 
  9.  
  10. // 测试代码 
  11. function test() { 
  12.     var result = division(6, 2); 
  13.      
  14.     if (result === 3) { 
  15.         console.log('pass'); 
  16.     } else { 
  17.         console.log('fail'); 
  18.     } 
  19. }  

咋一看上面的代码没什么问题,可以满足产品的需求,但是问题来了,如果 b 为 0,这个模块就出现了 BUG,同时如果下次需要达到其他的值就算通过,那就得去修改测试代码,这样的测试代码本身也太不健全。于是乎有了下面的方式:


 
 
  1. /** 
  2.  * 获取 a 除以 b 的结果 
  3.  * @param  {[Number]} a [数字] 
  4.  * @param  {[Number]} b [数字] 
  5.  * @return {[Number]}   [结果数字] 
  6.  */ 
  7. function division(a, b) { 
  8.  
  9.     if (b === 0) { 
  10.         return 0; 
  11.     } else { 
  12.         return a / b; 
  13.     } 
  14.  
  15. function test(name, result, expect) { 
  16.  
  17.     if (result === expect) { 
  18.         console.log(name + '-> pass'); 
  19.     } else { 
  20.         console.log(name + '-> fail'); 
  21.     } 
  22. test('normal number', division(6, 2), 3); 
  23. test('zero', division(6, 0), 0);  

如果需要期望值为 10 就通过,那可以这样:


 
 
  1. test('normal number is 10', division(20, 2), 10); 

单元测试环境搭建及代码示例

但是随着前端迅速的发展,也出现了很多测试框架,下面我演示我在实际项目中使用的测试框架环境配置 karma + jasmine,对于 karma、jasmine 我就不介绍,网上一搜一大把介绍:

1. 安装 node 环境

依赖于 node 作为基础环境,安装完成在控制台运行下面命令查看是否安装成功。


 
 
  1. node -v 

2. 新建目录并通过以下命令初始化项目配置 package.json


 
 
  1. npm init 

在 package.json scripts: {} 添加以下内容:


 
 
  1. "test""karma start karma.conf.js" 

3. 依次安装测试框架


 
 
  1. npm install karma -g 
  2. npm install jasmine --save-dev 
  3. npm install karma-jasmine --save-dev 
  4. npm install karma-chrome-launcher --save-dev 
  5. npm install jasmine-core --save-dev  

或者一次性安装


 
 
  1. npm install karma -g 
  2.  
  3. npm install jasmine karma-jasmine karma-chrome-launcher jasmine-core --save-dev  

运行以下命令新建 karma.conf.js(根目录下不是必须)


 
 
  1. karma init 

文件内容及说明:


 
 
  1. /** 
  2.  * karma 自动化测试参数配置 
  3.  */ 
  4.  
  5. module.exports = function(config) { 
  6.     config.set({ 
  7.  
  8.         // 基础路径,用在files,exclude属性上 
  9.         basePath: ''
  10.  
  11.         // 可用的测试框架: https://npmjs.org/browse/keyword/karma-adapter 
  12.         frameworks: ['jasmine'], 
  13.  
  14.         // 需要加载到浏览器的文件列表 
  15.         files: [ 
  16.             './src/**/*.js'
  17.             './test/unit/specs/*.spec.js' 
  18.         ], 
  19.  
  20.         // 排除的文件列表 
  21.         exclude: [ 
  22.             'karma.conf.js' 
  23.         ], 
  24.  
  25.         // 在浏览器使用之前处理匹配的文件 
  26.         // 可用的预处理: https://npmjs.org/browse/keyword/karma-preprocessor 
  27.         preprocessors: {}, 
  28.  
  29.         // 使用测试结果报告者 
  30.         // 可能的值: "dots""progress" 
  31.         // 可用的报告者: https://npmjs.org/browse/keyword/karma-reporter 
  32.         reporters: ['progress'], 
  33.  
  34.         // web server port 
  35.         port: 9876, 
  36.  
  37.         // 启用或禁用输出报告或者日志中的颜色 
  38.         colors: true
  39.  
  40.         /** 
  41.          * 日志等级 
  42.          * 可能的值: 
  43.          * config.LOG_DISABLE //不输出信息 
  44.          * config.LOG_ERROR    //只输出错误信息 
  45.          * config.LOG_WARN //只输出警告信息 
  46.          * config.LOG_INFO //输出全部信息 
  47.          * config.LOG_DEBUG //输出调试信息 
  48.          */ 
  49.         // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 
  50.         logLevel: config.LOG_INFO, 
  51.  
  52.         // 启用或禁用自动检测文件变化进行测试 
  53.         autoWatch: true
  54.  
  55.         // 测试启动的浏览器 
  56.         // 可用的浏览器: https://npmjs.org/browse/keyword/karma-launcher 
  57.         browsers: ['Chrome'], 
  58.  
  59.         // 开启或禁用持续集成模式 
  60.         // 设置为true, Karma将打开浏览器,执行测试并最后退出 
  61.         singleRun: false
  62.  
  63.         // 并发级别(启动的浏览器数) 
  64.         concurrency: Infinity, 
  65.  
  66.         // 依赖插件 
  67.         plugins: [ 
  68.             'karma-chrome-launcher'
  69.             'karma-jasmine' 
  70.         ] 
  71.     }) 
  72. }  

5. 新建源代码及测试代码目录,目录结构如下:


 
 
  1. project 
  2.     - node_modules 
  3.         - *(node 模块) 
  4.     - src 
  5.         - FQA 
  6.             - index.js 
  7.     - test 
  8.         - unit 
  9.             - specs 
  10.                 - *.spec.js 
  11.     - karma.conf.js 
  12.     - package.json  

6. 测试代码

。index.js 源码


 
 
  1. /** 
  2.  - test map method callback and parseInt param use 
  3.  - @return {[Array]} [Array] 
  4.  */ 
  5. function checkMap() { 
  6.     var nums = ['1''2''3']; 
  7.  
  8.     return nums.map(parseInt); 
  9.  
  10. /** 
  11.  - test null is Object,and common object is same 
  12.  - @return {[Array]} [Array] 
  13.  */ 
  14. function typeofAndInstanceOf() { 
  15.     var result = []; 
  16.     result.push(typeof null); 
  17.     result.push(null instanceof Object); 
  18.  
  19.     return result; 
  20.  
  21. /** 
  22.  - 检测操作符优先级 
  23.  - @return {[string]} [返回字符串] 
  24.  */ 
  25. function checkOperators() { 
  26.     var result = 'autoTest'
  27.     result = 'Value is ' + (result === 'autoTest') ? 'Something' : 'Nothing'
  28.  
  29.     return result; 
  30. }  

。fqa.spec.js 测试代码


 
 
  1. /** 
  2.  - test index.js checkMap method 
  3.  - detail: 
  4.  -     parseInt(val, base), base is 2 ~ 36, otherwise value equal NaN. 
  5.  */ 
  6. describe('test map and callback parseInt'function() { 
  7.      
  8.     it('a array call map'function() { 
  9.         var nums = checkMap(); 
  10.         console.log(nums); 
  11.  
  12.         expect([1, NaN, NaN]).toEqual(nums); 
  13.     }); 
  14. }); 
  15.  
  16. /** 
  17.  - test index.js typeofAndInstanceOf method 
  18.  - detail: 
  19.  -     typeof null qeual 'object', but null instanceof Object equal false, because null Constructor not Object. 
  20.  */ 
  21. describe('test null is object'function() { 
  22.      
  23.     it('null object'function() { 
  24.         var result = typeofAndInstanceOf(); 
  25.         console.log(result); 
  26.  
  27.         expect(['object'false]).toEqual(result); 
  28.     }); 
  29. }); 
  30.  
  31. /** 
  32.  - test index.js checkOperators method 
  33.  - detail: 
  34.  -     compare operator precedence, + gt ?. 
  35.  */ 
  36. describe('test null is object'function() { 
  37.  
  38.     it('test operator preceence'function() { 
  39.         var result = checkOperators(); 
  40.         console.log(result); 
  41.  
  42.         expect('Something').toEqual(result); 
  43.     }); 
  44. });  

7. 运行 sudo npm run test 执行测试代码


 
 
  1. "scripts": { 
  2.     "test""karma start karma.conf.js" 
  3. }  

结果:

解答

1. npm run test 运行的实际上是 package.json 中配置的命令:


 
 
  1. "test""karma start karma.conf.js" 

2. describe 定义测试模块,it 测试一个单元,describe 内部可以同时定义多个 it,因此可以做一系列的单元测试,测试方法详见官方文档。

3. karma.conf.js 配置 files 设置测试时需要被加载的文件


 
 
  1. files: [ 
  2.     './src/**/*.js'
  3.     './test/unit/specs/*.spec.js' 

总结

希望看完这篇文章,你也能够动起手来,开始编写一些单元测试代码,提高代码的质量,提升自己的周围影响力。本篇文章内容表述了实际项目开发中会遇到的问题,我们可以通过单元测试来减少这类问题的发生,以提高代码的安全性,代码的质量,从而保证产品的稳定性。点击此处查看更多文章。


作者:佚名

来源:51CTO

相关文章
|
2月前
|
设计模式 前端开发 测试技术
告别脆弱:构建稳定UI自动化测试的3个核心策略
告别脆弱:构建稳定UI自动化测试的3个核心策略
320 113
|
3月前
|
存储 关系型数据库 测试技术
玩转n8n测试自动化:核心节点详解与测试实战指南
n8n中节点是自动化测试的核心,涵盖触发器、数据操作、逻辑控制和工具节点。通过组合节点,测试工程师可构建高效、智能的测试流程,提升测试自动化能力。
|
3月前
|
机器学习/深度学习 人工智能 测试技术
EdgeMark:嵌入式人工智能工具的自动化与基准测试系统——论文阅读
EdgeMark是一个面向嵌入式AI的自动化部署与基准测试系统,支持TensorFlow Lite Micro、Edge Impulse等主流工具,通过模块化架构实现模型生成、优化、转换与部署全流程自动化,并提供跨平台性能对比,助力开发者在资源受限设备上高效选择与部署AI模型。
374 9
EdgeMark:嵌入式人工智能工具的自动化与基准测试系统——论文阅读
|
5月前
|
XML jenkins 机器人
JMeter+Ant+Jenkins实现接口自动化测试持续集成
本文介绍了如何使用Ant生成JMeter接口测试报告,并集成到Jenkins中实现自动化测试。内容涵盖Ant与JMeter环境配置、build.xml文件设置、测试执行及报告生成,同时包括Jenkins插件安装、项目配置和钉钉消息通知的集成,帮助实现持续测试与结果可视化。
686 0
|
3月前
|
自然语言处理 前端开发 测试技术
使用 Playwright MCP 实现 UI 自动化测试
本文介绍如何结合Playwright与MCP协议实现智能化UI自动化测试。通过自然语言指令控制浏览器,降低技术门槛,提升效率,并涵盖环境搭建、核心功能、实战案例及最佳实践,展现对话式自动化的未来趋势。
|
5月前
|
人工智能 前端开发 测试技术
如何让AI帮你做前端自动化测试?我们这样落地了
本文介绍了一个基于AI的UI自动化测试框架在专有云质量保障中的工程化实践。
2127 21
如何让AI帮你做前端自动化测试?我们这样落地了
|
5月前
|
Web App开发 开发框架 .NET
Playwright 自动化测试系列(6)| 第三阶段:测试框架集成​指南:参数化测试 + 多浏览器并行执行
Pytest 与 Playwright 集成可提升自动化测试效率,支持参数化测试、多浏览器并行执行及统一报告生成。通过数据驱动、Fixture 管理和并行优化,显著增强测试覆盖率与执行速度,适用于复杂 Web 应用测试场景。
|
4月前
|
人工智能 IDE 测试技术
Browser-Use在UI自动化测试中的应用
Browser-Use是一款浏览器自动化工具,具备视觉与HTML解析、多标签管理、操作记录与复现、自定义操作、自我纠正及并行执行等功能,助力AI智能体高效完成网页任务。
340 0
|
5月前
|
测试技术 API C++
Playwright 自动化测试系列(7)| 第三阶段:测试框架集成​​Page Object 模式
本课程详解Playwright测试框架中的Page Object模式,通过电商登录-下单实战演示PO架构设计与高级技巧,结合Pytest实现多用户测试。重点解析PO模式提升代码复用性、降低维护成本的核心价值,并提供常见问题解决方案,助力构建高可维护性的自动化测试体系。

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    542
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    211
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    209
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    153
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    257
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    375
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    166
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    106
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    176
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    241