What is Shopware?
Shopware 6 is an open commerce platform based on Symfony Framework and Vue and is supported by a worldwide community and more than 1.500 community extensions.
Folder structure
The test folder structure should match the source folder structure. You add a test for a file in the same path as the source path.
└── <pluginRoot>/src/Resources/app/administration
├── src
│ └── module
│ └── custom-cms
│ └── component
│ └── custom-cms-sidebar
│ ├── index.js
│ └── custom-cms-sidebar.html.twig
├── test
│ ├── _mocks_
│ │ └── entity-schema.json
│ │
│ └── module
│ └── custom-cms
│ └── component
│ └── custom-cms-sidebar.spec.js
│
├── babel.config.json
├── jest.config.js
└── package.json
Installation
Let’s grab all the dependencies we will need for the setup in package.json
{
// ...
"devDependencies": {
"@babel/plugin-proposal-class-properties": "^7.16.7",
"@babel/plugin-transform-runtime": "7.13.15",
"@babel/preset-env": "7.13.15",
"@shopware-ag/jest-preset-sw6-admin": "^2.0.1",
"@vue/test-utils": "1.1.0",
"jest": "26.4.2"
}
}
@shopware-ag/jest-preset-sw6-admin
Default Jest preset for Shopware 6 administration development.
@vue/test-utils
We are using the Vue Test Utils for easier testing of Vue components. It provides some methods to mount and interact with Vue components in an isolated manner.
Setup
After installing the required dependency packages, please create a file called babel.config.json
right next to your own package.json with the following content:
{
"presets": ["@babel/preset-env"],
"plugins": [
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-class-properties"
]
}
Next up, create a file jest.config.js
which should contain the following content:
const { resolve, join } = require('path');
const ADMIN_PATH = resolve('../../../../vendor/shopware/administration/Resources/app/administration');
process.env.ADMIN_PATH = process.env.ADMIN_PATH || ADMIN_PATH;
module.exports = {
preset: '@shopware-ag/jest-preset-sw6-admin',
globals: {
adminPath: process.env.ADMIN_PATH,
},
collectCoverageFrom: [
'src/**/*.js',
],
moduleNameMapper: {
'^plugin-admin(.*)$': '<rootDir>$1',
'\@vue/test-utils': '<rootDir>/node_modules/@vue/test-utils',
'../../_mocks_/entity-schema.json': '<rootDir>/test/_mocks_/entity-schema.json',
},
setupFilesAfterEnv: [
resolve(join(process.env.ADMIN_PATH, 'test/_setup/prepare_environment.js')),
],
};
The file entity-schema.json
could be generated by running this command:
bin/console framework:schema -s 'entity-schema' custom/plugins/<your_plugin>/src/Resources/app/administration/test/_mocks_/entity-schema.json
Writing Test
We are using a global object as an interface for the whole administration. Every component gets registered to this object, e.g. Shopware.Component.register(). Therefore, we have access to Component with the Shopware.Component.build() method. This creates a native Vue component with a working template. Every override and extension from another component are resolved in the built component.
Your component might look like this:
// src/module/custom-cms/component/custom-cms-sidebar/index.js
Component.extend('custom-cms-sidebar', 'sw-cms-sidebar', {
// The vue component
});
Create test file custom-cms-sidebar.spec.js
for custom-cms-sidebar
component.
When you want to mount your component it needs to be imported first:
import 'plugin-admin/src/module/custom-cms/component/custom-cms-sidebar';
Then import it's related components:
import 'src/module/sw-cms/mixin/sw-cms-state.mixin';
import 'src/module/sw-cms/component/sw-cms-sidebar';
import 'src/app/component/base/sw-button';
In the next step we can mount our Vue component which we get from the global Shopware object:
shallowMount(Shopware.Component.build('custom-cms-sidebar'));
Now you can test the component like any other component. Let's try to write our first test:
import { shallowMount } from '@vue/test-utils';
import 'src/module/sw-cms/mixin/sw-cms-state.mixin';
import 'src/module/sw-cms/component/sw-cms-sidebar';
import 'src/app/component/base/sw-button';
import 'plugin-admin/src/module/custom-cms/component/custom-cms-sidebar';
function createWrapper() {
return shallowMount(Shopware.Component.build('custom-cms-sidebar'), {
propsData: {
page: {
sections: []
}
},
stubs: {
'sw-button': Shopware.Component.build('sw-button'),
'sw-sidebar': true,
'sw-sidebar-item': true,
'sw-sidebar-collapse': true,
'sw-text-field': true,
'sw-select-field': true,
'sw-cms-block-config': true,
'sw-cms-block-layout-config': true,
'sw-cms-section-config': true,
'sw-context-button': true,
'sw-context-menu-item': true,
'sw-cms-sidebar-nav-element': true,
'sw-entity-single-select': true,
'sw-modal': true,
'sw-checkbox-field': true
},
provide: {
repositoryFactory: {
create: () => ({
create: () => ({
id: null,
slots: []
}),
save: () => {}
})
},
cmsService: {
getCmsBlockRegistry: () => ({
'foo-bar': {}
})
}
}
});
}
describe('module/custom-cms/component/custom-cms-sidebar', () => {
beforeAll(() => {
Shopware.State.registerModule('cmsPageState', {
namespaced: true,
state: {
isSystemDefaultLanguage: true
}
});
});
it('should be a Vue.js component', async () => {
const wrapper = createWrapper();
expect(wrapper.vm).toBeTruthy();
});
});
Running Test
Create a script in package.json
"scripts": {
"jest": "jest --config=jest.config.js",
}
Open a terminal and run this command:
npm run jest
I hope this post helps you with the config testing environment for your plugin. I am really happy to receive your feedback on this article. Thanks for your precious time reading this.