Jest单元测试进阶

Jest 命令行窗口中的指令

在学习Jest单元测试入门的时候,我们给Jest命令提供了一个参数 --watchAll, 让它监听测试文件或测试文件引入的文件的变化,从而时时进行测试。但这样做也带来一个问题,只要改变一点内容,Jest就会把所有的测试都跑一遍,有点浪费资源。有没有可能对--watchAll模式进行进一步的优化,那是有的, 在什么地方呢?在命令窗口中。执行npm run test, 测试完成后,你会发现还有很多提示(Watch Usage),这些就是对--watchAll模式的优化

Jest单元测试进阶

   Press f to run only failed tests.  按f 键,进入一种模式,它只跑失败的测试用例。当我们执行npm run test 的时候,发现有一个测试失败了,这时我们只想跑失败的测试用例,那就按f吧。演示一下,随便把一个测试用例改为错误,比如 把request 的mock 改为name: ‘jason‘

jest.mock(‘request‘, () => {
    return (url, callback) => {
        callback(null, ‘ok‘, {name: ‘jason‘})
    }
});

   这时测试重新跑了一遍了(watchAll 模式),命令窗口中显示了错误, 并且在最下面显示press w to show more,  同时光标在闪烁,等待输入。此时按w,  显示了上图中的内容,再按f, 只跑了失败的测试,因为三个测试skipped 了, 当然肯定还是有错误,因为我们还没有修改测试代码

Jest单元测试进阶

   此时修改测试代码到正确并保存,测试成功,不过它也是跑了刚才错误的测试。此时你再修改func.test.js 文件或其它测试用例,发现测试不会再运行了,显示No failed test found.Jest单元测试进阶

这时就要退出f 模式了, Jest 也提示了,按f键退出 ‘只跑失败测试’ 的模式。此时按f, 重新回到了watchAll 模式,把所有的测试用例重新跑了一遍。

f 模式的使用就是,npm run  test 有失败测试,按f,  修改失败到成功,再按f 退出该模式。

Press o to only run tests related to changed files.  按o ,只跑改变文件中的测试。Jest 会实时监听文件的变化,如果哪个文件发生变化,它会跑哪个文件中的测试,其它没有变化的文件中的测试,它是不会跑的。那Jest是怎么知道哪个文件发生变化的呢?它自己不知道,需要借助git. 因为git 就是追踪文件变化的。只要把工作区和仓库区的代码一对比,就知道哪个文件发生变化了。那就要把项目变成git 项目。在根目录下,先建.gitignore 文件,再执行git init, 把项目变成git 项目,否则会把node_modules 放到 git 仓库中。此时为了对比,把func.test.js拆分为三个测试文件,fetchData.test.js,  forEach.test.js, math.test.js 

jest.mock(‘request‘, () => {
    return (url, callback) => {
        callback(null, ‘ok‘, {name: ‘sam‘})
    }
});

const fetchData = require(‘./func‘).fetchData;

test(‘should return data when fetchData request success‘, () => {
   return fetchData().then(res => {
       expect(res).toEqual({name: ‘sam‘})
   })
})
const forEach = (array, callback) => {
    for (let index = 0; index < array.length; index++) {
        const element = array[index];
        callback(element);
    }
}

test(‘should call callback when forEach‘, () => {
    const mockFun = jest.fn(); // mock 函数
    const array = [1, 2];

    forEach(array, mockFun); // 用mock函数代替真实的回调函数
    expect(mockFun.mock.calls.length).toBe(2)
})
const math = require(‘./func‘);

test("calls math.add", () => {
  const addMock = jest.spyOn(math, "add");

  // override the implementation
  addMock.mockImplementation(() => "mock");
  expect(addMock(1, 2)).toEqual("mock");

  // restore the original implementation
  addMock.mockRestore();
  expect(addMock(1, 2)).toBeUndefined();
});

test(‘should call add‘, () => {
    function callMath(a, b) {
        return math.add(a + b);
    }
    const addMock = jest.spyOn(math, ‘add‘);
    callMath(1, 2);
    expect(addMock).toBeCalled();  // toBeCalled, 就是函数有没有被调用。
})

git add . and git commit -m "init git" 把文件提交到git 仓库。这时再执行npm run test, 启动测试,直接按o ,进入到o 模式, 可以看到提示,没有文件发生变化。

Jest单元测试进阶

   这时更改一个文件,如forEach 加一个空行,看一下控制台,只有forEach.test.js 测试文件执行了,其它测试文件并没有执行, 再改一个fetchData.test.js 文件,两个测试文件执行了,还是只跑改变的文件中的测试。这时让我想起了jest 命令的另一个参数,--watch,  -o 模式 不就是--watch 吗。把package.json 中的 --watchAll 改成 --watch 

"scripts": {
    "test": "jest --watch"
},

重新启动npm run test, 有了-a模式,run all the tests, 这不就是--watchAll,  原来 --watch,  --watchAll,  a 模式,o 模式,是这样时行互通的。

Jest单元测试进阶

   再看一下p,  按照文件名执行测试,我们提供一个文件名,它只会对该文件进行测试,可以使用正则表达式来匹配文件名。按p,  提示输入pattern,  再输入fetch,  它就会用fetch 去匹配所有的测试文件名,找到了fetchData.test.js 测试文件,然后它就执行了。如果找不到任何测 试文件,它什么测试都不会执行。

Jest单元测试进阶

   t 则是匹配的test 名字,每一个test 都有一个描述,这个描述可以称之为test 的名字。提供一个test 的名字,它只跑这个test,用法和p 一样。

q 退出watch, enter 就是跑一次单元测试,无论是在什么模式下,只要按enter,就会跑一次对应模式的测试。

相关推荐