I. Introduction to JEST

Jest is Facebook’s open source JavaScript testing framework that integrates assertions, JSDom, coverage reporting, and all the testing tools developers need.

Official description: a delightful javascript testing framework. My understanding is that there is no need to work overtime to fix the bug, and you can leave work early to drink milk tea with your girlfriend!

Two, Jest start

2.1 installation

# used in projects
yarn init -y
yarn add --dev jest
# or global installation, anytime, anywhere
yarn global add jest  
Copy the code

2.2 hello world (jest)

To write the following two JS files, the console enters the command jest –no-cache –verbose(global installation) or NPX jest –no-cache –verbose(project dependent installation). Jest will search all the test scripts under the project and execute the output test results.

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

it('First unit test'.() = > {
    expect(hello()).toBe('hello world');
});

Copy the code

Three, basic test knowledge

3.1 Naming conventions for JEST files and directories

Under test file: hello. Js test script file name: hello. Test. Jsorhello. Spec. Js test directory: testsor__tests__

3.2 Test Function

test("Column description for test".() = >{})// or
it("Test Case Description".() = >{})Copy the code

3.3 Assertion functions

The assertion function is used to verify that the results are correct

Exspect (operating result). ToBe (desired result);// Common assertion methods
expect({a:1}).toBe({a:1})// Determine whether two objects are equal
expect(1).not.toBe(2)// The judgment is unequal
expect({ a: 1.foo: { b: 2 } }).toEqual({ a: 1.foo: { b: 2 } })
expect(n).toBeNull(); // Check whether it is null
expect(n).toBeUndefined(); // Check whether it is undefined
expect(n).toBeDefined(); // The result is opposite to toBeUndefined
expect(n).toBeTruthy(); // Determine the result to be true
expect(n).toBeFalsy(); // The result is false
expect(value).toBeGreaterThan(3); / / is greater than 3
expect(value).toBeGreaterThanOrEqual(3.5); // Greater than or equal to 3.5
expect(value).toBeLessThan(5); / / less than 5
expect(value).toBeLessThanOrEqual(4.5); // The value is less than or equal to 4.5
expect(value).toBeCloseTo(0.3); // Float values are equal
expect('Christoph').toMatch(/stop/); // Regular expression judgment
expect(['one'.'two']).toContain('one'); / / no explanation
Copy the code

3.4 Grouping function

describe("Unit tests for each feature or component".() = >{
    // Unit tests for different use cases
})
Copy the code

3.5 Common Commands

{
  "nocache": "jest --no-cache".// Clear the cache
  "watch": "jest --watchAll".// Live monitor
  "coverage": "jest --coverage".// Generate coverage test documents
  "verbose": "npx jest --verbose" // Displays the test description
}
Copy the code

4. Basic test

4.1 Object equivalence test

describe('Object Test'.() = > {

    it("Is it the same object?".() = > {
        const foo = { a: 1 }
        expect(foo).toBe(foo)
    })

    it("Are the object values equal?".() = > {
        expect({ a: 1.foo: { b: 2 } }).toEqual({ a: 1.foo: { b: 2 } })
    })

    test('Object assignment'.() = > {
        const data = { one: 1 };
        data['two'] = 2;
        expect(data).toEqual({ one: 1.two: 2 });
    });

});
Copy the code

4.2 Asynchronous Test

When the asynchronous test script is finished, the unit test is finished. If a delay is required to assert the result, the unit test function needs to set the done parameter to be called in the timed callback function to show that the unit test is finished.

describe('Asynchronous operation Test'.() = > {
    function foo(callback) {
        console.log('foo... ')
        setTimeout(() = > {
            callback && callback();
        }, 1000)
    }
    it('Asynchronous test'.(done) = > {
        function bar() {
            console.log('bar.. ')
            done();
        }
        foo(bar);
    });
});

Copy the code

4.3 Timer test (asynchronous test) and assertion

Based on the two methods provided by Jest, jest. UseFakeTimers and jest. RunAllTimers can be more elegant to test the delay function.

describe('Timer related Tests'.() = > {
    // Enable timing function emulation
    jest.useFakeTimers();
    
    function foo(callback) {
        console.log('foo... ')
        setTimeout(() = > {
            callback && callback();
        }, 1000)
    }
    it('Assert asynchronous tests'.() = > {
        // Create mock functions to assert whether the function will be executed or how many times
        const callback = jest.fn();
        foo(callback);
        expect(callback).not.toBeCalled();
        // Fast forward to make all timers callbackjest.runAllTimers(); expect(callback).toBeCalled(); })});Copy the code

4.4 the Dom test

Implementation of DOM rendering tests, as well as click events and other interactive function tests.

describe('the Dom test'.() = > {
    it('Test whether the button is rendered'.() = > {
        document.body.innerHTML = '
      
'
console.log(document.getElementById('btn'), document.getElementById('btn').toString()) expect(document.getElementById('btn')).not.toBeNull(); expect(document.getElementById('btn').toString()).toBe("[object HTMLButtonElement]"); }); it('Test Click event'.() = > { const onclick = jest.fn(); document.body.innerHTML = '
'
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); }); }); Copy the code

V. Vue test

5.1 installation unit – jest

If the project you are creating does not have unit-jest dependencies installed, you can add them by using the vue add@vue /unit-jest command. Otherwise, create a project containing Unit-Jest in scaffolding manual mode.

5.2 Basic Knowledge

Difference between mount and shallowMount

  • ShallowMount mounts only the specified component, not its children
  • Mount Mount all components

Vue’s rendering mechanism By default Vue performs batch updates asynchronously (next tick) to avoid unnecessary DOM redrawing or observer calculations

Asynchronous tests need to be executed after nextTick()

5.3 hello Jest Vue

Vue component rendering test

it('Mount countBtn component'.() = > {
        const wraper = shallowMount(CountBtn);
        const btn = wraper.find("button");
        expect(wraper.html()).toBe(');
    });
Copy the code

5.4 Event Test

Vue component click event test

it('Test the countBtn component and click'.(done) = > {
    const wraper = shallowMount(CountBtn);
    const btn = wraper.find("button");
    expect(wraper.html()).toBe(');
    btn.trigger('click');
    setTimeout(() = > {
        expect(wraper.html()).toBe();
        done();
    }, 1000);
});

it('Elegant test click event'.async() = > {const wraper = shallowMount(CountBtn);
    const btn = wraper.find("button");
    expect(wraper.html()).toBe(');
    btn.trigger('click');
    await wraper.vm.$nextTick();
    expect(wraper.html()).toBe();
});
Copy the code

5.5 AXIOS Asynchronous Request Test

Simulate asynchronous request to test whether the render results are consistent

<! -- 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>
Copy the code
// User.spec.js
import { mount } from '@vue/test-utils';
import User from '@/components/User';

it('Test user Component'.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())
    / / before rendering
    expect(wrapper.html()).toBe('<table></table>');
    await wrapper.vm.$nextTick();
    / / after rendering
    // 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>')});Copy the code

Six, Demo source code

Github address Demo also contains express+restful interface test cases. If you do not want to use Postman test interface, you can use Jest instead.

A little heart to encourage you. 😘 😍 🥰