Skip to content

Commit

Permalink
Extension rewritten for PHPUnit 10 (allure-framework#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
remorhaz committed Dec 22, 2022
1 parent ffae8d9 commit add07eb
Show file tree
Hide file tree
Showing 29 changed files with 455 additions and 224 deletions.
7 changes: 3 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ jobs:
fail-fast: false
matrix:
php-version:
- "8.0"
- "8.1"
- "8.2"
os:
Expand Down Expand Up @@ -49,15 +48,15 @@ jobs:
${{ matrix.composer-options }}

- name: Run tests
if: ${{ matrix.os != 'windows-latest' && matrix.php-version != '8.2' }}
if: ${{ matrix.os != 'windows-latest' }}
run: composer test

- name: Run tests (windows)
if: ${{ matrix.os == 'windows-latest' && matrix.php-version != '8.2' }}
if: ${{ matrix.os == 'windows-latest' }}
run: composer test-windows

- name: Run tests (experimental)
if: ${{ matrix.os != 'windows-latest' && matrix.php-version == '8.2' }}
if: ${{ matrix.os != 'windows-latest' }}
continue-on-error: true
run: composer test

Expand Down
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,18 @@ In order to use this adapter you need to add a new dependency to your **composer
```
{
"require": {
"php": "^8",
"php": "^8.1",
"allure-framework/allure-phpunit": "^2"
}
}
```
Then add Allure test listener in **phpunit.xml** file:
```xml
<extensions>
<extension class="Qameta\Allure\PHPUnit\AllureExtension">
<!-- Optional arguments block; omit it if you want to use default values -->
<arguments>
<!-- Path to config file (default is config/allure.config.php) -->
<string>config/allure.config.php</string>
</arguments>
</extension>
<bootstrap class="Qameta\Allure\PHPUnit\AllureExtension">
<!-- Path to config file (default is config/allure.config.php) -->
<parameter name="config" value="config/allure.config.php" />
</bootstrap>
</extensions>
```
Config is common PHP file that should return an array:
Expand Down
23 changes: 10 additions & 13 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"name": "allure-framework/allure-phpunit",
"minimum-stability": "dev",
"prefer-stable": true,
"keywords": [
"phpunit",
"testing",
Expand Down Expand Up @@ -29,15 +31,12 @@
"source": "https://github.com/allure-framework/allure-phpunit"
},
"require": {
"php": "^8",
"php": "~8.1 || ~8.2",
"allure-framework/allure-php-commons": "^2",
"phpunit/phpunit": "^9"
"phpunit/phpunit": "^10@dev"
},
"require-dev": {
"brianium/paratest": "^6.7",
"psalm/plugin-phpunit": "^0.18.4",
"squizlabs/php_codesniffer": "^3.6.2",
"vimeo/psalm": "^5.4"
"squizlabs/php_codesniffer": "^3.6.2"
},
"conflict": {
"amphp/byte-stream": "<1.5.1"
Expand All @@ -62,9 +61,9 @@
"clear-allure-results": "rm -rf ./build/allure-results",
"test-report": [
"@clear-allure-results",
"vendor/bin/paratest --processes=3 --configuration=phpunit.report.xml --testsuite=positive",
"vendor/bin/paratest --processes=3 --configuration=phpunit.report.xml --testsuite=negative; exit 0",
"vendor/bin/paratest --processes=3 --configuration=phpunit.report.xml --testsuite=retries --repeat=3; exit 0"
"vendor/bin/phpunit --configuration=phpunit.report.xml --testsuite=positive",
"vendor/bin/phpunit --configuration=phpunit.report.xml --testsuite=negative; exit 0",
"vendor/bin/phpunit --configuration=phpunit.report.xml --testsuite=retries --repeat=3; exit 0"
],
"test-report-windows": [
"@clear-allure-results",
Expand All @@ -76,14 +75,12 @@
"test": [
"@test-cs",
"@test-unit",
"@test-report",
"@test-psalm"
"@test-report"
],
"test-windows": [
"@test-cs",
"@test-unit",
"@test-report-windows",
"@test-psalm"
"@test-report-windows"
]
}
}
4 changes: 2 additions & 2 deletions phpunit.report.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd"
colors="true"
defaultTestSuite="positive">
<testsuites>
Expand All @@ -18,6 +18,6 @@
</testsuite>
</testsuites>
<extensions>
<extension class="Qameta\Allure\PHPUnit\AllureExtension" />
<bootstrap class="Qameta\Allure\PHPUnit\AllureExtension" />
</extensions>
</phpunit>
4 changes: 2 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd"
colors="true"
defaultTestSuite="unit">
<testsuites>
<testsuite name="unit">
<directory>test/unit/</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<coverage>
<include>
<directory suffix=".php">src/</directory>
</include>
Expand Down
140 changes: 27 additions & 113 deletions src/AllureExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,12 @@

namespace Qameta\Allure\PHPUnit;

use PHPUnit\Runner\AfterIncompleteTestHook;
use PHPUnit\Runner\AfterRiskyTestHook;
use PHPUnit\Runner\AfterSkippedTestHook;
use PHPUnit\Runner\AfterSuccessfulTestHook;
use PHPUnit\Runner\AfterTestErrorHook;
use PHPUnit\Runner\AfterTestFailureHook;
use PHPUnit\Runner\AfterTestHook;
use PHPUnit\Runner\AfterTestWarningHook;
use PHPUnit\Runner\BeforeTestHook;
use PHPUnit\Runner\Extension\Extension;
use PHPUnit\Runner\Extension\Facade;
use PHPUnit\Runner\Extension\ParameterCollection;
use PHPUnit\TextUI\Configuration\Configuration;
use Qameta\Allure\Allure;
use Qameta\Allure\Model\LinkType;
use Qameta\Allure\Model\Status;
use Qameta\Allure\PHPUnit\Internal\Config;
use Qameta\Allure\PHPUnit\Internal\ConfigInterface;
use Qameta\Allure\PHPUnit\Internal\DefaultThreadDetector;
Expand All @@ -29,37 +23,20 @@

use const DIRECTORY_SEPARATOR;

final class AllureExtension implements
BeforeTestHook,
AfterTestHook,
AfterTestFailureHook,
AfterTestErrorHook,
AfterIncompleteTestHook,
AfterSkippedTestHook,
AfterTestWarningHook,
AfterRiskyTestHook,
AfterSuccessfulTestHook
final class AllureExtension implements Extension
{
private const DEFAULT_OUTPUT_DIRECTORY = 'build' . DIRECTORY_SEPARATOR . 'allure-results';

private const DEFAULT_CONFIG_FILE = 'config' . DIRECTORY_SEPARATOR . 'allure.config.php';

private TestLifecycleInterface $testLifecycle;

public function __construct(
string|array|ConfigInterface|TestLifecycleInterface|null $configOrTestLifecycle = null,
private readonly ?TestLifecycleInterface $testLifecycle = null,
) {
$this->testLifecycle = $configOrTestLifecycle instanceof TestLifecycleInterface
? $configOrTestLifecycle
: $this->createTestLifecycle($configOrTestLifecycle);
}

private function createTestLifecycle(string|array|ConfigInterface|null $configSource): TestLifecycleInterface
private function createTestLifecycle(?string $configSource): TestLifecycleInterface
{
$config = $configSource instanceof ConfigInterface
? $configSource
: $this->loadConfig($configSource);

$config = new Config($this->loadConfigData($configSource));
$this->setupAllure($config);

return new TestLifecycle(
Expand Down Expand Up @@ -95,15 +72,6 @@ private function setupAllure(ConfigInterface $config): void
}
}

private function loadConfig(string|array|null $configSource): ConfigInterface
{
return new Config(
is_array($configSource)
? $configSource
: $this->loadConfigData($configSource),
);
}

private function loadConfigData(?string $configFile): array
{
$fileShouldExist = isset($configFile);
Expand All @@ -121,80 +89,26 @@ private function loadConfigData(?string $configFile): array

return [];
}
public function executeBeforeTest(string $test): void
{
$this
->testLifecycle
->switchTo($test)
->reset()
->create()
->updateInfo()
->start();
}

public function executeAfterTest(string $test, float $time): void
{
$this
->testLifecycle
->switchTo($test)
->stop()
->updateRunInfo()
->write();
}

public function executeAfterTestFailure(string $test, string $message, float $time): void
{
$this
->testLifecycle
->switchTo($test)
->updateDetectedStatus($message, Status::failed(), Status::failed());
}

public function executeAfterTestError(string $test, string $message, float $time): void
{
$this
->testLifecycle
->switchTo($test)
->updateDetectedStatus($message, Status::broken());
}

public function executeAfterIncompleteTest(string $test, string $message, float $time): void
{
$this
->testLifecycle
->switchTo($test)
->updateStatus($message, Status::broken());
}

public function executeAfterSkippedTest(string $test, string $message, float $time): void
{
$this
->testLifecycle
->switchTo($test)
->updateStatus($message, Status::skipped());
}

public function executeAfterTestWarning(string $test, string $message, float $time): void
public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters): void
{
$this
->testLifecycle
->switchTo($test)
->updateStatus($message, Status::broken());
}

public function executeAfterRiskyTest(string $test, string $message, float $time): void
{
$this
->testLifecycle
->switchTo($test)
->updateStatus($message, Status::failed());
}

public function executeAfterSuccessfulTest(string $test, float $time): void
{
$this
->testLifecycle
->switchTo($test)
->updateStatus(status: Status::passed());
$configSource = $parameters->has('config')
? $parameters->get('config')
: null;

$testLifecycle = $this->testLifecycle ?? $this->createTestLifecycle($configSource);

$facade->registerSubscribers(
new Event\TestPreparationStartedSubscriber($testLifecycle),
new Event\TestPreparedSubscriber($testLifecycle),
new Event\TestFinishedSubscriber($testLifecycle),
new Event\TestFailedSubscriber($testLifecycle),
new Event\TestErroredSubscriber($testLifecycle),
new Event\TestMarkedIncompleteSubscriber($testLifecycle),
new Event\TestSkippedSubscriber($testLifecycle),
new Event\TestWarningTriggeredSubscriber($testLifecycle),
new Event\TestConsideredRiskySubscriber($testLifecycle),
new Event\TestPassedSubscriber($testLifecycle),
);
}
}
33 changes: 33 additions & 0 deletions src/Event/TestConsideredRiskySubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Qameta\Allure\PHPUnit\Event;

