Skip to content

Commit

Permalink
Add phpunit v10 testing support (#2133)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek authored Nov 26, 2023
1 parent 15f5d10 commit cb8e2d0
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 56 deletions.
48 changes: 24 additions & 24 deletions .github/workflows/test-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ jobs:
- name: Install PHP dependencies
run: |
if [ "${{ matrix.type }}" != "Phpunit" ] && [ "${{ matrix.type }}" != "StaticAnalysis" ]; then composer remove --no-interaction --no-update phpunit/phpunit johnkary/phpunit-speedtrap --dev; fi
if [ "${{ matrix.type }}" != "CodingStyle" ]; then composer remove --no-interaction --no-update friendsofphp/php-cs-fixer --dev; fi
if [ "${{ matrix.type }}" != "Phpunit" ] && [ "${{ matrix.type }}" != "StaticAnalysis" ]; then composer remove --no-interaction --no-update phpunit/phpunit atk4/ergebnis-phpunit-slow-test-detector --dev; fi
if [ "${{ matrix.type }}" != "CodingStyle" ]; then composer remove --no-interaction --no-update friendsofphp/php-cs-fixer ergebnis/composer-normalize --dev; fi
if [ "${{ matrix.type }}" != "StaticAnalysis" ]; then composer remove --no-interaction --no-update phpstan/\* behat/\* --dev; fi
composer update --ansi --prefer-dist --no-interaction --no-progress --optimize-autoloader
- name: "Run tests: SQLite (only for Phpunit)"
if: startsWith(matrix.type, 'Phpunit')
run: |
php demos/_demo-data/create-db.php
vendor/bin/phpunit --exclude-group none --no-coverage -v
vendor/bin/phpunit --exclude-group none --no-coverage --fail-on-warning --fail-on-risky $(if vendor/bin/phpunit --version | grep -q '^PHPUnit 9\.'; then echo -v; else echo --fail-on-notice --fail-on-deprecation --display-notices --display-deprecations --display-warnings --display-errors --display-incomplete --display-skipped; fi)
- name: Check Coding Style (only for CodingStyle)
if: matrix.type == 'CodingStyle'
Expand Down Expand Up @@ -133,13 +133,13 @@ jobs:
- name: Install PHP dependencies
run: |
if [ "${{ matrix.type }}" != "Phpunit" ] && [ "${{ matrix.type }}" != "Phpunit Lowest" ] && [ "${{ matrix.type }}" != "Phpunit Burn" ]; then composer remove --no-interaction --no-update phpunit/phpunit johnkary/phpunit-speedtrap --dev; fi
if [ "${{ matrix.type }}" != "CodingStyle" ]; then composer remove --no-interaction --no-update friendsofphp/php-cs-fixer --dev; fi
if [ "${{ matrix.type }}" != "Phpunit" ] && [ "${{ matrix.type }}" != "Phpunit Lowest" ] && [ "${{ matrix.type }}" != "Phpunit Burn" ]; then composer remove --no-interaction --no-update phpunit/phpunit atk4/ergebnis-phpunit-slow-test-detector --dev; fi
if [ "${{ matrix.type }}" != "CodingStyle" ]; then composer remove --no-interaction --no-update friendsofphp/php-cs-fixer ergebnis/composer-normalize --dev; fi
if [ "${{ matrix.type }}" != "StaticAnalysis" ]; then composer remove --no-interaction --no-update phpstan/\* behat/\* --dev; fi
if [ -n "$LOG_COVERAGE" ]; then composer require --no-interaction --no-install phpunit/phpcov; fi
composer update --ansi --prefer-dist --no-interaction --no-progress --optimize-autoloader
if [ "${{ matrix.type }}" = "Phpunit Lowest" ]; then composer update --ansi --prefer-dist --prefer-lowest --prefer-stable --no-interaction --no-progress --optimize-autoloader; fi
if [ "${{ matrix.type }}" = "Phpunit Burn" ]; then sed -i 's~ *public function runBare(): void~public function runBare(): void { gc_collect_cycles(); gc_collect_cycles(); $memDiffs = array_fill(0, '"$(if [ \"$GITHUB_EVENT_NAME\" == \"schedule\" ]; then echo 64; else echo 16; fi)"', 0); for ($i = -1; $i < count($memDiffs); ++$i) { $this->_runBare(); gc_collect_cycles(); gc_collect_cycles(); $mem = memory_get_usage(); if ($i !== -1) { $memDiffs[$i] = $mem - $memPrev; } $memPrev = $mem; rsort($memDiffs); if (array_sum($memDiffs) >= 4096 * 1024 || $memDiffs[2] > 0) { $this->onNotSuccessfulTest(new AssertionFailedError("Memory leak detected! (" . implode(" + ", array_map(static fn ($v) => number_format($v / 1024, 3, ".", " "), array_filter($memDiffs))) . " KB, " . ($i + 2) . " iterations)")); } } } private function _runBare(): void~' vendor/phpunit/phpunit/src/Framework/TestCase.php && cat vendor/phpunit/phpunit/src/Framework/TestCase.php | grep '_runBare('; fi
if [ "${{ matrix.type }}" = "Phpunit Burn" ]; then sed -i 's~public function runBare(): void~public function runBare(): void { gc_collect_cycles(); gc_collect_cycles(); $memDiffs = array_fill(0, '"$(if [ \"$GITHUB_EVENT_NAME\" == \"schedule\" ]; then echo 64; else echo 16; fi)"', 0); for ($i = -1; $i < count($memDiffs); ++$i) { $this->_runBare(); gc_collect_cycles(); gc_collect_cycles(); $mem = memory_get_usage(); if ($i !== -1) { $memDiffs[$i] = $mem - $memPrev; } $memPrev = $mem; rsort($memDiffs); if (array_sum($memDiffs) >= 4096 * 1024 || $memDiffs[2] > 0) { $this->onNotSuccessfulTest(new AssertionFailedError("Memory leak detected! (" . implode(" + ", array_map(static fn ($v) => number_format($v / 1024, 3, ".", " "), array_filter($memDiffs))) . " KB, " . ($i + 2) . " iterations)")); } } } private function _runBare(): void~' vendor/phpunit/phpunit/src/Framework/TestCase.php && cat vendor/phpunit/phpunit/src/Framework/TestCase.php | grep '_runBare('; fi
- name: Init
run: |
Expand All @@ -152,31 +152,31 @@ jobs:
- name: "Run tests: SQLite"
run: |
php demos/_demo-data/create-db.php
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) -v
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) --fail-on-warning --fail-on-risky $(if vendor/bin/phpunit --version | grep -q '^PHPUnit 9\.'; then echo -v; else echo --fail-on-notice --fail-on-deprecation --display-notices --display-deprecations --display-warnings --display-errors --display-incomplete --display-skipped; fi)
if [ -n "$LOG_COVERAGE" ]; then mv coverage/phpunit.cov coverage/phpunit-sqlite.cov; fi
- name: "Run tests: MySQL"
if: success() || failure()
- name: "Run tests: MySQL (only for cron)"
if: (success() || failure()) && github.event_name == 'schedule'
env:
DB_DSN: "mysql:host=mysql;dbname=atk4_test"
DB_USER: atk4_test_user
DB_PASSWORD: atk4_pass
run: |
sed -E "s~(\\\$db = new.+Persistence\\\\Sql)\(.+\);~\\1('$DB_DSN', '$DB_USER', '$DB_PASSWORD');~g" -i demos/db.default.php
php demos/_demo-data/create-db.php
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) -v
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) --fail-on-warning --fail-on-risky $(if vendor/bin/phpunit --version | grep -q '^PHPUnit 9\.'; then echo -v; else echo --fail-on-notice --fail-on-deprecation --display-notices --display-deprecations --display-warnings --display-errors --display-incomplete --display-skipped; fi)
if [ -n "$LOG_COVERAGE" ]; then mv coverage/phpunit.cov coverage/phpunit-mysql.cov; fi
- name: "Run tests: MariaDB (only for cron)"
if: (success() || failure()) && github.event_name == 'schedule'
- name: "Run tests: MariaDB"
if: success() || failure()
env:
DB_DSN: "mysql:host=mariadb;dbname=atk4_test"
DB_USER: atk4_test_user
DB_PASSWORD: atk4_pass
run: |
sed -E "s~(\\\$db = new.+Persistence\\\\Sql)\(.+\);~\\1('$DB_DSN', '$DB_USER', '$DB_PASSWORD');~g" -i demos/db.default.php
php demos/_demo-data/create-db.php
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) -v
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) --fail-on-warning --fail-on-risky $(if vendor/bin/phpunit --version | grep -q '^PHPUnit 9\.'; then echo -v; else echo --fail-on-notice --fail-on-deprecation --display-notices --display-deprecations --display-warnings --display-errors --display-incomplete --display-skipped; fi)
if [ -n "$LOG_COVERAGE" ]; then mv coverage/phpunit.cov coverage/phpunit-mariadb.cov; fi
- name: "Run tests: PostgreSQL (only for cron)"
Expand All @@ -188,7 +188,7 @@ jobs:
run: |
sed -E "s~(\\\$db = new.+Persistence\\\\Sql)\(.+\);~\\1('$DB_DSN', '$DB_USER', '$DB_PASSWORD');~g" -i demos/db.default.php
php demos/_demo-data/create-db.php
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) -v
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) --fail-on-warning --fail-on-risky $(if vendor/bin/phpunit --version | grep -q '^PHPUnit 9\.'; then echo -v; else echo --fail-on-notice --fail-on-deprecation --display-notices --display-deprecations --display-warnings --display-errors --display-incomplete --display-skipped; fi)
if [ -n "$LOG_COVERAGE" ]; then mv coverage/phpunit.cov coverage/phpunit-postgres.cov; fi
- name: "Run tests: MSSQL (only for cron)"
Expand All @@ -200,20 +200,20 @@ jobs:
run: |
sed -E "s~(\\\$db = new.+Persistence\\\\Sql)\(.+\);~\\1('$DB_DSN', '$DB_USER', '$DB_PASSWORD');~g" -i demos/db.default.php
php demos/_demo-data/create-db.php
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) -v
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) --fail-on-warning --fail-on-risky $(if vendor/bin/phpunit --version | grep -q '^PHPUnit 9\.'; then echo -v; else echo --fail-on-notice --fail-on-deprecation --display-notices --display-deprecations --display-warnings --display-errors --display-incomplete --display-skipped; fi)
if [ -n "$LOG_COVERAGE" ]; then mv coverage/phpunit.cov coverage/phpunit-mssql.cov; fi
- name: "Run tests: Oracle (only for cron)"
if: (success() || failure()) && github.event_name == 'schedule'
env:
DB_DSN: "oci:dbname=oracle/xe"
DB_DSN: "oci:dbname=oracle/free"
DB_USER: system
DB_PASSWORD: atk4_pass
NLS_LANG: AMERICAN_AMERICA.AL32UTF8
run: |
sed -E "s~(\\\$db = new.+Persistence\\\\Sql)\(.+\);~\\1('$DB_DSN', '$DB_USER', '$DB_PASSWORD');~g" -i demos/db.default.php
php demos/_demo-data/create-db.php
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) -v
php -d opcache.enable_cli=1 vendor/bin/phpunit --exclude-group none $(if [ -n "$LOG_COVERAGE" ]; then echo --coverage-text; else echo --no-coverage; fi) --fail-on-warning --fail-on-risky $(if vendor/bin/phpunit --version | grep -q '^PHPUnit 9\.'; then echo -v; else echo --fail-on-notice --fail-on-deprecation --display-notices --display-deprecations --display-warnings --display-errors --display-incomplete --display-skipped; fi)
if [ -n "$LOG_COVERAGE" ]; then mv coverage/phpunit.cov coverage/phpunit-oracle.cov; fi
- name: Upload coverage logs 1/2 (only for latest Phpunit)
Expand Down Expand Up @@ -353,8 +353,8 @@ jobs:
- name: Install PHP dependencies
run: |
composer remove --no-interaction --no-update phpunit/phpunit johnkary/phpunit-speedtrap --dev
composer remove --no-interaction --no-update friendsofphp/php-cs-fixer --dev
composer remove --no-interaction --no-update phpunit/phpunit atk4/ergebnis-phpunit-slow-test-detector --dev
composer remove --no-interaction --no-update friendsofphp/php-cs-fixer ergebnis/composer-normalize --dev
composer remove --no-interaction --no-update phpstan/\* --dev
if [ -n "$LOG_COVERAGE" ]; then composer require --no-interaction --no-install phpunit/phpcov; fi
composer update --ansi --prefer-dist --no-interaction --no-progress --optimize-autoloader
Expand Down Expand Up @@ -383,8 +383,8 @@ jobs:
php demos/_demo-data/create-db.php
vendor/bin/behat -vv --config behat.yml.dist
- name: "Run tests: MySQL (only for coverage or cron)"
if: (success() || failure()) && (env.LOG_COVERAGE || github.event_name == 'schedule')
- name: "Run tests: MySQL (only for cron)"
if: (success() || failure()) && github.event_name == 'schedule'
env:
DB_DSN: "mysql:host=mysql;dbname=atk4_test"
DB_USER: atk4_test_user
Expand All @@ -394,8 +394,8 @@ jobs:
php demos/_demo-data/create-db.php
vendor/bin/behat -vv --config behat.yml.dist
- name: "Run tests: MariaDB (only for cron)"
if: (success() || failure()) && github.event_name == 'schedule'
- name: "Run tests: MariaDB (only for coverage or cron)"
if: (success() || failure()) && (env.LOG_COVERAGE || github.event_name == 'schedule')
env:
DB_DSN: "mysql:host=mariadb;dbname=atk4_test"
DB_USER: atk4_test_user
Expand Down Expand Up @@ -430,7 +430,7 @@ jobs:
- name: "Run tests: Oracle (only for cron)"
if: (success() || failure()) && github.event_name == 'schedule'
env:
DB_DSN: "oci:dbname=oracle/xe"
DB_DSN: "oci:dbname=oracle/free"
DB_USER: system
DB_PASSWORD: atk4_pass
NLS_LANG: AMERICAN_AMERICA.AL32UTF8
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,17 @@
},
"require-dev": {
"atk4/behat-mink-selenium2-driver": "^1.6.2",
"atk4/ergebnis-phpunit-slow-test-detector": "^2.4",
"behat/mink-extension": "^2.3.1",
"ergebnis/composer-normalize": "^2.13",
"friendsofphp/php-cs-fixer": "^3.0",
"fzaninotto/faker": "^1.6",
"guzzlehttp/guzzle": "^7.3",
"johnkary/phpunit-speedtrap": "^3.3",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.0",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-strict-rules": "^1.3",
"phpunit/phpunit": "^9.5.5",
"phpunit/phpunit": "^9.5.5 || ^10.0",
"symfony/process": "^4.4.30 || ^5.3.7 || ^6.0"
},
"conflict": {
Expand Down
10 changes: 10 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ parameters:
- '~^Only booleans are allowed in .+, .+ given( on the (left|right) side)?\.~'
- '~^Variable (static )?(property access|method call) on .+\.~'

# remove once PHPUnit 9.x support is removed
-
path: 'tests/DemosTest.php'
message: '~^Access to constant (STATUS_PASSED|STATUS_INCOMPLETE|STATUS_SKIPPED) on an unknown class PHPUnit\\Runner\\BaseTestRunner\.$~'
count: 3
-
path: 'tests/DemosTest.php'
message: '~^Call to an undefined method Atk4\\Ui\\Tests\\DemosTest::(getName|getStatus)\(\)\.$~'
count: 4

# TODO these rules are generated, this ignores should be fixed in the code
# for level = 2
-
Expand Down
12 changes: 7 additions & 5 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<phpunit bootstrap="vendor/autoload.php" printerClass="Atk4\Core\Phpunit\ResultPrinter" colors="true">
<phpunit bootstrap="vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="tests">
<directory>tests</directory>
Expand All @@ -16,17 +16,19 @@
<group>require_session</group>
</exclude>
</groups>
<listeners>
<listener class="JohnKary\PHPUnit\Listener\SpeedTrapListener" />
</listeners>
<coverage>
<extensions>
<bootstrap class="Ergebnis\PHPUnit\SlowTestDetector\Extension" />
</extensions>
<source>
<include>
<directory>src</directory>
<directory>tests</directory>
</include>
<exclude>
<directory>src/Behat</directory>
</exclude>
</source>
<coverage>
<report>
<php outputFile="coverage/phpunit.cov" />
</report>
Expand Down
2 changes: 1 addition & 1 deletion src/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public function __construct(array $defaults = [])
if ($this->catchExceptions) {
set_exception_handler(\Closure::fromCallable([$this, 'caughtException']));
set_error_handler(static function (int $severity, string $msg, string $file, int $line): bool {
if ((error_reporting() & ~(\PHP_MAJOR_VERSION >= 8 ? 4437 : 0)) === 0) {
if ((error_reporting() & ~(\PHP_MAJOR_VERSION >= 8 ? (\E_ERROR | \E_PARSE | \E_CORE_ERROR | \E_COMPILE_ERROR | \E_USER_ERROR | \E_RECOVERABLE_ERROR) : 0)) === 0) {
$isFirstFrame = true;
foreach (array_slice(debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 10), 1) as $frame) {
// allow to suppress any warning outside Atk4
Expand Down
8 changes: 4 additions & 4 deletions src/Behat/CoverageUtil.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,18 @@ public static function startFromPhpunitConfig(string $phpunitConfigDir): void
{
$filter = new Filter();

$phpunitCoverageConfig = simplexml_load_file($phpunitConfigDir . '/phpunit.xml.dist')->coverage;
$phpunitCoverageConfig = simplexml_load_file($phpunitConfigDir . '/phpunit.xml.dist')->source;
foreach ($phpunitCoverageConfig->include->directory ?? [] as $path) {
$filter->includeDirectory($phpunitConfigDir . '/' . $path);
$filter->includeDirectory($phpunitConfigDir . '/' . $path); // @phpstan-ignore-line
}
foreach ($phpunitCoverageConfig->include->file ?? [] as $path) {
$filter->includeFile($phpunitConfigDir . '/' . $path);
}
foreach ($phpunitCoverageConfig->exclude->directory ?? [] as $path) {
$filter->excludeDirectory($phpunitConfigDir . '/' . $path);
$filter->excludeDirectory($phpunitConfigDir . '/' . $path); // @phpstan-ignore-line
}
foreach ($phpunitCoverageConfig->exclude->file ?? [] as $path) {
$filter->excludeFile($phpunitConfigDir . '/' . $path);
$filter->excludeFile($phpunitConfigDir . '/' . $path); // @phpstan-ignore-line
}

static::start($filter);
Expand Down
2 changes: 1 addition & 1 deletion tests/AppTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public function testEmptyRequestPathException(): void
$this->createApp(['request' => $request]);
}

public function provideUrlCases(): iterable
public static function provideUrlCases(): iterable
{
foreach (['/', '/page.html', '/d/', '/0/index.php'] as $requestPage) {
yield [$requestPage, [], ['x'], [], 'x.php'];
Expand Down
2 changes: 1 addition & 1 deletion tests/DemosHttpTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public function testDemoLateOutputError(string $urlTrigger, string $expectedOutp
self::assertSame($expectedOutput, $response->getBody()->getContents());
}

public function provideDemoLateOutputErrorCases(): iterable
public static function provideDemoLateOutputErrorCases(): iterable
{
$hOutput = "\n" . '!! FATAL UI ERROR: Headers already sent, more headers cannot be set at this stage !!' . "\n";
$oOutput = 'unmanaged output' . "\n" . '!! FATAL UI ERROR: Unexpected output detected !!' . "\n";
Expand Down
Loading

0 comments on commit cb8e2d0

Please sign in to comment.