implementation of jest unit testing

This commit is contained in:
Carlos Jimenez Ruiz 2022-03-24 13:41:17 +01:00
parent 778835737b
commit 601cdc0908
13 changed files with 12497 additions and 17 deletions

19
.babelrc Normal file
View File

@ -0,0 +1,19 @@
{
"plugins": ["@babel/plugin-syntax-dynamic-import"],
"env": {
"test": {
"plugins": ["dynamic-import-node"],
"presets": [
[
"@babel/preset-env",
{
"modules": "commonjs",
"targets": {
"node": "current"
}
}
]
]
}
}
}

View File

@ -1,14 +1,18 @@
/* eslint-disable */
/* eslint-env node */
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require('fs-extra');
let extend = undefined;
module.exports = api => {
return {
presets: [
[
'@quasar/babel-preset-app',
api.caller(caller => caller && caller.target === 'node')
? { targets: { node: 'current' } }
: {}
]
]
}
/**
* The .babelrc file has been created to assist Jest for transpiling.
* You should keep your application's babel rules in this file.
*/
if (fs.existsSync('./.babelrc')) {
extend = './.babelrc';
}
module.exports = {
presets: ['@quasar/babel-preset-app'],
extends: extend,
};

64
jest.config.js Executable file
View File

@ -0,0 +1,64 @@
const esModules = ['quasar', 'quasar/lang', 'lodash-es'].join('|');
module.exports = {
globals: {
__DEV__: true,
// TODO: Remove if resolved natively
// See https://github.com/vuejs/vue-jest/issues/175
'vue-jest': {
pug: { doctype: 'html' },
},
},
// Jest assumes we are testing in node environment, specify jsdom environment instead
testEnvironment: 'jsdom',
// noStackTrace: true,
// bail: true,
// cache: false,
// verbose: true,
// watch: true,
collectCoverage: false,
coverageDirectory: '<rootDir>/test/jest/coverage',
collectCoverageFrom: [
'<rootDir>/src/**/*.vue',
'<rootDir>/src/**/*.js',
'<rootDir>/src/**/*.jsx',
],
// Needed in JS codebases too because of feature flags
coveragePathIgnorePatterns: ['/node_modules/', '.d.ts$'],
coverageThreshold: {
global: {
// branches: 50,
// functions: 50,
// lines: 50,
// statements: 50
},
},
testMatch: [
'<rootDir>/test/jest/__tests__/**/*.(spec|test).js',
'<rootDir>/src/**/*.jest.(spec|test).js',
],
moduleFileExtensions: ['vue', 'js', 'jsx', 'json'],
moduleNameMapper: {
'^quasar$': 'quasar/dist/quasar.esm.prod.js',
'^~/(.*)$': '<rootDir>/$1',
'^src/(.*)$': '<rootDir>/src/$1',
'^app/(.*)$': '<rootDir>/$1',
'^components/(.*)$': '<rootDir>/src/components/$1',
'^layouts/(.*)$': '<rootDir>/src/layouts/$1',
'^pages/(.*)$': '<rootDir>/src/pages/$1',
'^assets/(.*)$': '<rootDir>/src/assets/$1',
'^boot/(.*)$': '<rootDir>/src/boot/$1',
'.*css$': '@quasar/quasar-app-extension-testing-unit-jest/stub.css',
},
transform: {
'.*\\.vue$': 'vue-jest',
'.*\\.js$': 'babel-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
'jest-transform-stub',
// use these if NPM is being flaky, care as hosting could interfere with these
// '.*\\.vue$': '@quasar/quasar-app-extension-testing-unit-jest/node_modules/vue-jest',
// '.*\\.js$': '@quasar/quasar-app-extension-testing-unit-jest/node_modules/babel-jest'
},
transformIgnorePatterns: [`node_modules/(?!(${esModules}))`],
snapshotSerializers: ['jest-serializer-vue'],
};

12238
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,25 +8,34 @@
"scripts": {
"lint": "eslint --ext .js,.vue ./",
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
"test": "echo \"No test specified\" && exit 0"
"test": "echo \"See package.json => scripts for available tests.\" && exit 0",
"test:unit": "jest --updateSnapshot",
"test:unit:ci": "jest --ci",
"test:unit:coverage": "jest --coverage",
"test:unit:watch": "jest --watch",
"test:unit:watchAll": "jest --watchAll",
"serve:test:coverage": "quasar serve test/jest/coverage/lcov-report/ --port 8788",
"concurrently:dev:jest": "concurrently \"quasar dev\" \"jest --watch\""
},
"dependencies": {
"axios": "^0.21.1",
"vue-i18n": "^9.0.0",
"@quasar/extras": "^1.0.0",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"quasar": "^2.6.0",
"vue": "^3.0.0",
"vue-i18n": "^9.0.0",
"vue-router": "^4.0.0"
},
"devDependencies": {
"@babel/eslint-parser": "^7.13.14",
"@quasar/app-webpack": "^3.0.0",
"@quasar/quasar-app-extension-testing-unit-jest": "^3.0.0-alpha.9",
"eslint": "^8.10.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-vue": "^8.5.0",
"eslint-webpack-plugin": "^3.1.1",
"eslint-config-prettier": "^8.1.0",
"prettier": "^2.5.1",
"@quasar/app-webpack": "^3.0.0"
"eslint-plugin-jest": "^25.2.2"
},
"browserslist": [
"last 10 Chrome versions",

8
quasar.extensions.json Normal file
View File

@ -0,0 +1,8 @@
{
"@quasar/testing-unit-jest": {
"babel": "babelrc",
"options": [
"scripts"
]
}
}

5
quasar.testing.json Normal file
View File

@ -0,0 +1,5 @@
{
"unit-jest": {
"runnerCommand": "jest --ci"
}
}

10
test/jest/.eslintrc.js Normal file
View File

@ -0,0 +1,10 @@
module.exports = {
extends: [
// Removes 'no-undef' lint errors for Jest global functions (`describe`, `it`, etc),
// add Jest-specific lint rules and Jest plugin
// See https://github.com/jest-community/eslint-plugin-jest#recommended
'plugin:jest/recommended',
// Uncomment following line to apply style rules
// 'plugin:jest/style',
],
};

1
test/jest/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
coverage/*

View File

@ -0,0 +1,42 @@
import { describe, expect, it } from '@jest/globals';
import { installQuasarPlugin } from '@quasar/quasar-app-extension-testing-unit-jest';
import { mount, shallowMount } from '@vue/test-utils';
import { QBtn } from 'quasar';
import MyButton from './demo/MyButton';
// Specify here Quasar config you'll need to test your component
installQuasarPlugin();
describe('MyButton', () => {
it('has increment method', () => {
const wrapper = mount(MyButton);
const { vm } = wrapper;
expect(typeof vm.increment).toBe('function');
});
it('can check the inner text content', () => {
const wrapper = mount(MyButton);
const { vm } = wrapper;
expect(vm.$el.textContent).toContain('rocket muffin');
expect(wrapper.find('.content').text()).toContain('rocket muffin');
});
it('sets the correct default data', () => {
const wrapper = mount(MyButton);
const { vm } = wrapper;
expect(typeof vm.counter).toBe('number');
expect(vm.counter).toBe(0);
});
it('correctly updates counter when button is pressed', async () => {
const wrapper = shallowMount(MyButton);
const { vm } = wrapper;
const button = wrapper.findComponent(QBtn);
await button.trigger('click');
expect(vm.counter).toBe(1);
});
});

View File

@ -0,0 +1,30 @@
import { installQuasarPlugin } from '@quasar/quasar-app-extension-testing-unit-jest';
import { beforeEach, describe, expect, it } from '@jest/globals';
import { DOMWrapper, mount } from '@vue/test-utils';
import MyDialog from './demo/MyDialog';
installQuasarPlugin();
describe('MyDialog', () => {
beforeEach(() => {
mount(MyDialog, {
data: () => ({
isDialogOpen: true,
}),
});
});
it('should mount the document body and expose for testing', () => {
const wrapper = new DOMWrapper(document.body);
expect(wrapper.find('.q-dialog').exists()).toBeTruthy();
});
it('can check the inner text of the dialog', () => {
const wrapper = new DOMWrapper(document.body);
expect(wrapper.find('.q-dialog').html()).toContain(
'Custom dialog which should be tested',
);
});
});

View File

@ -0,0 +1,30 @@
<script>
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'MyButton',
props: {
incrementStep: {
type: Number,
default: 1,
},
},
setup(props) {
const counter = ref(0);
const input = ref('rocket muffin');
function increment() {
counter.value += props.incrementStep;
}
return { counter, input, increment };
},
});
</script>
<template>
<div>
<p class="content">{{ input }}</p>
<span>{{ counter }}</span>
<q-btn class="button" @click="increment()"></q-btn>
</div>
</template>

View File

@ -0,0 +1,20 @@
<template>
<q-dialog v-model="isDialogOpen">
<q-card>
<q-card-section>Custom dialog which should be tested</q-card-section>
</q-card>
</q-dialog>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
name: 'MyDialog',
data() {
return {
isDialogOpen: false,
};
},
});
</script>