
When it comes to testing a Shopware 6 plugin, there are two types of test that can be performed:
- Testing the code itself (more in the official documentation)
- PHP unit test
- Jest unit tests in Shopware's storefront
- Jest unit tests in Shopware's administration
- End-to-End (E2E) Testing
- Ensuring high code quality (more in the official documentation)
Code quality
Let's start with code quality because it's easier to run it outside a CI/CD environment.
We will again use the shopware-cli.
shopware-cli extension validate --full --reporter summary .
This will run all the tests described here and hopefully produce an output like this:
✖ 0 problems (0 errors, 0 warnings)
If there are any errors, refer to the Shopware documentation how to fix them and rerun only the failed tests like described here.
Code quality pipeline
Now we will run it in GitLab.
<plugin-root>/.gitlab-ci.ymlstages:
- test
code-quality:
image:
name: ghcr.io/shopware/shopware-cli:latest-php-8.2
entrypoint: [""]
stage: test
script:
- shopware-cli extension validate --full . | tee report.json
artifacts:
reports:
codequality: report.json
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
when: never
- if: $CI_COMMIT_BRANCH
This pipeline will run on the default branch and on merge request pipelines.
Running on the default branch before build and release prevents from accidentally creating a low-quality release.
A nice touch to the MR pipeline is the Code Quality report integration!
PHP unit test
First of all, we need to configure PHPUnit by following the official shopware documentation
We won't focus here on this process. When everything is setup, we should be able to run our test like this in out Shopware project root:
./vendor/bin/phpunit --configuration="custom/static-plugins/SwagBasicExample"
PHPUnit pipeline
Running PHPUnit for a plugin requires a full Shopware instance. Fortunately, shopware-cli can help us to deal with it.
<plugin-root>/.gitlab-ci.ymlstages:
- test
phpunit:
stage: test
image:
name: ghcr.io/shopware/shopware-cli:latest-php-8.2
entrypoint: [""]
services:
- name: mysql:8.3.0
alias: test_database
variables:
MYSQL_SKIP_TEST_DB: 'yes'
MYSQL_ALLOW_EMPTY_PASSWORD: yes
variables:
GIT_STRATEGY: none
SHOPWARE_ROOT: ${CI_PROJECT_DIR}/shopware
SHOPWARE_VERSION: 6.6.10.13
APP_SECRET: def00000bb5acb32b54ff8ee130270586eec0e878f7337dc7a837acc31d3ff00f93a56b595448b4b29664847dd51991b3314ff65aeeeb761a133b0ec0e070433bff08e48
MESSENGER_TRANSPORT_DSN: sync://
DATABASE_URL: mysql://root@test_database/shopware
COMPOSER_CACHE_DIR: ${CI_PROJECT_DIR}/.composer
XDEBUG_MODE: coverage
before_script:
- apk add --no-cache php-8.2-xdebug
- shopware-cli project create shopware ${SHOPWARE_VERSION}
- cd $SHOPWARE_ROOT
- composer req --dev shopware/dev-tools phpunit/phpunit
- git clone "https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" "custom/plugins/${CI_PROJECT_NAME}"
- cd custom/plugins/${CI_PROJECT_NAME}
- git checkout ${CI_COMMIT_SHA}
- cd ${SHOPWARE_ROOT}
- composer require $(composer -d custom/plugins/${CI_PROJECT_NAME} config name)
- cd custom/plugins/${CI_PROJECT_NAME}
script:
- ${SHOPWARE_ROOT}/vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage.cobertura.xml
cache:
- key: $CI_JOB_NAME
paths:
- $COMPOSER_CACHE_DIR
coverage: /^\s*Lines:\s*\d+.\d+\%/
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.cobertura.xml
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
when: never
- if: $CI_COMMIT_BRANCH
Let's explain this a little
- We disable automatic repository cloning (16)
- We include a database service (9-14)
- We set some required Shopware env variables (20-23)
- Create an empty shopware project with phpunit and xdebug (27-36)
- Run PHPUnit with code coverage generation as text and in cobertura format (38)
Like the Code quality pipeline, this takes full advantage of GitLab coverage reporting
Putting it all together
For this part, we don't include the build and release part.
<plugin-root>/.gitlab-ci.ymlstages:
- test
phpunit:
stage: test
image:
name: ghcr.io/shopware/shopware-cli:latest-php-8.2
entrypoint: [""]
services:
- name: mysql:8.3.0
alias: test_database
variables:
MYSQL_SKIP_TEST_DB: 'yes'
MYSQL_ALLOW_EMPTY_PASSWORD: yes
variables:
GIT_STRATEGY: none
SHOPWARE_ROOT: ${CI_PROJECT_DIR}/shopware
SHOPWARE_VERSION: 6.6.10.13
APP_SECRET: def00000bb5acb32b54ff8ee130270586eec0e878f7337dc7a837acc31d3ff00f93a56b595448b4b29664847dd51991b3314ff65aeeeb761a133b0ec0e070433bff08e48
MESSENGER_TRANSPORT_DSN: sync://
DATABASE_URL: mysql://root@test_database/shopware
COMPOSER_CACHE_DIR: ${CI_PROJECT_DIR}/.composer
XDEBUG_MODE: coverage
before_script:
- apk add --no-cache php-8.2-xdebug
- shopware-cli project create shopware ${SHOPWARE_VERSION}
- cd $SHOPWARE_ROOT
- composer req --dev shopware/dev-tools phpunit/phpunit
- git clone "https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" "custom/plugins/${CI_PROJECT_NAME}"
- cd custom/plugins/${CI_PROJECT_NAME}
- git checkout ${CI_COMMIT_SHA}
- cd ${SHOPWARE_ROOT}
- composer require $(composer -d custom/plugins/${CI_PROJECT_NAME} config name)
- cd custom/plugins/${CI_PROJECT_NAME}
script:
- ${SHOPWARE_ROOT}/vendor/bin/phpunit --coverage-text --coverage-cobertura=coverage.cobertura.xml
cache:
- key: $CI_JOB_NAME
paths:
- $COMPOSER_CACHE_DIR
coverage: /^\s*Lines:\s*\d+.\d+\%/
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.cobertura.xml
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
when: never
- if: $CI_COMMIT_BRANCH
code-quality:
image:
name: ghcr.io/shopware/shopware-cli:latest-php-8.2
entrypoint: [""]
stage: test
script:
- shopware-cli extension validate --full . | tee report.json
artifacts:
reports:
codequality: report.json
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
when: never
- if: $CI_COMMIT_BRANCH
