一文入门Jest测试

173 阅读4分钟

环境搭建

  1. 生成package.json,执行npm init -y
  2. 下载jest,执行yarn add jest --dev

最基本的测试

  1. 创建被测试的文件以及方法,比如创建:index.js

    function sum(a, b) {
      return a + b;
    }
    
    module.exports = { sum }
    
  2. 创建测试文件,比如:index.test.js

    const {sum} = require('./index.js');
    
    test('sum_test', ()=>{
      expect(sum(2,2)).toBe(3);
    })
    
    /**
     * test('测试说明', ()=>{
     *   expect(被测试的内容).匹配器
     * })
     */
    
    
  3. 修改package.jsontest指令:

    {
      "scripts": {
        "test": "jest"
      }
    }
    
  4. 执行yarn test,查看结果。

    image.png

测试覆盖率生成

代码覆盖率含义:测试时执行的代码占所有源代码的比例

  1. 生成基础配置文件:npx jest --init,生成时会有一些选项如下:

    • Would you like to use Typescript for the configuration file? —— 是否对配置文件使用ts
    • Choose the test environment that will be used for testing —— 选择测试的测试环境(node或者浏览器环境)
    • Do you want Jest to add coverage reports? —— 是否生成代码覆盖率报告
    • Which provider should be used to instrument code for coverage? —— 选择代码覆盖率标准的厂家(v8或者babel)
    • Automatically clear mock calls, instances and results before every test? —— 在每次测试之前自动清除模拟调用、实例和结果
  2. 选择之后,就可以在项目根目录中看见jest.config.js,以上的问题可以通过配置文件来修改

  3. 修改配置文件中的collectCoveragetrue。(如果上面问题已经选择生成覆盖率可以不改)

  4. 执行npx jest --coverage来查看代码覆盖率信息:

    image.png

  5. 同时,在根目录中会生成一个coverage文件。里面是代码覆盖率信息的文件。可以打开其中的lcov-report/index.html查看

    image.png

常用的匹配器

