Why did you choosejest

Jest is a testing framework developed on Facebook that makes testing easier for me. Jest automatically integrates assertions, JSDom, coverage reporting, and all the testing tools a developer needs, making it a testing framework with almost zero configuration.

Actually, my reason is because

  • It is an open source JavaScript testing framework
  • I haven’t used anything else
  • Welcome everyone to speak out 🙂

Install Nuxt

NPM run test

Write an example yourself

Create two new files in the test directory

  • sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;

Copy the code
  • sum.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1.2)).toBe(3);
});

Copy the code

Run again

Enter the project and open the file jest.config.js

  • collectCoverage
    • This can slow down your test execution significantly by revisiting all executed files with coverage collection statements
module.exports = {
  moduleNameMapper: { / / similar webpack. Resolve. Alias
    '^ @ / (. *) $': '<rootDir>/$1'.'^ ~ / (. *) $': '<rootDir>/$1'.'^vue$': 'vue/dist/vue.common.js'
  },
  moduleFileExtensions: ['js'.'vue'.'json']./ / similar webpack. Resolve. Extensions
  transform: { / / similar webpack. Module. Rules
    '^.+\\.js$': 'babel-jest'.'.*\\.(vue)$': 'vue-jest'
  },
  'collectCoverage': false.// Indicates whether coverage information is collected at test time
  'collectCoverageFrom': [ // 类似 webpack 的 rule.include
    '<rootDir>/components/**/*.vue'.'<rootDir>/pages/**/*.vue']}Copy the code

Run again

collectCoverageFrom

Vscode set

Install the jest

Configure in the file directoryjest.configThe path

You can now see the output of Jest in real time

Write your first vue.js component unit test in Jest

The official VueJS test library vue/test-utils

incomponentsDirectory, add a few files

  • MessageList.vue
<template>
    <ul>
        <li v-for="message in messages">
            {{ message }}
        </li>
    </ul>
</template>

<script>
export default {
  name: 'list'.props: ['messages']}</script>
Copy the code

Example Modify index.vue in the Pages directory


<template>
  <div id="app">
    <MessageList :messages="messages" />
  </div>
</template>

<script>
import MessageList from "~/components/MessageList";
export default {
  name: "app".data: (a)= > ({ messages: ["Hey John"."Howdy Paco"]}),components: {
    MessageList
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Copy the code

Start writing our test file

Write a file named index.test.js in the test directory

import Vue from "vue";
import pageIndex from '@/pages/index.vue'

describe("index.test.js", () = > {let cmp, vm;

  beforeEach((a)= > {
    cmp = Vue.extend(pageIndex); // Create a copy of the original component
    vm = new cmp({
      data: {
        // Replace data value with this fake data
        messages: ["Cat"]
      }
    }).$mount(); // Instances and mounts the component
  });

  it('equals messages to ["Cat"]', () => {
    expect(vm.messages).toEqual(["Cat"]);
  });

Copy the code

Look at the input/NPM run test, the test should run and pass.

Snapshots function

Add an IT

it("has the expected html structure", () => {
    expect(vm.$el).toMatchSnapshot();
 });
Copy the code

Run again generates the following file

There’s a big problem here: Unit tests must be tested as a separate unit, which means index.test.js we test APP components without affecting anything else. Imagine, for example, that a child component (MessageList in this case) performs a side effect operation on a Created hook, such as calling a FETCH, Vuex action, or state change? Isn’t that what we want?

Shallow rendering

Shallow shading is a technique for ensuring that components are rendered without child objects

  • Test only the components to be tested (unit tests)
  • Avoid side effects that child components can have, such as making HTTP calls, calling storage operations…

Rewrite the index. Test. Js

import { shallowMount } from "@vue/test-utils";
import pageIndex from '@/pages/index.vue'

describe("index.test.js", () = > {let cmp;

  beforeEach((a)= > {
    cmp = shallowMount(pageIndex, {
      // Create a shallow instance of the component
      data: {
        messages: ["Cat"]}}); }); it('equals messages to ["Cat"]', () = > {// Within cmp.vm, we can access all Vue instance methods
    expect(cmp.vm.messages).toEqual(["Cat"]);
  });

  it("has the expected html structure", () => {
    expect(cmp.element).toMatchSnapshot();
  });
});
Copy the code

SnapShots are checked and indexes are isolated. If there are any hooks in child components, they are not called, such as created.

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`App.test.js has the expected html structure 1`] = ` <div id="app" > <! -- --> </div> `;
Copy the code

New MessageList. Test. Js

import { mount } from "@vue/test-utils";
import MessageList from "~/components/MessageList";

describe("MessageList.test.js", () = > {let cmp;

  beforeEach((a)= > {
    cmp = mount(MessageList, {
      // Be aware that props is overridden using `propsData`
      propsData: {
        messages: ["Cat"]}}); }); it('has received ["Cat"] as the message property', () => {
    expect(cmp.vm.messages).toEqual(["Cat"]);
  });

  it("has the expected html structure", () => {
    expect(cmp.element).toMatchSnapshot();
  });
});
Copy the code

npm run test