Coder Social home page Coder Social logo

jest-study-demo's Introduction

一、JEST简介

Jest是Facebook开源的一套JavaScript测试框架, 它集成了断言、JSDom、覆盖率报告等开发者所需要的所有测试工具。

官方简介:一个令人愉快的javascript测试框架。 我的理解是,不用加班改bug了,可以提前下班,陪女朋友喝奶茶!

二、jest启步

2.1 安装

# 项目中使用
yarn init -y
yarn add --dev jest
# 或者全局安装,随时随地使用
yarn global add jest  

2.2 hello world(jest)

编写以下两个js文件,控制台输入命令jest --no-cache --verbose(全局安装),或者npx jest --no-cache --verbose(项目依赖安装),jest会搜索项目下所有测试脚本并执行输出测试结果。

// hello.js
module.exports = function(){
    return "hello world";
}
// hello.test.js
const hello = require('../hello');

it('should ', () => {
    expect(hello()).toBe('hello world');
});

三、基础测试知识

3.1 jest文件和目录命名规范

待测试文件: hello.js 测试脚本文件取名:hello.test.jsorhello.spec.js 测试目录:testsor__tests__

3.2 测试函数

test("测试用列描述信息",()=>{

})
// or
it("测试用例描述信息",()=>{

})

3.3 断言函数

测试即运行结果是否与我们预期结果一致 断言函数用来验证结果是否正确

exspect(运行结果).toBe(期望的结果);
//常见断言方法
expect({a:1}).toBe({a:1})//判断两个对象是否相等
expect(1).not.toBe(2)//判断不等
expect({ a: 1, foo: { b: 2 } }).toEqual({ a: 1, foo: { b: 2 } })
expect(n).toBeNull(); //判断是否为null
expect(n).toBeUndefined(); //判断是否为undefined
expect(n).toBeDefined(); //判断结果与toBeUndefined相反
expect(n).toBeTruthy(); //判断结果为true
expect(n).toBeFalsy(); //判断结果为false
expect(value).toBeGreaterThan(3); //大于3
expect(value).toBeGreaterThanOrEqual(3.5); //大于等于3.5
expect(value).toBeLessThan(5); //小于5
expect(value).toBeLessThanOrEqual(4.5); //小于等于4.5
expect(value).toBeCloseTo(0.3); // 浮点数判断相等
expect('Christoph').toMatch(/stop/); //正则表达式判断
expect(['one','two']).toContain('one'); //不解释

3.4 分组函数

describe("关于每个功能或某个组件的单元测试",()=>{
    // 不同用例的单元测试
})

3.5 常见命令

{
  "nocache": "jest --no-cache", //清除缓存
  "watch": "jest --watchAll", //实时监听
  "coverage": "jest --coverage",  //生成覆盖测试文档
  "verbose": "npx jest --verbose" //显示测试描述
}

四、基础测试

4.1 对象等值测试

describe('对象测试', () => {

    it("是否同一个对象", () => {
        const foo = { a: 1 }
        expect(foo).toBe(foo)
    })

    it("对象值是否相等", () => {
        expect({ a: 1, foo: { b: 2 } }).toEqual({ a: 1, foo: { b: 2 } })
    })

    test('对象赋值', () => {
        const data = { one: 1 };
        data['two'] = 2;
        expect(data).toEqual({ one: 1, two: 2 });
    });

});

4.2 异步测试

异步测试脚本执行完,单元测试就结束了,如果需要延时才能断言的结果,单元测试函数需要设置done形参,在定时回调函数中调用,显示的通过单元测试已完成。

describe('异步操作测试',  () => {
    function foo(callback) {
        console.log('foo...')
        setTimeout(() => {
            callback && callback();
        }, 1000)
    }
    it('异步测试', (done) => {
        function bar() {
            console.log('bar..')
            done();
        }
        foo(bar);
    });
});

4.3 定时器测试(异步测试)及断言

基于jest提供的两个方法jest.useFakeTimersjest.runAllTimers可以更优雅的对延时功能的测试。

describe('定时器相关测试', () => {
    // 开启定时函数模拟
    jest.useFakeTimers();
    
    function foo(callback) {
        console.log('foo...')
        setTimeout(() => {
            callback && callback();
        }, 1000)
    }
    it('断言异步测试', () => {
        //创建mock函数,用于断言函数被执行或是执行次数的判断
        const callback = jest.fn();
        foo(callback);
        expect(callback).not.toBeCalled();
        //快进,使所有定时器回调
        jest.runAllTimers();
        expect(callback).toBeCalled();
    })
});