所有匹配器地址,点击查看

  1. toBe()匹配器

    toBe()匹配器类似===,会比较结果是不是绝对等于

    test('toBe()匹配器', ()=>{
        expect('test').toBe('test');
    })
    
    // 测试不通过
    test('toBe()匹配器2', ()=>{
        const obj = {name:'zs'};
        expect(obj).toBe({name:'zs'});
    })
    
  2. toEqual()匹配器

    toEqual()只是比较想等,类似于==

    test('toEqual()匹配器', ()=>{
        expect('test').toEqual('test');
    })
    
    test('toEqual()匹配器2', ()=>{
        const obj = {name:'zs'};
        expect(obj).toEqual({name:'zs'});
    })
    
  3. toBeNull()匹配器

    toBeNull()匹配器是只有返回值为null时才通过匹配.

    test('toBeNull()匹配器', ()=>{
        const a = null;
        expect(a).toBeNull();
    })
    
    // undefined也不可以通过测试!
    test('toBeNull()匹配器2', ()=>{
        let a;
        expect(a).toBeNull();
    })
    
  4. toBeUndefined()匹配器

    toBeUndefined()匹配器,只有当返回值为undefined时才可以通过

    // 测试不通过,值为null
    test('toBeUndefined()匹配器', ()=>{
        const a = null;
        expect(a).toBeUndefined();
    })
    
    test('toBeUndefined()匹配器2', ()=>{
        let a;
        expect(a).toBeUndefined();
    })
    
  5. toBeDefined()匹配器

    toBeDefined()匹配器,只要值定义过就可以通过

    test('toBeDefined()匹配器', ()=>{
        const a = null;
        expect(a).toBeDefined();
    })
    
    test('toBeDefined()匹配器2', ()=>{
        let a = '111';
        expect(a).toBeDefined();
    })
    
  6. toBeTruThy()匹配器和toBeFalsy()匹配器

    toBeTruThy()匹配器是只要为true就通过测试,toBeFalsy()匹配器则为false就通过

    test('toBeTruthy()匹配器', ()=>{
        const a = '111';
        expect(a).toBeTruthy();
    })
    
    test('toBeFalsy()匹配器', ()=>{
        let a = null;
        expect(a).toBeFalsy();
    })
    
  7. toBeGreaterThan()匹配器和toBeGreaterThanOrEqual()匹配器

    toBeGreaterThan()匹配器用来和数字做比较,可以理解成大于 >,而toBeGreaterOrEqual()则可以理解成大于等于>=

    test('toBeGreaterThan()匹配器', ()=>{
        const num = 10;
        expect(num).toBeGreaterThan(9);
    })
    
  8. toBeLessThan()匹配器和toBeLessThanOrEqual()匹配器

    toBeLessThan()匹配器可以理解是小于<,而toBeLessThanOrEqual()则是小雨等于

    test('toBeLessThan()匹配器', ()=>{
        const num = 10;
        expect(num).toBeLessThan(11);
    })
    
  9. toBeCloseTo()匹配器

    toBeCloseTo()匹配器可以自动消除js浮点精确度错误。

    // 测试不通过
    test('toBeEqual', ()=>{
        expect(0.1+0.2).toEqual(0.3);
    })
    
    test('toBeCloseTo()匹配器', ()=>{
        expect(0.1+0.2).toBeCloseTo(0.3);
    })
    
  10. toMatch()匹配器

    toMatch()匹配器,类似于includes,判断字符串是否包含指定内容

    test('toMatch()匹配器', ()=>{
        const str = '苹果、柿子、鸭梨、葡萄';
        expect(str).toMatch('柿子2');
    })
    
  11. toContain()匹配器

    toContain()匹配器类也是类似于includes,只是它用于数组和Set

    test('toContain()匹配器', ()=>{
        const arr = ['苹果','柿子','鸭梨',"葡萄"];
        expect(arr).toContain('柿子');
    })
    
    test('toContain()匹配器2', ()=>{
        const arr = ['苹果','柿子','鸭梨',"葡萄"];
        const set = new Set(arr);
        expect(set).toContain('柿子');
    })
    
  12. toThrow()匹配器

    toThrow()匹配器,只要抛出异常,就通过测试

    test('toThrow()匹配器', ()=>{
        const fn = ()=>{
            throw new Error('error');
        }
        expect(fn).toThrow();
    })
    
    // 如果匹配器传入字符串,异常内容必须和字符串一致才可以通过测试
    test('toThrow()匹配器2', ()=>{
        const fn = ()=>{
            throw new Error('error');
        }
        expect(fn).toThrow('error');
    })
    
  13. not()匹配器

not()匹配器可以理解成取反的意思!not()匹配器可以和其他匹配器一块使用

// 只要内容不是test就可以通过测试
test('not()匹配器', ()=>{
    expect('testaaa').not.toBe('test');
})

异步测试方法

  1. 回调函数测试
// 被测试方法
function fetchData(callback){
    setTimeout(()=>{
        callback({msg:'error'})
    },1500)
}

// jest测试部分
test('fetchData_test', ()=>{
    fetchData((data)=>{
        expect(data).toEqual({msg:'ok'})
    })
})

上面的写法是无论执行成功和失败都是可以通过测试的,因为当执行测试的时候。代码还没有执行完毕。回调还没有执行,所以需要加入一个done方法来保证执行。jest修改为如下内容:

test('fetchData_test', (done)=>{
    fetchData((data)=>{
        expect(data).toEqual({msg:'ok'});
        done();
    })
})

done函数如果一直没有执行,就会认为是测试失败。显示超时错误

  1. Promise测试
// 被测试方法
function fetchData(){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            resolve({msg:'ok'})
        },1500)
    })
}

//jest 测试部分
test('promise_test', ()=>{
    return fetchData().then(data=>{
        expect(data).toEqual({msg:'ok'})
    })
})

3.Async/Await测试

test('async-await_test', async ()=>{
    const data = await fetchData();
    expect(data).toEqual({msg:'ok'})
})