diff --git a/composer.json b/composer.json
index e81f8c7..3fc2892 100644
--- a/composer.json
+++ b/composer.json
@@ -56,16 +56,17 @@
"Qameta\\Allure\\PHPUnit\\": "src/"
}
},
- "autoload-dev": {
- "psr-0": {
- "Yandex": "test/"
+ "autoload-dev": {
+ "psr-0": {
+ "Yandex": "test/"
+ },
+ "psr-4": {
+ "Qameta\\Allure\\PHPUnit\\Test\\Unit\\": "test/unit/",
+ "Qameta\\Allure\\PHPUnit\\Test\\Report\\": "test/report/",
+ "Qameta\\Allure\\PHPUnit\\Test\\Integration\\": "test/integration/",
+ "Qameta\\Allure\\PHPUnit\\Scripts\\": "scripts/"
+ }
},
- "psr-4": {
- "Qameta\\Allure\\PHPUnit\\Test\\Unit\\": "test/unit/",
- "Qameta\\Allure\\PHPUnit\\Test\\Report\\": "test/report/",
- "Qameta\\Allure\\PHPUnit\\Scripts\\": "scripts/"
- }
- },
"scripts": {
"test-cs": "vendor/bin/phpcs -sp",
"test-unit": "vendor/bin/phpunit --coverage-text",
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index e6191bc..df4c930 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -14,6 +14,9 @@
test/unit/
+
+ test/integration/HookFailureIntegrationTest.php
+
diff --git a/psalm.xml.dist b/psalm.xml.dist
index 828d139..dec02b2 100644
--- a/psalm.xml.dist
+++ b/psalm.xml.dist
@@ -5,6 +5,7 @@
findUnusedCode="false"
findUnusedPsalmSuppress="false"
findUnusedVariablesAndParams="false"
+ findUnusedIssueHandlerSuppression="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd">
@@ -18,4 +19,13 @@
+
+
+
+
+
+
+
+
diff --git a/src/AllureAdapter.php b/src/AllureAdapter.php
index 2e8e3be..60af350 100644
--- a/src/AllureAdapter.php
+++ b/src/AllureAdapter.php
@@ -27,8 +27,34 @@ final class AllureAdapter implements AllureAdapterInterface
*/
private array $lastRuns = [];
+ /**
+ * @var array
+ */
+ private array $startedTests = [];
+
+ /**
+ * @var array
+ */
+ private array $writtenTests = [];
+
+ /**
+ * @var array
+ */
+ private array $classContainers = [];
+
+ /**
+ * @var array
+ */
+ private array $emittedHookGlobals = [];
+
private ?Throwable $lastException = null;
+ private ?string $activeFixtureUuid = null;
+
+ private ?string $activeHookName = null;
+
+ private ?TestInfo $pendingFinalizeTest = null;
+
private function __construct()
{
}
@@ -73,6 +99,7 @@ public function registerStart(ContainerResult $containerResult, TestResult $test
containerId: $containerResult->getUuid(),
testId: $testResult->getUuid(),
);
+ unset($this->startedTests[$info->getTest()], $this->writtenTests[$info->getTest()]);
return $testResult->getUuid();
}
@@ -115,6 +142,104 @@ public function registerRun(TestResult $testResult, TestInfo $info): TestRunInfo
return $currentRunInfo;
}
+ #[\Override]
+ public function markTestStarted(TestInfo $info): void
+ {
+ $this->startedTests[$info->getTest()] = true;
+ }
+
+ #[\Override]
+ public function wasTestStarted(TestInfo $info): bool
+ {
+ return isset($this->startedTests[$info->getTest()]);
+ }
+
+ #[\Override]
+ public function markTestWritten(TestInfo $info): void
+ {
+ $this->writtenTests[$info->getTest()] = true;
+ }
+
+ #[\Override]
+ public function wasTestWritten(TestInfo $info): bool
+ {
+ return isset($this->writtenTests[$info->getTest()]);
+ }
+
+ #[\Override]
+ public function registerClassContainer(string $className, string $containerUuid): void
+ {
+ $this->classContainers[$className] = $containerUuid;
+ }
+
+ #[\Override]
+ public function getClassContainerId(string $className): ?string
+ {
+ return $this->classContainers[$className] ?? null;
+ }
+
+ #[\Override]
+ public function clearClassContainer(string $className): void
+ {
+ unset($this->classContainers[$className]);
+ }
+
+ #[\Override]
+ public function setActiveFixture(string $uuid, string $hookName): void
+ {
+ $this->activeFixtureUuid = $uuid;
+ $this->activeHookName = $hookName;
+ }
+
+ #[\Override]
+ public function getActiveFixtureUuid(): ?string
+ {
+ return $this->activeFixtureUuid;
+ }
+
+ #[\Override]
+ public function getActiveHookName(): ?string
+ {
+ return $this->activeHookName;
+ }
+
+ #[\Override]
+ public function clearActiveFixture(): void
+ {
+ $this->activeFixtureUuid = null;
+ $this->activeHookName = null;
+ }
+
+ #[\Override]
+ public function hasEmittedHookGlobalError(string $fixtureUuid): bool
+ {
+ return isset($this->emittedHookGlobals[$fixtureUuid]);
+ }
+
+ #[\Override]
+ public function markHookGlobalErrorEmitted(string $fixtureUuid): void
+ {
+ $this->emittedHookGlobals[$fixtureUuid] = true;
+ }
+
+ #[\Override]
+ public function markPendingFinalize(TestInfo $info): void
+ {
+ $this->pendingFinalizeTest = $info;
+ }
+
+ #[\Override]
+ public function getPendingFinalizeTest(): ?TestInfo
+ {
+ return $this->pendingFinalizeTest;
+ }
+
+ #[\Override]
+ public function clearPendingFinalize(): void
+ {
+ $this->pendingFinalizeTest = null;
+ }
+
/**
* @param TestResult $test
* @return list
diff --git a/src/AllureAdapterInterface.php b/src/AllureAdapterInterface.php
index 4f5b432..45e7b53 100644
--- a/src/AllureAdapterInterface.php
+++ b/src/AllureAdapterInterface.php
@@ -25,4 +25,36 @@ public function resetLastException(): void;
public function setLastException(Throwable $e): void;
public function getLastException(): ?Throwable;
+
+ public function markTestStarted(TestInfo $info): void;
+
+ public function wasTestStarted(TestInfo $info): bool;
+
+ public function markTestWritten(TestInfo $info): void;
+
+ public function wasTestWritten(TestInfo $info): bool;
+
+ public function registerClassContainer(string $className, string $containerUuid): void;
+
+ public function getClassContainerId(string $className): ?string;
+
+ public function clearClassContainer(string $className): void;
+
+ public function setActiveFixture(string $uuid, string $hookName): void;
+
+ public function getActiveFixtureUuid(): ?string;
+
+ public function getActiveHookName(): ?string;
+
+ public function clearActiveFixture(): void;
+
+ public function hasEmittedHookGlobalError(string $fixtureUuid): bool;
+
+ public function markHookGlobalErrorEmitted(string $fixtureUuid): void;
+
+ public function markPendingFinalize(TestInfo $info): void;
+
+ public function getPendingFinalizeTest(): ?TestInfo;
+
+ public function clearPendingFinalize(): void;
}
diff --git a/src/AllureExtension.php b/src/AllureExtension.php
index 3c3a37a..3d817c8 100644
--- a/src/AllureExtension.php
+++ b/src/AllureExtension.php
@@ -18,7 +18,9 @@
use Qameta\Allure\PHPUnit\Internal\TestUpdater;
use RuntimeException;
+use function class_exists;
use function file_exists;
+use function interface_exists;
use function is_array;
use const DIRECTORY_SEPARATOR;
@@ -99,7 +101,7 @@ public function bootstrap(Configuration $configuration, Facade $facade, Paramete
$testLifecycle = $this->testLifecycle ?? $this->createTestLifecycle($configSource);
- $facade->registerSubscribers(
+ $subscribers = [
new Event\TestPreparationStartedSubscriber($testLifecycle),
new Event\TestPreparedSubscriber($testLifecycle),
new Event\TestFinishedSubscriber($testLifecycle),
@@ -110,6 +112,211 @@ public function bootstrap(Configuration $configuration, Facade $facade, Paramete
new Event\TestWarningTriggeredSubscriber($testLifecycle),
new Event\TestConsideredRiskySubscriber($testLifecycle),
new Event\TestPassedSubscriber($testLifecycle),
+ new Event\TestSuiteFinishedSubscriber($testLifecycle),
+ ];
+
+ $facade->registerSubscribers(...$subscribers, ...$this->createHookSubscribers($testLifecycle));
+ }
+
+ /**
+ * @return list