ci/README-COVERAGE.md
This directory contains scripts for capturing code coverage during end-to-end (E2E), API, and Inferno certification tests.
auto_prepend.php)A PHP auto-prepend script runs before every HTTP request during E2E, API, and Inferno tests:
ENABLE_COVERAGE=true/tmp/openemr-coverage/e2e/coverage.e2e.*.raw.php for E2E tests/tmp/openemr-coverage/api/coverage.api.*.raw.php for API tests/tmp/openemr-coverage/inferno/coverage.inferno.*.raw.php for Inferno testsEach file contains a raw Xdebug coverage array from a single HTTP request. The test type is automatically detected based on:
INFERNO_TEST=true environment variable → Inferno/apis/* → APIsetup_e2e_bookends in ciLibrary.source)Configures PHP to auto-prepend the coverage script:
auto_prepend_file INI directive pointing to ci/auto_prepend.phpconvert-coverage via convert_coverage helper)After tests complete, the convert_coverage() shell helper (in ciLibrary.source) runs the
convert-coverage CLI tool inside the Docker container via _exec. This is critical because
the raw coverage arrays contain absolute container paths (e.g., /var/www/localhost/htdocs/openemr/src/Foo.php)
that only resolve inside the container.
The helper passes --coverage-filter for each source directory so the CodeCoverage Filter is
populated with real files, which the Clover writer needs to produce a non-empty report.
The convert-coverage CLI tool:
--coverage-filter directoriesCodeCoverage object.cov file (PHPUnit format) and Clover XML reportExamples using the shell helper (from ci/ciLibrary.source):
. ci/ciLibrary.source
convert_coverage /tmp/openemr-coverage/e2e coverage/coverage.e2e.cov --clover=coverage.e2e.clover.xml
convert_coverage /tmp/openemr-coverage/api coverage/coverage.api.cov --clover=coverage.api.clover.xml
convert_coverage /tmp/openemr-coverage/inferno /dev/null --clover=coverage.inferno-http.clover.xml
merge_coverage in ciLibrary.source)The existing phpcov merge command combines all .cov files (unit, api, e2e, etc.) into final coverage reports.
OPENEMR_ENABLE_CI_PHP=1 - Enables CI scripts (set in docker-compose)ENABLE_COVERAGE=true - Activates coverage collectionINFERNO_TEST=true - Identifies requests as Inferno certification testsXDEBUG_ON=1 - Enables XdebugXDEBUG_MODE=coverage - Sets Xdebug to coverage modeauto_prepend.php - Auto-prepend script with coverage hooks (supports E2E, API, and Inferno tests)convert-coverage - Generic Symfony Console CLI tool to merge raw coverage filesciLibrary.source - Contains setup_e2e_bookends(), configure_coverage(), and merge_coverage()inferno/run.sh - Contains collect_inferno_coverage() for Inferno-specific coverage handlingIn .github/workflows/test.yml, the coverage process happens in these steps:
build_test apiconvert_coverage inside the container to merge raw files into coverage/coverage.api.covsetup_e2e_bookends() to configure auto-prependbuild_test e2econvert_coverage inside the container to merge raw files into coverage/coverage.e2e.covmerge_coverage() which runs phpcov merge coverage/ to combine all .cov files into final reports.github/workflows/inferno-test.yml):ci/inferno/run.sh with ENABLE_COVERAGE=true, INFERNO_TEST=true, and Xdebug enabled
configure_coverage() to set up Xdebugsetup_e2e_bookends() to enable auto-prepend for HTTP request coverage--coverage-php to capture unit test coveragecollect_inferno_coverage() to:
convert_coverage inside the container to convert raw HTTP coverage filescoverage.inferno-http.clover.xmlinferno,phpunit flagsinferno,http flagsinferno,combined flagsflowchart TD
A[Test Starts - E2E, API, or Inferno] --> B[HTTP Request]
B --> C[auto_prepend.php detects test type]
C --> D{Test Type?}
D -->|INFERNO_TEST=true| E[Inferno Test - save to /tmp/openemr-coverage/inferno/]
D -->|/apis/*| F[API Test - save to /tmp/openemr-coverage/api/]
D -->|Other| G[E2E Test - save to /tmp/openemr-coverage/e2e/]
E --> H[PHP executes application code]
F --> H
G --> H
H --> I[Shutdown handler saves raw coverage]
I --> J{More requests?}
J -->|Yes| B
J -->|No| L[convert_coverage runs inside container]
L --> M[Output: coverage/coverage.TYPE.cov]
M --> N[phpcov merge combines all .cov files]
N --> O[Final: coverage.clover.xml + htmlcov/]
.cov files