Skip to content

Commit 412798a

Browse files
Closes #6297
1 parent c2c98b8 commit 412798a

File tree

13 files changed

+258
-1
lines changed

13 files changed

+258
-1
lines changed

ChangeLog-11.5.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes of the PHPUnit 11.5 release series are documented in this fi
44

55
## [11.5.29] - 2025-MM-DD
66

7+
### Added
8+
9+
* [#6297](https://github.com/sebastianbergmann/phpunit/issues/6297): `--check-php-configuration` CLI option for checking whether PHP is configured for testing
10+
711
### Changed
812

913
* `#[IgnorePhpunitDeprecations]` is now considered for test runner deprecations (where applicable)

phpunit.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
<testsuite name="end-to-end">
1919
<directory suffix=".phpt">tests/end-to-end/baseline</directory>
20+
<directory suffix=".phpt">tests/end-to-end/check-php-version</directory>
2021
<directory suffix=".phpt">tests/end-to-end/cli</directory>
2122
<directory suffix=".phpt">tests/end-to-end/data-provider</directory>
2223
<directory suffix=".phpt">tests/end-to-end/deprecation-trigger</directory>

src/TextUI/Application.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
use PHPUnit\TextUI\CliArguments\Exception as ArgumentsException;
6262
use PHPUnit\TextUI\CliArguments\XmlConfigurationFileFinder;
6363
use PHPUnit\TextUI\Command\AtLeastVersionCommand;
64+
use PHPUnit\TextUI\Command\CheckPhpConfigurationCommand;
6465
use PHPUnit\TextUI\Command\GenerateConfigurationCommand;
6566
use PHPUnit\TextUI\Command\ListGroupsCommand;
6667
use PHPUnit\TextUI\Command\ListTestFilesCommand;
@@ -463,6 +464,10 @@ private function executeCommandsThatOnlyRequireCliConfiguration(CliConfiguration
463464
$this->execute(new ShowVersionCommand);
464465
}
465466

467+
if ($cliConfiguration->checkPhpConfiguration()) {
468+
$this->execute(new CheckPhpConfigurationCommand);
469+
}
470+
466471
if ($cliConfiguration->checkVersion()) {
467472
$this->execute(new VersionCheckCommand(new PhpDownloader, Version::majorVersionNumber(), Version::id()));
468473
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\TextUI\Command;
11+
12+
use const PHP_EOL;
13+
use function extension_loaded;
14+
use function ini_get;
15+
use function max;
16+
use function sprintf;
17+
use function strlen;
18+
use PHPUnit\Runner\Version;
19+
20+
/**
21+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
22+
*
23+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
24+
*/
25+
final readonly class CheckPhpConfigurationCommand implements Command
26+
{
27+
/**
28+
* @var non-empty-array<non-empty-string, array{expectedValue: non-empty-string, valueForConfiguration: non-empty-string, requiredExtensions: list<non-empty-string>}>
29+
*/
30+
private const array SETTINGS = [
31+
'display_errors' => [
32+
'expectedValue' => '1',
33+
'valueForConfiguration' => 'On',
34+
'requiredExtensions' => [],
35+
],
36+
'display_startup_errors' => [
37+
'expectedValue' => '1',
38+
'valueForConfiguration' => 'On',
39+
'requiredExtensions' => [],
40+
],
41+
'error_reporting' => [
42+
'expectedValue' => '-1',
43+
'valueForConfiguration' => '-1',
44+
'requiredExtensions' => [],
45+
],
46+
'xdebug.show_exception_trace' => [
47+
'expectedValue' => '0',
48+
'valueForConfiguration' => '0',
49+
'requiredExtensions' => ['xdebug'],
50+
],
51+
'zend.assertions' => [
52+
'expectedValue' => '1',
53+
'valueForConfiguration' => '1',
54+
'requiredExtensions' => [],
55+
],
56+
'assert.exception' => [
57+
'expectedValue' => '1',
58+
'valueForConfiguration' => '1',
59+
'requiredExtensions' => [],
60+
],
61+
'memory_limit' => [
62+
'expectedValue' => '-1',
63+
'valueForConfiguration' => '-1',
64+
'requiredExtensions' => [],
65+
],
66+
];
67+
68+
public function execute(): Result
69+
{
70+
$lines = [];
71+
$shellExitCode = 0;
72+
73+
foreach (self::SETTINGS as $name => $setting) {
74+
foreach ($setting['requiredExtensions'] as $extension) {
75+
if (!extension_loaded($extension)) {
76+
continue 2;
77+
}
78+
}
79+
80+
if (ini_get($name) === $setting['expectedValue']) {
81+
$check = 'ok';
82+
} else {
83+
$check = 'not ok';
84+
$shellExitCode = 1;
85+
}
86+
87+
$lines[] = [
88+
sprintf(
89+
'%s = %s',
90+
$name,
91+
$setting['valueForConfiguration'],
92+
),
93+
$check,
94+
];
95+
}
96+
97+
$maxLength = 0;
98+
99+
foreach ($lines as $line) {
100+
$maxLength = max($maxLength, strlen($line[0]));
101+
}
102+
103+
$buffer = sprintf(
104+
'Checking whether PHP is configured according to https://docs.phpunit.de/en/%s/installation.html#configuring-php-for-development' . PHP_EOL . PHP_EOL,
105+
Version::series(),
106+
);
107+
108+
foreach ($lines as $line) {
109+
$buffer .= sprintf(
110+
'%-' . $maxLength . 's ... %s' . PHP_EOL,
111+
$line[0],
112+
$line[1],
113+
);
114+
}
115+
116+
return Result::from($buffer, $shellExitCode);
117+
}
118+
}

src/TextUI/Configuration/Cli/Builder.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ final class Builder
4141
'do-not-cache-result',
4242
'cache-directory=',
4343
'check-version',
44+
'check-php-configuration',
4445
'colors==',
4546
'columns=',
4647
'configuration=',
@@ -188,6 +189,7 @@ public function fromParameters(array $parameters): Configuration
188189
$bootstrap = null;
189190
$cacheDirectory = null;
190191
$cacheResult = null;
192+
$checkPhpConfiguration = false;
191193
$checkVersion = false;
192194
$colors = null;
193195
$columns = null;
@@ -1094,6 +1096,11 @@ public function fromParameters(array $parameters): Configuration
10941096

10951097
break;
10961098

1099+
case '--check-php-configuration':
1100+
$checkPhpConfiguration = true;
1101+
1102+
break;
1103+
10971104
case '--check-version':
10981105
$checkVersion = true;
10991106

@@ -1202,6 +1209,7 @@ public function fromParameters(array $parameters): Configuration
12021209
$bootstrap,
12031210
$cacheDirectory,
12041211
$cacheResult,
1212+
$checkPhpConfiguration,
12051213
$checkVersion,
12061214
$colors,
12071215
$columns,

src/TextUI/Configuration/Cli/Configuration.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
private ?string $bootstrap;
3030
private ?string $cacheDirectory;
3131
private ?bool $cacheResult;
32+
private bool $checkPhpConfiguration;
3233
private bool $checkVersion;
3334
private ?string $colors;
3435
private null|int|string $columns;
@@ -186,7 +187,7 @@
186187
* @param ?non-empty-list<non-empty-string> $coverageFilter
187188
* @param ?non-empty-list<non-empty-string> $extensions
188189
*/
189-
public function __construct(array $arguments, ?string $atLeastVersion, ?bool $backupGlobals, ?bool $backupStaticProperties, ?bool $beStrictAboutChangesToGlobalState, ?string $bootstrap, ?string $cacheDirectory, ?bool $cacheResult, bool $checkVersion, ?string $colors, null|int|string $columns, ?string $configurationFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4J, ?string $coverageHtml, ?string $coveragePhp, ?string $coverageText, ?bool $coverageTextShowUncoveredFiles, ?bool $coverageTextShowOnlySummary, ?string $coverageXml, ?bool $pathCoverage, bool $warmCoverageCache, ?int $defaultTimeLimit, ?bool $disableCodeCoverageIgnore, ?bool $disallowTestOutput, ?bool $enforceTimeLimit, ?array $excludeGroups, ?int $executionOrder, ?int $executionOrderDefects, ?bool $failOnAllIssues, ?bool $failOnDeprecation, ?bool $failOnPhpunitDeprecation, ?bool $failOnPhpunitWarning, ?bool $failOnEmptyTestSuite, ?bool $failOnIncomplete, ?bool $failOnNotice, ?bool $failOnRisky, ?bool $failOnSkipped, ?bool $failOnWarning, ?bool $doNotFailOnDeprecation, ?bool $doNotFailOnPhpunitDeprecation, ?bool $doNotFailOnPhpunitWarning, ?bool $doNotFailOnEmptyTestSuite, ?bool $doNotFailOnIncomplete, ?bool $doNotFailOnNotice, ?bool $doNotFailOnRisky, ?bool $doNotFailOnSkipped, ?bool $doNotFailOnWarning, ?bool $stopOnDefect, ?bool $stopOnDeprecation, ?string $specificDeprecationToStopOn, ?bool $stopOnError, ?bool $stopOnFailure, ?bool $stopOnIncomplete, ?bool $stopOnNotice, ?bool $stopOnRisky, ?bool $stopOnSkipped, ?bool $stopOnWarning, ?string $filter, ?string $excludeFilter, ?string $generateBaseline, ?string $useBaseline, bool $ignoreBaseline, bool $generateConfiguration, bool $migrateConfiguration, ?array $groups, ?array $testsCovering, ?array $testsUsing, ?array $testsRequiringPhpExtension, bool $help, ?string $includePath, ?array $iniSettings, ?string $junitLogfile, bool $listGroups, bool $listSuites, bool $listTestFiles, bool $listTests, ?string $listTestsXml, ?bool $noCoverage, ?bool $noExtensions, ?bool $noOutput, ?bool $noProgress, ?bool $noResults, ?bool $noLogging, ?bool $processIsolation, ?int $randomOrderSeed, ?bool $reportUselessTests, ?bool $resolveDependencies, ?bool $reverseList, ?bool $stderr, ?bool $strictCoverage, ?string $teamcityLogfile, ?string $testdoxHtmlFile, ?string $testdoxTextFile, ?array $testSuffixes, ?string $testSuite, ?string $excludeTestSuite, bool $useDefaultConfiguration, ?bool $displayDetailsOnAllIssues, ?bool $displayDetailsOnIncompleteTests, ?bool $displayDetailsOnSkippedTests, ?bool $displayDetailsOnTestsThatTriggerDeprecations, ?bool $displayDetailsOnPhpunitDeprecations, ?bool $displayDetailsOnTestsThatTriggerErrors, ?bool $displayDetailsOnTestsThatTriggerNotices, ?bool $displayDetailsOnTestsThatTriggerWarnings, bool $version, ?array $coverageFilter, ?string $logEventsText, ?string $logEventsVerboseText, ?bool $printerTeamCity, ?bool $testdoxPrinter, ?bool $testdoxPrinterSummary, bool $debug, ?array $extensions)
190+
public function __construct(array $arguments, ?string $atLeastVersion, ?bool $backupGlobals, ?bool $backupStaticProperties, ?bool $beStrictAboutChangesToGlobalState, ?string $bootstrap, ?string $cacheDirectory, ?bool $cacheResult, bool $checkPhpConfiguration, bool $checkVersion, ?string $colors, null|int|string $columns, ?string $configurationFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4J, ?string $coverageHtml, ?string $coveragePhp, ?string $coverageText, ?bool $coverageTextShowUncoveredFiles, ?bool $coverageTextShowOnlySummary, ?string $coverageXml, ?bool $pathCoverage, bool $warmCoverageCache, ?int $defaultTimeLimit, ?bool $disableCodeCoverageIgnore, ?bool $disallowTestOutput, ?bool $enforceTimeLimit, ?array $excludeGroups, ?int $executionOrder, ?int $executionOrderDefects, ?bool $failOnAllIssues, ?bool $failOnDeprecation, ?bool $failOnPhpunitDeprecation, ?bool $failOnPhpunitWarning, ?bool $failOnEmptyTestSuite, ?bool $failOnIncomplete, ?bool $failOnNotice, ?bool $failOnRisky, ?bool $failOnSkipped, ?bool $failOnWarning, ?bool $doNotFailOnDeprecation, ?bool $doNotFailOnPhpunitDeprecation, ?bool $doNotFailOnPhpunitWarning, ?bool $doNotFailOnEmptyTestSuite, ?bool $doNotFailOnIncomplete, ?bool $doNotFailOnNotice, ?bool $doNotFailOnRisky, ?bool $doNotFailOnSkipped, ?bool $doNotFailOnWarning, ?bool $stopOnDefect, ?bool $stopOnDeprecation, ?string $specificDeprecationToStopOn, ?bool $stopOnError, ?bool $stopOnFailure, ?bool $stopOnIncomplete, ?bool $stopOnNotice, ?bool $stopOnRisky, ?bool $stopOnSkipped, ?bool $stopOnWarning, ?string $filter, ?string $excludeFilter, ?string $generateBaseline, ?string $useBaseline, bool $ignoreBaseline, bool $generateConfiguration, bool $migrateConfiguration, ?array $groups, ?array $testsCovering, ?array $testsUsing, ?array $testsRequiringPhpExtension, bool $help, ?string $includePath, ?array $iniSettings, ?string $junitLogfile, bool $listGroups, bool $listSuites, bool $listTestFiles, bool $listTests, ?string $listTestsXml, ?bool $noCoverage, ?bool $noExtensions, ?bool $noOutput, ?bool $noProgress, ?bool $noResults, ?bool $noLogging, ?bool $processIsolation, ?int $randomOrderSeed, ?bool $reportUselessTests, ?bool $resolveDependencies, ?bool $reverseList, ?bool $stderr, ?bool $strictCoverage, ?string $teamcityLogfile, ?string $testdoxHtmlFile, ?string $testdoxTextFile, ?array $testSuffixes, ?string $testSuite, ?string $excludeTestSuite, bool $useDefaultConfiguration, ?bool $displayDetailsOnAllIssues, ?bool $displayDetailsOnIncompleteTests, ?bool $displayDetailsOnSkippedTests, ?bool $displayDetailsOnTestsThatTriggerDeprecations, ?bool $displayDetailsOnPhpunitDeprecations, ?bool $displayDetailsOnTestsThatTriggerErrors, ?bool $displayDetailsOnTestsThatTriggerNotices, ?bool $displayDetailsOnTestsThatTriggerWarnings, bool $version, ?array $coverageFilter, ?string $logEventsText, ?string $logEventsVerboseText, ?bool $printerTeamCity, ?bool $testdoxPrinter, ?bool $testdoxPrinterSummary, bool $debug, ?array $extensions)
190191
{
191192
$this->arguments = $arguments;
192193
$this->atLeastVersion = $atLeastVersion;
@@ -196,6 +197,7 @@ public function __construct(array $arguments, ?string $atLeastVersion, ?bool $ba
196197
$this->bootstrap = $bootstrap;
197198
$this->cacheDirectory = $cacheDirectory;
198199
$this->cacheResult = $cacheResult;
200+
$this->checkPhpConfiguration = $checkPhpConfiguration;
199201
$this->checkVersion = $checkVersion;
200202
$this->colors = $colors;
201203
$this->columns = $columns;
@@ -454,6 +456,11 @@ public function cacheResult(): bool
454456
return $this->cacheResult;
455457
}
456458

459+
public function checkPhpConfiguration(): bool
460+
{
461+
return $this->checkPhpConfiguration;
462+
}
463+
457464
public function checkVersion(): bool
458465
{
459466
return $this->checkVersion;

src/TextUI/Help.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ private function elements(): array
315315
['arg' => '--version', 'desc' => 'Prints the version and exits'],
316316
['arg' => '--atleast-version <min>', 'desc' => 'Checks that version is greater than <min> and exits'],
317317
['arg' => '--check-version', 'desc' => 'Checks whether PHPUnit is the latest version and exits'],
318+
['arg' => '--check-php-configuration', 'desc' => 'Checks whether PHP configuration follows best practices'],
318319
];
319320

320321
return $elements;

tests/end-to-end/_files/output-cli-help-color.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,6 @@
224224
<min> and exits
225225
--check-version  Checks whether PHPUnit is the latest
226226
version and exits
227+
--check-php-configuration  Checks whether PHP configuration follows
228+
best practices
227229

tests/end-to-end/_files/output-cli-usage.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,4 @@ Miscellaneous:
147147
--version Prints the version and exits
148148
--atleast-version <min> Checks that version is greater than <min> and exits
149149
--check-version Checks whether PHPUnit is the latest version and exits
150+
--check-php-configuration Checks whether PHP configuration follows best practices
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
phpunit --check-php-configuration (failure, Xdebug loaded)
3+
--SKIPIF--
4+
<?php declare(strict_types=1);
5+
if (!extension_loaded('xdebug')) {
6+
print 'skip: Extension Xdebug must be loaded.';
7+
}
8+
--FILE--
9+
<?php
10+
$_SERVER['argv'][] = '--check-php-configuration';
11+
12+
require_once __DIR__ . '/../../bootstrap.php';
13+
14+
ini_set('display_errors', 0);
15+
16+
(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
17+
?>
18+
--EXPECTF--
19+
PHPUnit %s by Sebastian Bergmann and contributors.
20+
21+
Checking whether PHP is configured according to https://docs.phpunit.de/en/%s/installation.html#configuring-php-for-development
22+
23+
display_errors = On ... not ok
24+
display_startup_errors = On ... ok
25+
error_reporting = -1 ... ok
26+
xdebug.show_exception_trace = 0 ... ok
27+
zend.assertions = 1 ... ok
28+
assert.exception = 1 ... ok
29+
memory_limit = -1 ... ok

0 commit comments

Comments
 (0)