4.4 Dom测试

实现dom渲染测试,以及点击事件等交互功能测试。

describe('Dom测试', () => {
    it('测试按钮是否被渲染 ', () => {
        document.body.innerHTML = `
    <div>
        <button id='btn'>小按钮</button>
    </div> `
        console.log(document.getElementById('btn'), document.getElementById('btn').toString())
        expect(document.getElementById('btn')).not.toBeNull();
        expect(document.getElementById('btn').toString()).toBe("[object HTMLButtonElement]");
    });

    it('测试点击事件', () => {
        const onclick = jest.fn();
        document.body.innerHTML = `
        <div>
            <button id='btn'>小按钮</button>
        </div> `
        const btn = document.getElementById('btn');
        expect(onclick).not.toBeCalled();
        btn.onclick = onclick;
        btn.click();
        expect(onclick).toBeCalled();
        expect(onclick).toHaveBeenCalledTimes(1);
        btn.click();
        btn.click();
        expect(onclick).toHaveBeenCalledTimes(3);
    });
});

五、Vue测试

5.1 安装unit-jest

如果你创建的项目没有安装unit-jest依赖包,可以通过vue add @vue/unit-jest命令添加。否则通过脚手架手动模式创建一个包含unit-jest的项目。

5.2 基础知识

mount和shallowMount的区别

  • shallowMount只挂载指定组件,不挂载子组件
  • mount挂载所有组件

Vue的渲染机制 默认情况下 Vue 会异步地批量执行更新 (在下一轮 tick),以避免不必要的 DOM 重绘或者是观察者计算

异步测试需要在nextTick()之后执行

5.3 hello Jest Vue

vue组件渲染测试

it('挂载countBtn组件', () => {
        const wraper = shallowMount(CountBtn);
        const btn = wraper.find("button");
        expect(wraper.html()).toBe(`<button>点击次数0</button>`);
    });

5.4 事件测试

vue组件点击事件测试

it('测试countBtn组件点击', (done) => {
    const wraper = shallowMount(CountBtn);
    const btn = wraper.find("button");
    expect(wraper.html()).toBe(`<button>点击次数0</button>`);
    btn.trigger('click');
    setTimeout(() => {
        expect(wraper.html()).toBe(`<button>点击次数1</button>`);
        done();
    }, 1000);
});

it('优雅的测试点击事件', async () => {
    const wraper = shallowMount(CountBtn);
    const btn = wraper.find("button");
    expect(wraper.html()).toBe(`<button>点击次数0</button>`);
    btn.trigger('click');
    await wraper.vm.$nextTick();
    expect(wraper.html()).toBe(`<button>点击次数1</button>`);
});

5.5 axios异步请示测试

模拟异步请示,测试渲染结果是否一致

<!-- User.vue -->
<template>
<table>
    <tr v-for="item in list" :key="item.id">
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td>{{item.age}}</td>
    </tr>
</table>
</template>

<script>
export default {
    data() {
        return {
            list: []
        }
    },
    created() {
        this.$http.get('/user').then(({
            data
        }) => {
            this.list = data
        })
    }
}
</script>
// User.spec.js
import { mount } from '@vue/test-utils';
import User from '@/components/User';

it('测试用户组件', async() => {
    const wrapper = mount(User,{
        mocks:{
            $http:{
                get: url=>Promise.resolve({data:[{id:1,name:'xxxx',age:18},{id:2,name:'yyyy',age:19}]})
            }
        }
    })
    console.log(wrapper.html())
    // 渲染前
    expect(wrapper.html()).toBe('<table></table>');
    await wrapper.vm.$nextTick();
    // 渲染后
    // console.log(wrapper.html())
    // console.log(wrapper.find('tr'))
    expect(wrapper.findAll('tr').length).toBe(2)
    expect(wrapper.findAll('td').at(2).html()).toBe('<td>18</td>')
    
});

六、demo源码

github地址 demo中还包含express+restful接口的测试用例,不想用postman测试接口的同学,可以用jest来代替。

顺手点个小爱心,以示鼓励。😘😍🥰

jest-study-demo's People

Contributors

calcyu avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.