当前位置: 首页 > 科技观察

前端自动化测试:Jest测试框架应用

时间:2023-03-14 19:28:42 科技观察

Jest:https://jestjs.io/zh-Hans/是Facebook出品的JavaScript开源测试框架。与其他测试框架相比,其一大特点是内置了常用的测试工具,如零配置、自包含断言、测试覆盖率工具等功能,实现开箱即用.Jest适用于但不限于使用以下技术的项目:Babel、TypeScript、Node、React、Angular、Vue等Jest的主要特点:零配置、内置断言作为一个面向前端的测试框架,Jest可以利用其独有的快照测试功能,通过对比UI代码生成的快照文件,实现对React等常见前端框架的自动化测试。Jest的测试用例是并行执行的,只执行变化文件对应的测试,提高了测试速度。测试覆盖率MockSimulate快速体验Jest将Jest安装到项目中:add,subtract}//test.js==>math.test.jsconst{add,subtract}=require('./math')test('测试加法',()=>{expect(add(1,2).toBe(3)})test('测试减法',()=>{expect(subtract(2,1)).toBe(1)})//package.json{"scripts":{"test":"jest"}}jest命令会运行项目中所有以.test.js结尾的文件最后运行测试命令:npmruntest解决方法:jest找到项目中所有以.test.js结尾的文件并运行jest会得到test文件提供了test、expect等全局函数,所以可以在测试文件中直接使用jest,为测试结果提供良好的日志输出,解决vscode中jest代码提示的问题npmi-D@types/jest注意:@types/jest必须安装在项目的根目录下,并以根目录在vscode中打开,否则不会生效。或者只要vscode打开的项目根目录下有@types/jest包。配置文件npxjest--init配置文件生成选项:是否使用ts;使用哪个测试环境;使用jest收集测试覆盖率报告;使用哪个引擎检测覆盖率:v8处于实验阶段,建议在Nodev14之后使用,babel成熟后是否会自动清除每次测试的mock实例;详细配置信息参考:https://jestjs.io/docs/zh-Hans/configuration。//jest.config.js/**关于每个配置属性的详细说明,访问:*https://jestjs.io/docs/en/configuration.html*/module.exports={//自动模拟所有导入的外部模块//automock:false,//在指定的失败次数后停止运行测试//bail:0,//Jest应该存储其缓存依赖信息的目录//cacheDirectory:"/private/var/folders/5h/_98rffpj1z95b_0dm76lvzm40000gn/T/jest_dx",//每次测试之间自动清除mock调用和实例clearMocks:true,//是否收集测试覆盖信息//collectCoverage:false,//一个glob模式数组,表示一组应该收集覆盖信息的文件//collectCoverageFrom:undefined,//测试覆盖率错误文件输出目录coverageDirectory:"coverage",//忽略测试覆盖率统计//coveragePathIgnorePatterns:[//"/node_modules/"//],//指示应该使用哪个provider来检测代码覆盖率,默认babel,可选v8,但是v8不是很稳定,建议使用Node14以上版本//"三叶草"//],//为覆盖结果配置最小阈值强制执行的对象//coverageThreshold:undefined,//Apathtoacustomdependencyextractor//dependencyExtractor:undefined,//MakecallingdeprecatedAPIsthrowhelpfulerrormessages//errorOnDeprecated:false,//Forcecoveragecollectionfromignoredfilesusinganarrayofglobpatterns//forceCoverageMatch:[],//Apathtoamodulewhichexportsanasyncfunctionthatistriggeredoncebeforealltestsuites//globalSetup:undefined,//Apathtoamodulewhichexportsanasyncfunctionthatistriggeredonceafteralltestsuites//globalTeardown:undefined,//Asetofglobalvariablesthatneedtobeavailableinalltestenvironments//globals:{},//Themaximumamountofworkersusedtorunyourtests.Canbespecifiedas%oranumber.E.g.maxWorkers:10%willuse10%ofyourCPUamount+1asthemaximumworkernumber.maxWorkers:2willuseamaximumof2workers.//maxWorkers:"50%",//Anarrayofdirectorynamestobesearchedrecursivelyupfromtherequiringmodule'slocation//moduleDirectories:[//"node_modules"//],//Anarrayoffileextensionsyourmodulesuse//moduleFileExtensions:[//"js",//"json",//"jsx",//"ts",//"tsx",//"node"//],//Amapfromregularexpressionstomodulenamesortoarraysofmodulenamesthatallowtostuboutresourceswithasinglemodule//moduleNameMapper:{},//正则表达式模式字符串数组,在被认为对模块加载程序“可见”之前再次匹配安装模块路径//modulePathIgnorePatterns:[],//Activatesnotificationsfortestresults//notify:false,//Anenumthatspecifiesnotificationmode.Requires{notify:true}//notifyMode:"failure-change",//ApresetthatisusedasabaseforJest'sconfiguration//preset:undefined,//Runtestsfromoneormoreprojects//projects:undefined,//UsethisconfigurationoptiontoaddcustomreporterstoJest//reporters:undefined,//Automaticallyresetmockstatebetweeneverytest//resetMocks:false,//Resetthemoduleregistrybeforerrunningeachindividualtest//resetModules:false,//自定义解析器的路径//解析器:undefined,//Automaticallyrestoremockstatebetweeneverytest//restoreMocks:false,//TherootdirectorythatJestshouldscanfortestsandmoduleswithin//rootDir:undefined,//AlistofpathstodirectoriesthatJestshouldusetosearchforfilesin//roots:[//""//],//AllowsyoutuseacustomrunnerinsteadofJest'sdefaulttestrunner//runner:"jest-runner",//Thepathstomodulesthatberuneachtesttoconfigure一些测试代码//setupFiles:[],//Alistofpathstomodulesthatrunsomecodetoconfigureorsetupthetestingframeworkbeforeeachtest//setupFilesAfterEnv:[],//Thenumberofsecondsafterwhichatestisconsideredasslowandreportedassuchintheresults.//slowTestThreshold:5,//AlistofpathstosnapshotserializermodulesJestshoulduseforsnapshottesting//snapshotSerializers:[],//Thetestenvironmentthatwillbeusedfortesting//testEnvironment:"jest-environment-jsdom",//OptionsthatwillbepassedtothetestEnvironment//testEnvironmentOptions:{},//Addsalocationfieldtotestresults//testLocationInResults:false,//TheglobpatternsJestusestodetecttestfiles//testMatch:[//"**/__tests__/**/*.[jt]s?(x)",//"**/?(*.)+(spec|test).[tj]s?(x)"//],//Anarrayofregexppatternstringsthatarematchedagaininstalltestpaths,matchedtestsareskipped//testPathIgnorePatterns:[//"/node_modules/"//],//TheregexppatternorarrayofpatternsthatJestusestodetecttestfiles//testRegex:[],//Thisoptionallowstheuseofacustomresultsprocessor//testResults,Processor:undefined//Thisoptionallowsuseofacustomtestrunner//testRunner:"jasmine2",//这个选项设置了jsdom环境的URL。它反映在propertiessuchaslocation.href//testURL:"http://localhost",//Settingthisvalueto"fake"allowstheuseoffaketimersforfunctionssuchas"setTimeout"//timers:"real",//Amapfromregularexpressionstopathstotransformers//transform:undefined,//Anarrayofregexppatternstringsthatarematchedagaininstallsourcefilepaths,匹配的文件将跳过转换//transformIgnorePatterns:[//"/node_modules/",//"\\.pnp\\.[^\\/]+$"//],//在模块加载器将自动为它们返回模拟之前匹配的正则表达式模式字符串数组//unmockedModulePathPatterns:undefined,//Indicateseverbwhateachindividualtests:undefined,//Anarrayofregexppatternsthatarematchedagainstallsourcefilepathsbeforere-runningtestsinwatchmode//watchPathIgnorePatterns:[],//是否使用watchman进行文件抓取//watchman:true,};JestCLIOptions参考:https://jestjs.io/zh-Hans/docs/cli指定要运行的测试文件"scripts":{"test":"jest./math.test.js"},Jestwatchmode--watchAll选项:监视文件的变化并在任何变化上重新运行所有测试"scripts":{"test":"jest--watchAll"},JestAPI在测试文件中,Jest将所有这些方法和对象进入全球环境。它们不需要或导入任何东西就可以使用。但是,如果您更喜欢显式导入,则可以:从'@jest/globals'导入{describe,expect,test}测试函数测试函数别名:it(name,fn,timeout)。测试(名称,fn,超时)test.concurrent(名称,fn,超时)test.concurrent.each(表)(名称,fn,超时)test.concurrent.only.each(表)(名称,fn)测试。concurrent.skip.each(table)(name,fn)test.each(table)(name,fn,timeout)test.only(name,fn,timeout)只运行当前测试用例test.only.each(table)(name,fn)test.skip(name,fn)test.skip.each(table)(name,fn)test.todo(name)创建一个global-api.test.js测试文件,注意必须有一个测试文件中的Testcase,如果没有,直接报错。测试('应该',()=>{console.log('test--api')})测试('应该',()=>{console.log('test--api')})测试('should1',()=>{console.log('test--api1')})//以上两个不运行test.only('should2',()=>{console.log('test--api2')})Expectmatchers在编写测试时,经常需要检查一个值是否满足某些条件。Expect使我们能够访问许多“匹配器”来验证不同的事物。测试('twoplustwoisfour',()=>{expect(2+2).toBe(6)expect({name:'jack'}).toEqual({name:'jack'})expect('Christoph').toMatch(/stop/)expect(4).toBeGreaterThan(3)expect(4).toBeLessThan(5)})匹配器的完整列表:https://jestjs.io/zh-Hans/docs/expectdescribe函数描述创建一个将几个相关测试组合在一起的块。constmyBeverage={delicious:true,sour:false,};describe('mybeverage',()=>{test('isdelicious',()=>{expect(myBeverage.delicious).toBeTruthy();});测试('isnotsour',()=>{expect(myBeverage.sour).toBeFalsy();});});分组最直观的一点就是在测试提示中有更友好的信息输出。describe(name,fn)describe.each(table)(name,fn,timeout)describe.only(name,fn)describe.only.each(table)(name,fn)describe.skip(name,fn)描述。跳过。每个(表)(名称,fn)