大家好,我叫CUGGZ。在前端测试中,框架可以提取测试代码,整体设计测试用例并进行结构化,放入专门的测试文件中,还可以实现测试结果的自动运行和显示。一起来看看常用的测试框架,有什么优缺点吧!前端测试通常可以分为以下三种:单元测试:将代码的各个部分分开,检查和验证软件中最小的可测试单元;集成测试:测试多个单元是否可以协同工作;端到端测试(E2E):从头到尾测试整个软件产品,以确保应用程序流程按预期运行。stateofjs2022:前端测试框架流行榜JestJest是Facebook开发的JavaScript测试框架。它是测试React的首选,由React社区支持和开发。Jest具有以下特点:兼容性:除了可以测试React应用外,还可以方便地集成到其他应用中,兼容Angular、Node、Vue等基于babel的项目。AutomaticMocking:当导入测试文件中的库时,Jest会自动mock这些库,帮助我们轻松使用。扩展的API:Jest提供了一个扩展的API,你不需要包含额外的库,除非你真的需要它。计时器模拟:Jest有一个时间模拟系统,非常适合在您的应用程序中快速转发超时,并有助于在运行测试时节省时间。活跃的社区:Jest有一个活跃的社区,可以帮助我们在需要时快速找到解决方案。示例代码:constsum=require('./sum');test('1+2=3',()=>{expect(sum(1,2)).toBe(3);});}Github:https://github.com/facebook/jestMochaMocha是一个功能丰富的JavaScript测试框架,可以运行在Node.js和浏览器中,让异步测试变得简单有趣。Mocha测试持续运行,允许灵活和准确的报告,同时将未捕获的异常映射到正确的测试用例。Mocha不支持开箱即用的断言、模拟等,这些功能需要通过组件/插件添加。与Mocha配合使用的最流行的断言库包括Chai、Assert、Should.js和Better-assert。Mocha具有以下特点:使用简单:对于不包含复杂断言或测试逻辑的较小项目,Mocha是一个简单的解决方案。ES模块支持:Mocha支持将测试编写为ES模块,而不仅仅是使用CommonJS。当然,Mocha也有缺点:设置困难:必须使用额外的断言库,这确实意味着它比其他库更难设置。与插件的潜在不一致:Mocha将测试结构作为全局变量包含在内,通过不必在每个文件中使用includeor来节省时间。require的缺点是插件可能无论如何都需要包含这些,从而导致不一致。不支持任意转译器:在v6.0.0之前,Mocha有一个允许任意转译器的功能,例如coffee-script等,但现在已弃用。示例代码:varassert=require('assert');describe('Array',function(){describe('#indexOf()',function(){it('当值不存在时应该返回-1',function(){assert.equal([1,2,3].indexOf(4),-1);});});});Github:https://github.com/mochajs/mochaCypressCypress是用于现代Web构建的下一代前端测试工具。借助Cypress,开发人员可以编写端到端测试、集成测试和单元测试。Cypress完全在真正的浏览器(Chrome、Firefox和Edge)中运行,不需要驱动程序二进制文件。自动化代码和应用程??序代码共享同一个平台,使开发人员能够完全控制被测应用程序。Cypress以其端到端测试功能而闻名,这意味着遵循预定义的用户行为,并让该工具在每次部署新代码时报告潜在的差异。Cypress特性:端到端测试:因为Cypress在真实浏览器中运行,所以您可以依赖它进行端到端用户测试。时间线快照测试:在执行过程中,赛普拉斯会拍摄那一刻的快照,并允许开发人员或QA测试人员查看特定步骤发生的情况。稳定可靠:与其他测试框架相比,Cypress提供了稳定可靠的测试执行结果。文档和社区:从零到运行,Cypress包括所有必要的信息来帮助开发人员加快速度,并且它有一个活跃的社区。快速:赛普拉斯的测试执行速度很快,响应时间不到20毫秒。但是,需要注意的是,Cypress只能在单个浏览器中运行测试。示例代码:Cypress.Commands.add('login',(username,password)=>{cy.visit('/login')cy.get('input[name=username]').type(username)//{enter}导致表单提交cy.get('input[name=password]').type(`${password}{enter}`,{log:false})//我们应该被重定向到/dashboardcy.url().should('include','/dashboard')//我们的authcookie应该存在cy.getCookie('your-session-cookie').should('exist')//UI应该反映这个用户正在登录cy.get('h1').should('contain',username)})it('doessomethingonasecuredpage',function(){const{username,password}=this.currentUsercy.login(username,password)//...})Github:https://github.com/cypress-io/cypressStorybook与其他JavaScript测试框架不同,Storybook是一个提供隔离环境的UI测试工具。Storybook还附带了工具、测试运行器以及与更大的JavaScript生态系统的轻松集成,以扩展UI测试覆盖范围。有几种方法可以使用Storybook进行UI测试:视觉测试:捕获每个故事的屏幕截图并将它们与基线进行比较以检测外观和集成问题。辅助功能测试:发现与视觉、听觉、移动、认知、语言或神经障碍相关的可用性问题。交互测试:通过模拟用户行为、触发事件和确保状态按预期更新来验证组件功能。快照测试:检测渲染标记的变化以显示表面渲染错误或警告。将来自其他测试的故事导入QA甚至更多UI功能。Github:https://github.com/storybookjs/storybookJasmineJasmine是一个简单的JavaScript单元测试框架,不依赖于任何浏览器、DOM或任何JavaScript。它适用于任何网站、Node.js项目或任何可以在JavaScript上运行的程序。Jasmine被称为行为驱动开发(BDD)工具。BDD涉及在编写实际代码之前编写测试(与测试驱动开发(TDD)相反)。Jasmine具有以下特点:简单的API:它提供简洁易懂的语法,以及丰富直接的API来编写单元测试。开箱即用:不需要额外的断言或模拟库,开箱即用。快速:相对较快,因为它不依赖于任何外部库。多语言:不仅可以用于编写JS测试,还可以用于Ruby(通过Jasmine-gem)或Python(通过Jsmin-py)当然,Jasmine也有缺点:它会污染全局环境:默认情况下,它会创建测试全局变量(关键字,如“describe”或“test”),因此它们不必在测试中导入。在某些情况下,这可能是一个缺点。编写异步测试具有挑战性:使用Jasmine测试异步函数很困难。示例代码:describe("helloWorld",()=>{it("returnshelloworld",()=>{varactual=helloWorld();expect(actual).toBe("helloworld");});})Github:https://github.com/jasmine/jasmineReactTestingLibraryReactTestingLibrary在DOMTestingLibrary的基础上增加了一些API,主要用于测试React组件。该库在使用过程中并不关注组件的内部实现,更多的是测试。该库基于react-dom和react-dom/test-utils,是两者的轻量级实现。ReactTestingLibrary不像Jest那样是测试运行器。事实上,他们可以一起工作。React测试库是一组工具和功能,可帮助访问DOM并对其执行操作,即将组件渲染到虚拟DOM中,搜索并与之交互。ReactTestingLibrary具有以下特点:React官方推荐:可以在React的官方文档中找到使用该库的参考和建议。体积小:专为测试React应用程序/组件而编写。演示代码:演示代码:importReact,{useEffect}from'react'importReactDOMfrom'react-dom'import{render,fireEvent}from'@testing-library/react'constmodalRoot=document.createElement('div')modalRoot.setAttribute('id','modal-root')document.body.appendChild(modalRoot)constModal=({onClose,children})=>{constel=document.createElement('div')useEffect((){modalRoot.appendChild(el)return()modalRoot.removeChild(el)})returnReactDOM.createPortal(
