This article mainly explains how to build a relatively complete set of unit testing process based on Vite 2 and Vue 3
📦 Warehouse address: vue-Unit, welcome ✨ Star ✨ ~~
Installation and configuration
1. Create a vue3 empty project using create Vite Cli
yarn create vite
Copy the code
2. Install jest
yarn add jest -D
Copy the code
3. After installation, create the jest. Config. js file
// jest.config.js
module.exports = {
transform: {}}Copy the code
If you want to use the ES6 syntax, you need to install Babel and run the following command:
yarn add babel-jest @babel/core @babel/preset-env -D
Copy the code
5. Configure babel.config.js
module.exports = {
presets: [['@babel/preset-env', {
targets: {
node: 'current'}}]],};Copy the code
5. Configure Babel to jest. Config.js
module.exports = {
transform: {
'^.+\\.js$': 'babel-jest'}}Copy the code
6. Since we mainly test vUE components, we need to install the corresponding VUE-Jest and dependency packages.
Since it is VUe3 and the JEST version I installed before is 27.x, I execute the command (note the jEST version I installed here, different versions of JEST need to install different VUE-Jest).
For reference:
Github.com/vuejs/vue-j…
Github.com/vuejs/vue-t…
Yarn add @vue/vue3-jest@^27.0.0-alpha.3 @vue/test-utils@^2.0.0-rc.17 -d yarn add @vue/vue3-jest@^27.0.0-alphaCopy the code
7. After installing vue-jest, you need to further configure jest. Config.js
// jest.config.js
module.exports = {
transform: {
'^.+\\.js$': 'babel-jest'.'^.+\\.vue$': '@vue/vue3-jest',}}Copy the code
In general, unit test code is placed in the __tests__ folder
We can display the configuration to jest.config.js like this:
// jest.config.js
module.exports = {
transform: {
'^.+\\.js$': 'babel-jest'.'^.+\\.vue$': '@vue/vue3-jest',},testMatch: ['<rootDir>/__tests__/**/*.spec.js']}Copy the code
Every unit test file we write after that ends with *.spec.js.
Let’s use an example to verify the effect. Don’t forget to add jest to package.json before testing:
{
"scripts": {
"test": "jest"}}Copy the code
example
We can refer to the example given by vue-test-utils official next.vue-test-utils.vuejs.org/guide/ :
Create a hello.spec.js file in __tests__
// hello.spec.js
import { mount } from '@vue/test-utils'
// The component to test
const MessageComponent = {
template: '<p>{{ msg }}</p>'.props: ['msg']
}
test('displays message'.() = > {
const wrapper = mount(MessageComponent, {
props: {
msg: 'Hello world'}})// Assert the rendered text of the component
expect(wrapper.text()).toContain('Hello world')})Copy the code
2. An error message is displayed when you run the YARN test command. This message indicates that the single-test environment needs to be configured in jsDOM mode
IO /docs/config…
yarn run v1.22.17
$Jest FAIL __tests__/hello.spec.js ● Displays message The error below may be caused byusing the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string.
Consider using the "jsdom" test environment.
ReferenceError: document is not defined
9 |
10 | test('displays message', () => {>11 | const wrapper = mount(MessageComponent, {
| ^
12 | props: {
13 | msg: 'Hello world'
14 | }
at mount (node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:7757:14)
at Object.<anonymous> (__tests__/hello.spec.js:11:19)
Copy the code
TestEnvironment: ‘jsdom’
// jest.config.js
module.exports = {
testEnvironment: 'jsdom'.transform: {
'^.+\\.js$': 'babel-jest'.'^.+\\.vue$': '@vue/vue3-jest',},testMatch: ['<rootDir>/__tests__/**/*.spec.js']}Copy the code
Run yarn test again, and the PASS succeeds 🎉
The vUE component in the single test is a template component created temporarily and not imported from SRC. The actual situation may be:
1. Create.vue under SRC
2. Introduce to __tests__, mount to perform the test.
So let’s try it out and use the default app. vue instead:
App.vue
<script setup></script>
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3 + Vite" />
</template>
<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
To introduce app. vue to __tests__ :
Before we rush to execute the single test, let’s print the App and see if it can be introduced correctly:
// hello.spec.js
import { mount } from '@vue/test-utils'
import App from '.. /src/App.vue'
console.log(App)
// The component to test
const MessageComponent = {
template: '<p>{{ msg }}</p>'.props: ['msg']
}
test('displays message'.() = > {
const wrapper = mount(MessageComponent, {
props: {
msg: 'Hello world'}})// Assert the rendered text of the component
expect(wrapper.text()).toContain('Hello world')})Copy the code
Yarn test error:
● Test suite failed to run Jest encountered an unexpected token Jest failed to parse a file code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. Out of the box Jest supports Babel,which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do: • If you are trying to use ECMAScript Modules, See https://jestjs.io/docs/ecmascript-modules for how to enable it. • If you are trying to use TypeScript. See https://jestjs.io/docs/getting-started#using-typescript, and some of your "node_modules" files transformed, You can specify a custom "transformIgnorePatterns" in your config. • If you need a custom transformation specify a • If you simply want to mock your non-js modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
/Users/wisdom/Documents/workspace/vue-unit/src/assets/logo.png:1
({"Object.<anonymous>":function(module, exports, the require, __dirname __filename, jest) {� PNG SyntaxError: Invalid or unexpected token at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14) at Object.<anonymous> (src/App.vue:40:36)Copy the code
PNG fails to be parsed and cannot be converted. An additional transform is required
Jest does not process assets by default, but there is a package that does: jest-transform-stub
Install jest-transform-stub:
yarn add jest-transform-stub -D
Copy the code
Use jest-transform-stub in the Jest configuration file
// jest.config.js
module.exports = {
testEnvironment: 'jsdom'.transform: {
'^.+\\.js$': 'babel-jest'.'^.+\\.vue$': '@vue/vue3-jest'.'.+\\.(css|scss|png|jpg|svg)$': 'jest-transform-stub'
},
testMatch: ['<rootDir>/__tests__/**/*.spec.js']}Copy the code
Run the YARN test again. The PASS succeeds 🎉
Configuration alias
In real projects, we typically use the alias configuration as the absolute path introduced, such as the @ symbol for SRC directories,
So how to use it in a single test, do you need to do some configuration?
Helloworld.vue: HelloWorld.vue: helloWorld.vue: helloWorld.vue: helloWorld.vue
// hello.spec.js
import { mount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'
test('displays message'.() = > {
const wrapper = mount(HelloWorld, {
props: {
msg: 'Hello world'}})// Assert the rendered text of the component
expect(wrapper.text()).toContain('Hello world')})Copy the code
Does yarn test report an error?
Execute the test, as expected, error:
FAIL __tests__/hello.spec.js
● Test suite failed to run
Cannot find module '@/components/HelloWorld.vue' from '__tests__/hello.spec.js'
Copy the code
In conjunction with the @alias symbol just mentioned, jest.config.js needs to be modified slightly:
// jest.config.js
module.exports = {
testEnvironment: 'jsdom'.moduleNameMapper: {
"^ @ / (. *) $": "<rootDir>/src/$1"
},
transform: {
'^.+\\.js$': 'babel-jest'.'^.+\\.vue$': '@vue/vue3-jest'.'.+\\.(css|scss|png|jpg|svg)$': 'jest-transform-stub'
},
testMatch: ['<rootDir>/__tests__/**/*.spec.js']}Copy the code
The moduleNameMapper parameter, which can be used to map a module path to another module, is shown in the official description:
Jestjs. IO/docs/config…
Restart yarn test, PASS 🎉
Unit test coverage
Because the JEST version is 27.x, the coverageProvider: “V8” parameter needs to be added to generate coverage reports
module.exports = {
testEnvironment: 'jsdom'.moduleFileExtensions: ["js"."vue"].moduleNameMapper: {
"^ @ / (. *) $": "<rootDir>/src/$1"
},
testMatch: ['<rootDir>/__tests__/**/*.spec.js'].transformIgnorePatterns: ['/node_modules/'].transform: {
'^.+\\.js$': 'babel-jest'.'^.+\\.(vue)$': '@vue/vue3-jest'.'.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub'
},
coverageDirectory: 'coverage'.coverageProvider: "v8".collectCoverageFrom: [
'src/**/*.{js,vue}'.'! src/main.js'.'! src/App.vue'].coverageThreshold: {
global: {
branches: 40.functions: 80.lines: 90.statements: 80}}}Copy the code
Package. json add the following command:
"test:coverage": "jest --coverage"
Copy the code
Execute:
Yarn Run v1.22.17 $jest -- Coverage PASS __tests__/sum.spec.js PASS __tests__/hello.spec.js ----------------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line#s
----------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
HelloWorld.vue | 100 | 100 | 100 | 100 |
----------------|---------|----------|---------|---------|-------------------
Test Suites: 2 passed, 2 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 7.84 s
Ran all testSuites. ✨ Donein11.21 s.Copy the code
Associated Codecov
1, first enter the app. Codecov. IO/gh/pdsuwwz /… Codecov should prompt you to authorize Github. Click Authorize
2. After the authorization is completed, you can select which Github project to associate with, such as VUe-Unit
3. Click on the name and you should be presented with a token like this:
Click Copy to Copy, and then we will enter the key secrets setting page of github corresponding project:
Create a new token and name it CODECOV_TOKEN (CODECOV_TOKEN is used for convenience in github CI)
4. After creating the token, we need to create a Github CI
In the first place in the project root directory to create. Making/workflows/unit.and yml file
Write in the file:
name: Unit-Testing
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12.20.x
- name: Install dependencies
run: yarn install
- name: Testing
run: yarn test:coverage
env:
CI: true
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: The ${{ secrets.CODECOV_TOKEN }}
Copy the code
Note the last ${{secrets.codecov_token}}, github Action will get the secrets token we just created from the secrets when executing this workflow
5. Show the Codecov badge
Push code to Github, and github automatically executes the workflow
After the workflow is executed, we can write in readme.md:
[! [codecov] (https://codecov.io/gh/pdsuwwz/vue-unit/branch/main/graph/badge.svg(a)]https://codecov.io/gh/pdsuwwz/vue-unit)
Copy the code
Just change pdSUwwz to your username and vue-Unit to your repository name.
You can try it. It should look like this:
✿ Angry (° °) Blue ✿
📦 Warehouse address: vue-Unit, welcome ✨ Star ✨ ~~