Continuous Integration: Running Tests Automatically
Continuous Integration: Running Tests Automatically
~7 Min. Lesezeit Zuletzt aktualisiert am August 9, 2026
Every test command shown in chapters 91-94 is only worth as much as it actually gets run. A unit test nobody runs before a merge discovers a regression, at the earliest, once it has already landed on the main branch. A CI pipeline closes exactly that gap: it runs the same commands automatically on every push and every merge request.
Two speeds, two jobs
Chapter 93 already explained the speed difference between unit and integration tests - the same split belongs in the pipeline. A fast unit-tests job runs on every single push, a slower integration-tests job (with its own database as a GitLab CI service) only on merge requests against the main branch - keeping the feedback loop short for everyday commits.
stages:
- static-analysis
- test
variables:
COMPOSER_CACHE_DIR: "$CI_PROJECT_DIR/.composer-cache"
cache:
key: composer-cache
paths:
- .composer-cache/
phpstan:
stage: static-analysis
image: mark0x/php-8.4-fpm:latest
script:
- composer install --prefer-dist --no-progress
- vendor/bin/phpstan analyse app/code/Mironsoft/Loyalty --level=5 --no-progress
phpcs:
stage: static-analysis
image: mark0x/php-8.4-fpm:latest
script:
- composer install --prefer-dist --no-progress
- vendor/bin/phpcs --standard=Magento2 app/code/Mironsoft/Loyalty
unit-tests:
stage: test
image: mark0x/php-8.4-fpm:latest
script:
- composer install --prefer-dist --no-progress
- vendor/bin/phpunit -c dev/tests/unit/phpunit.xml.dist \
--coverage-text --colors=never \
app/code/Mironsoft/Loyalty/Test/Unit
rules:
- if: '$CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event"'
integration-tests:
stage: test
image: mark0x/php-8.4-fpm:latest
services:
- name: mysql:8.0
alias: db
variables:
MYSQL_ROOT_PASSWORD: magento
MYSQL_DATABASE: magento_integration_tests
script:
- composer install --prefer-dist --no-progress
- cp dev/tests/integration/etc/install-config-mysql.php.dist \
dev/tests/integration/etc/install-config-mysql.php
- vendor/bin/phpunit -c dev/tests/integration/phpunit.xml.dist \
app/code/Mironsoft/Loyalty/Test/Integration
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'Tipp: The services entry on integration-tests spins up its own, isolated MySQL container just for that job - the exact same principle as compose.dev.yaml in this project, just for the CI pipeline instead of the local development environment.
Static analysis before the tests
phpstan and phpcs run as their own stage before test - a module with a PHPStan error at level 5 shouldn't have to run through the far slower test suite first just to fail. Chapter 96 digs into exactly that phpstan job.
Achtung: A red, failing integration-tests job that gets ignored because "the database in CI is always a bit flaky anyway" is more dangerous than having no integration test at all - it creates a false sense of safety while real regressions get lost in the noise. An unstable CI job needs fixing or removing, never silently ignoring.
Chapter 96 wraps up block 11 - and the phpstan job from the pipeline above - with a closer look at PHPStan level 5 in this exact module.