Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ Add the following lines to the `phpunit.xml` file:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./vendor/autoload.php">
<extensions>
<bootstrap class="Qase\PHPUnitReporter\QaseExtension"/>
<bootstrap class="Qase\PHPUnitReporter\QaseExtension">
<!-- optional parameters -->
<parameter name="onlyReportTestsWithSuite" value="true"/>
<parameter name="formatTitleFromMethodName" value="true"/>
</bootstrap>
</extensions>
</phpunit>
```
Expand Down Expand Up @@ -116,6 +120,7 @@ Qase PHPUnit Reporter can be configured using:

1. A separate configuration file qase.config.json.
2. Environment variables (which override the values in the configuration file).
3. Additional configuration options via phpunit.xml (`onlyReportTestsWithSuite` and `formatTitleFromMethodName` are currently supported)

For a full list of configuration options, refer to
the [Configuration Reference](https://github.com/qase-tms/qase-php-commons/blob/main/README.md#configuration).
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"require": {
"php": "^8.1",
"phpunit/phpunit": "^10 || ^11",
"qase/php-commons": "^2.1.1"
"qase/php-commons": "^2.1.1",
"ext-mbstring": "*"
},
"autoload": {
"psr-4": {
Expand Down
14 changes: 14 additions & 0 deletions src/Config/PhpUnitConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace Qase\PHPUnitReporter\Config;

class PhpUnitConfig
{
public function __construct(
public readonly bool $debug = false,
public readonly bool $onlyReportTestsWithSuite = false,
public readonly bool $formatTitleFromMethodName = false,
)
{
}
}
32 changes: 32 additions & 0 deletions src/Config/PhpUnitConfigFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace Qase\PHPUnitReporter\Config;
use PHPUnit\Runner\Extension\ParameterCollection;

class PhpUnitConfigFactory
{
public function create(?ParameterCollection $parameters = null): PhpUnitConfig
{
if ($parameters === null) {
return new PhpUnitConfig();
}

$onlyReportTestsWithSuite = $parameters->has('onlyReportTestsWithSuite') && $this->castToBool($parameters->get('onlyReportTestsWithSuite'));
$debug = $parameters->has('debug') && $this->castToBool($parameters->get('debug'));
$formatTitleFromMethodName = $parameters->has('formatTitleFromMethodName') && $this->castToBool($parameters->get('formatTitleFromMethodName'));

return new PhpUnitConfig(
$debug,
$onlyReportTestsWithSuite,
$formatTitleFromMethodName,
);
}

private function castToBool(string $value): bool
{
return match ($value) {
'true', '1', 'yes' => true,
default => false,
};
}
}
6 changes: 4 additions & 2 deletions src/QaseExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ final class QaseExtension implements Extension
{
public function bootstrap(Configuration $configuration, Facade $facade, ParameterCollection $parameters): void
{
$logger = new Logger();
$configFactory = new Config\PhpUnitConfigFactory();
$config = $configFactory->create($parameters);
$logger = new Logger($config->debug);
$coreReporter = ReporterFactory::create("phpunit/phpunit", "qase/phpunit-reporter");
$attributeReader = new AttributeReader();
$attributeParser = new AttributeParser($logger, $attributeReader);

$reporter = QaseReporter::getInstance($attributeParser, $coreReporter);
$reporter = QaseReporter::getInstance($attributeParser, $coreReporter, $config);

$facade->registerSubscribers(
new Events\TestConsideredRiskySubscriber($reporter),
Expand Down
68 changes: 50 additions & 18 deletions src/QaseReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,30 @@
use Qase\PhpCommons\Models\Result;
use Qase\PhpCommons\Utils\Signature;
use Qase\PHPUnitReporter\Attributes\AttributeParserInterface;
use Qase\PHPUnitReporter\Config\PhpUnitConfig;

class QaseReporter implements QaseReporterInterface
{
private static QaseReporter $instance;
private array $testResults = [];
private AttributeParserInterface $attributeParser;
private ReporterInterface $reporter;
private ?string $currentKey = null;

private function __construct(AttributeParserInterface $attributeParser, ReporterInterface $reporter)
protected static QaseReporter $instance;
protected array $testResults = [];
protected ?string $currentKey = null;

protected function __construct(
protected readonly AttributeParserInterface $attributeParser,
protected readonly ReporterInterface $reporter,
protected readonly PhpUnitConfig $config,
)
{
$this->attributeParser = $attributeParser;
$this->reporter = $reporter;
}

public static function getInstance(AttributeParserInterface $attributeParser, ReporterInterface $reporter): QaseReporter
public static function getInstance(
AttributeParserInterface $attributeParser,
ReporterInterface $reporter,
PhpUnitConfig $config,
): QaseReporter
{
if (!isset(self::$instance)) {
self::$instance = new QaseReporter($attributeParser, $reporter);
self::$instance = new QaseReporter($attributeParser, $reporter, $config);
}
return self::$instance;
}
Expand All @@ -51,7 +56,6 @@ public function completeTestRun(): void
public function startTest(TestMethod $test): void
{
$key = $this->getTestKey($test);
$this->currentKey = $key;

$metadata = $this->attributeParser->parseAttribute($test->className(), $test->methodName());

Expand All @@ -62,6 +66,9 @@ public function startTest(TestMethod $test): void
}

if (empty($metadata->suites)) {
if ($this->config->onlyReportTestsWithSuite){
return;
}
$suites = explode('\\', $test->className());
foreach ($suites as $suite) {
$testResult->relations->addSuite($suite);
Expand All @@ -77,8 +84,9 @@ public function startTest(TestMethod $test): void
$testResult->signature = $this->createSignature($test, $metadata->qaseIds, $metadata->suites, $metadata->parameters);
$testResult->execution->setThread($this->getThread());

$testResult->title = $metadata->title ?? $test->methodName();
$testResult->title = $metadata->title ?? $this->makeTestTitle($test);

$this->currentKey = $key;
$this->testResults[$key] = $testResult;
}

Expand All @@ -87,13 +95,16 @@ public function updateStatus(TestMethod $test, string $status, ?string $message
$key = $this->getTestKey($test);

if (!isset($this->testResults[$key])) {
if ($this->config->onlyReportTestsWithSuite){
return;
}
$this->startTest($test);
$this->testResults[$key]->execution->setStatus($status);
$this->testResults[$key]->execution->finish();

$this->handleMessage($key, $message);
$this->reporter->addResult($this->testResults[$key]);

return;
}

Expand All @@ -105,7 +116,7 @@ public function updateStatus(TestMethod $test, string $status, ?string $message
}
}

private function handleMessage(string $key, ?string $message): void
protected function handleMessage(string $key, ?string $message): void
{
if ($message) {
$this->testResults[$key]->message = $this->testResults[$key]->message . "\n" . $message . "\n";
Expand All @@ -115,17 +126,21 @@ private function handleMessage(string $key, ?string $message): void
public function completeTest(TestMethod $test): void
{
$key = $this->getTestKey($test);
if (!isset($this->testResults[$key])) {
return;
}
$this->testResults[$key]->execution->finish();

$this->reporter->addResult($this->testResults[$key]);
$this->currentKey = null;
}

private function getTestKey(TestMethod $test): string
protected function getTestKey(TestMethod $test): string
{
return $test->className() . '::' . $test->methodName() . ':' . $test->line();
}

private function createSignature(TestMethod $test, ?array $ids = null, ?array $suites = null, ?array $params = null): string
protected function createSignature(TestMethod $test, ?array $ids = null, ?array $suites = null, ?array $params = null): string
{
$finalSuites = [];
if ($suites) {
Expand All @@ -140,7 +155,7 @@ private function createSignature(TestMethod $test, ?array $ids = null, ?array $s
return Signature::generateSignature($ids, $finalSuites, $params);
}

private function getThread(): string
protected function getThread(): string
{
return $_ENV['TEST_TOKEN'] ?? "default";
}
Expand Down Expand Up @@ -193,4 +208,21 @@ public function addAttachment(mixed $input): void
);
}
}

protected function makeTestTitle(TestMethod $test): string
{
$method = $test->methodName();
if (!$this->config->formatTitleFromMethodName){
return $method;
}
if (str_starts_with($method, 'test')){
$method = substr($method, 4);
}
$words = array_map(
fn(string $word) => mb_convert_case($word, MB_CASE_TITLE, 'UTF-8'),
preg_split('/(?=\p{Lu})/u', $method, -1, PREG_SPLIT_NO_EMPTY),
);

return implode(' ', $words);
}
}