use PHPUnit\Event\Code\TestMethod;
use PHPUnit\Event\Test\ConsideredRisky;
use PHPUnit\Event\Test\ConsideredRiskySubscriber;
use Qameta\Allure\Model\Status;
use Qameta\Allure\PHPUnit\Internal\TestLifecycleInterface;

final class TestConsideredRiskySubscriber implements ConsideredRiskySubscriber
{
public function __construct(
private readonly TestLifecycleInterface $testLifecycle,
) {
}

public function notify(ConsideredRisky $event): void
{
$test = $event->test();
$method = $test instanceof TestMethod ? $test->nameWithClass() : null;
if (!isset($method)) {
return;
}

$this
->testLifecycle
->switchTo($method)
->updateStatus($event->message(), Status::failed());
}
}
33 changes: 33 additions & 0 deletions src/Event/TestErroredSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Qameta\Allure\PHPUnit\Event;

use PHPUnit\Event\Code\TestMethod;
use PHPUnit\Event\Test\Errored;
use PHPUnit\Event\Test\ErroredSubscriber;
use Qameta\Allure\Model\Status;
use Qameta\Allure\PHPUnit\Internal\TestLifecycleInterface;

final class TestErroredSubscriber implements ErroredSubscriber
{
public function __construct(
private readonly TestLifecycleInterface $testLifecycle,
) {
}

public function notify(Errored $event): void
{
$test = $event->test();
$method = $test instanceof TestMethod ? $test->nameWithClass() : null;
if (!isset($method)) {
return;
}

$this
->testLifecycle
->switchTo($method)
->updateDetectedStatus($event->throwable()->message(), Status::broken());
}
}
Loading

0 comments on commit add07eb

Please sign in to comment.