Istanbul (伊斯坦布尔)是一个基于 JavaScript 的测试覆盖率统计工具,目前绝大多数测试框架比如 jest mocha 等都是使用 Istanbul 来统计覆盖率的。
istanbul 最新的版本为: nyc,官方站点为:https://istanbul.js.org,github: https://github.com/istanbuljs/nyc。下面将简称 Istanbul 为 nyc
传统的前端项目测试,假设使用 mocha 测试,我们会执行以下的测试用例:
`mocha test/suite/\*_/_.spec.js`
接着开发者安装 nyc npm 类库(npm install nyc -D),然后加个 nyc 前缀就会自动 完成运行时的覆盖统计与最终结果展现;
// nyc 无参数的默认用法 nyc mocha test/suite/**/\*.spec.js // nyc 携带参数:html 格式 nyc --reporter=html mocha test/suite/**/\*.spec.js // 也可以通过项目根目录增加配置文件(如:nyc.config.js)的形式,然后执行上面的命令 module.exports = { reporter: ['html'] }
该命令执行时,会依次完成以下几件事:
将项目 src 源码目录中的 JS 文件做转换并缓存起来;
接着将后面的 mocha 参数放到子进程(child_process)执行,即:调用 mocha 执行测试用例;
测试用例中所测试的 src 源码文件实际是上面的缓存文件,期间完成的语句与分支执行的统计,记录在 JS 内存的某个变量中;
子进程的测试用例执行结束之后,将统计数据发送给 nyc 命令所在线程并保存到文件,默认目录名为:.nyc_output,它记录了本次测试的代码覆盖最完整的数据;
nyc 线程内部调用 report 方法,完成从原始数据到可读性良好的内容转换;它会将 .nyc_output 目录中的数据读取出来,并使用 html 格式 进行转换,并默认生成在目录 coverage 下;
cypress 是通过模拟用户点击来测试的端到端测试框架,它也允许你编写集成测试与单元测试。
Cypress 是用的真正的后端数据,而不是 mock 一个数据然后测试组件行为。所以在测试时最好不要使用线上环境,这会使得后端写入很多测试脏数据。最好的就是在专门的沙箱环境测试,如果有租户概念可用新租户,测试时机为发起 MR 代码时。
Cypress 主要用于跑通主流程,测试的是预期内的东西,而对于有大量计算或复杂判断的纯函数方法而言,单测肯定是更好。
Given a compressed string, return its original form.
For example.
uncompress('3(ab)') // 'ababab' uncompress('3(ab2(c))') // 'abccabccabcc'
a number k
followed by a pair of parenthesis, meaning to repeat the substring inside the parenthesis by k
times, k
is positive integer.
inputs are guaranteed to be valid input like above example, there is no numerical digit in original form.
npm 离不开 package.json
,要了解 npm 的运行机制,我们先看看 package.json
文件是做什么的。首先 package.json
文件是每个前端项目存在于根目录的文件,包含了项目的一些基本信息(例如项目名称,版本号,描述,一些脚本,依赖等等),大致的结构如下:
{ "name": "whyknown", "version": "1.0.0", "description": "whyknown,前端开发者必备网站", "main": "src/index.js", "scripts": { "start": "node index.js", "lint": "eslint **/*.js" }, "dependencies": { "express": "^4.16.4", "compression": "~1.7.4" }, "devDependencies": { "eslint": "^5.16.0", "nodemon": "^1.18.11" }, "repository": { "type": "git", "url": "https://github.com/xxx.git" }, "author": "whyknown", "contributors": [ { "name": "whyknown", "email": "example@example.com", "url": "https://www.whyknown.com" } ], "keywords": ["server", "osiolabs", "express", "compression"] }
我们这里重点关注 script
的配置,该配置罗列了一些可以运行的脚本,当我们在根目录执行 npm run
或者 yarn run
的时候,就会去调用这里的命令。我们拿上面的 start 命令来讲解。
compose
compose 是函数式编程中一个非常重要的函数,compose 的函数作用就是组合函数的,将函数串联起来执行。将多个函数组合起来,一个函数的输出结果是另一个函数的输入参数,一旦第一个函数开始执行,就会像多米诺骨牌一样推导执行了。
2.1 简单例子
比如有这样的需求,输入一个名字
yideng
,然后全部变成大写,打印输出HELLO YIDENG
,我们可以考虑用函数组合的方法来解决这个问题,需要两个函数greeting、toUpper
。const greeting = (name) => `hello ${name}`; const toUpper = (str) => str.toUpperCase(); const fn = compose(toUpper, greeting); console.log(fn("yideng")); // HELLO YIDENG
这就是 compose 的大致使用,主要有以下几点:
- compose 参数是函数,返回也是一个函数
- 除了第一个函数接受参数,其它函数接受的都是上一个函数的返回值,所以初始函数的参数是多元的,而其它函数的接受值是一元的。
- compose 函数可以接受任意的参数,所有的参数都是函数,且执行方向是自右向左的,初始函数一定放到参数的最右面。