Skip to content

Commit 54e176e

Browse files
Enhance execution time reporting in PHPUnit (#3)
- Added a new extension for execution timing in `phpunit.xml.dist`. - Updated `ExecutionTimeReportPrinter` to include formatted display of execution times in milliseconds and seconds. - Refactored test output assertions to check for new time formatting. - Introduced a helper method to extract specific lines from output for cleaner test code.
1 parent 3bb696f commit 54e176e

File tree

3 files changed

+67
-30
lines changed

3 files changed

+67
-30
lines changed

phpunit.xml.dist

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@
1717
</testsuite>
1818
</testsuites>
1919

20+
<extensions>
21+
<bootstrap class="Phauthentic\PHPUnit\ExecutionTiming\ExecutionTimeExtension">
22+
<parameter name="topN" value="10"/>
23+
<parameter name="showIndividualTimings" value="false"/>
24+
<parameter name="warningThreshold" value="1.0"/>
25+
<parameter name="dangerThreshold" value="5.0"/>
26+
</bootstrap>
27+
</extensions>
28+
2029
<source>
2130
<include>
2231
<directory suffix=".php">src</directory>

src/ExecutionTimingExtension/ExecutionTimeReportPrinter.php

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ private function printTestLines(array $topTests): void
8787

8888
/**
8989
* @param array<int, array{name: string, time: float}> $topTests
90-
* @return array{rank: int, name: int}
90+
* @return array{rank: int, name: int, timeMs: int, timeSec: int}
9191
*/
9292
private function calculateColumnWidths(array $topTests): array
9393
{
@@ -100,35 +100,53 @@ private function calculateColumnWidths(array $topTests): array
100100
)
101101
);
102102

103+
$maxTimeMsWidth = max(
104+
array_map(
105+
static fn(array $test): int => strlen(sprintf('%.2f ms', round($test['time'] * 1000, 2))),
106+
$topTests
107+
)
108+
);
109+
110+
$maxTimeSecWidth = max(
111+
array_map(
112+
static fn(array $test): int => strlen(sprintf('(%.3f s)', round($test['time'], 3))),
113+
$topTests
114+
)
115+
);
116+
103117
return [
104118
'rank' => $maxRankWidth,
105119
'name' => $maxNameWidth,
120+
'timeMs' => $maxTimeMsWidth,
121+
'timeSec' => $maxTimeSecWidth,
106122
];
107123
}
108124

109125
/**
110126
* @param array{name: string, time: float} $test
111-
* @param array{rank: int, name: int} $columnWidths
127+
* @param array{rank: int, name: int, timeMs: int, timeSec: int} $columnWidths
112128
*/
113129
private function printTestLine(array $test, int $rank, array $columnWidths): void
114130
{
115131
$timeMs = round($test['time'] * 1000, 2);
116132
$timeSec = round($test['time'], 3);
117133
$rankFormatted = $this->formatRank($rank, $columnWidths['rank']);
118134
$nameFormatted = $this->formatTestName($test['name'], $columnWidths['name']);
135+
$timeMsFormatted = $this->formatTimeMs($timeMs, $columnWidths['timeMs']);
136+
$timeSecFormatted = $this->formatTimeSec($timeSec, $columnWidths['timeSec']);
119137

120138
$color = $this->determineColor($test['time']);
121139

122140
$nameDisplay = $color !== '' ? Color::colorize($color, $nameFormatted) : $nameFormatted;
123-
$timeMsDisplay = $color !== '' ? Color::colorize($color, sprintf('%.2f ms', $timeMs)) : sprintf('%.2f ms', $timeMs);
124-
$timeSecDisplay = $color !== '' ? Color::colorize($color, sprintf('(%.3f s)', $timeSec)) : sprintf('(%.3f s)', $timeSec);
141+
$timeMsDisplay = $color !== '' ? Color::colorize($color, $timeMsFormatted) : $timeMsFormatted;
142+
$timeSecDisplay = $color !== '' ? Color::colorize($color, $timeSecFormatted) : $timeSecFormatted;
125143

126144
printf(
127-
" %s. %s : %s %s" . PHP_EOL,
145+
" %s. ⏱ %s %s %s" . PHP_EOL,
128146
$rankFormatted,
129-
$nameDisplay,
130147
$timeMsDisplay,
131-
$timeSecDisplay
148+
$timeSecDisplay,
149+
$nameDisplay
132150
);
133151
}
134152

@@ -159,4 +177,14 @@ private function formatTestName(string $name, int $width): string
159177
{
160178
return str_pad($name, $width, ' ');
161179
}
180+
181+
private function formatTimeMs(float $timeMs, int $width): string
182+
{
183+
return str_pad(sprintf('%.2f ms', $timeMs), $width, ' ', STR_PAD_LEFT);
184+
}
185+
186+
private function formatTimeSec(float $timeSec, int $width): string
187+
{
188+
return str_pad(sprintf('(%.3f s)', $timeSec), $width, ' ', STR_PAD_LEFT);
189+
}
162190
}

tests/Unit/ExecutionTimeReportPrinterTest.php

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,12 @@ public function testPrintAlignsColumns(): void
126126
$firstLine = $testLines[0];
127127
$secondLine = $testLines[1];
128128

129-
$firstColonPos = strpos($firstLine, ':');
130-
$secondColonPos = strpos($secondLine, ':');
129+
$firstClockPos = strpos($firstLine, '');
130+
$secondClockPos = strpos($secondLine, '');
131131

132-
$this->assertNotFalse($firstColonPos);
133-
$this->assertNotFalse($secondColonPos);
134-
$this->assertEquals($firstColonPos, $secondColonPos, 'Columns should be aligned');
132+
$this->assertNotFalse($firstClockPos);
133+
$this->assertNotFalse($secondClockPos);
134+
$this->assertEquals($firstClockPos, $secondClockPos, 'Columns should be aligned');
135135
}
136136
}
137137

@@ -220,22 +220,16 @@ public function testPrintColorsCorrectlyWithMultipleThresholds(): void
220220
$output = ob_get_clean() ?: '';
221221

222222
// FastTest should not be colored
223-
$fastTestPos = strpos($output, 'FastTest');
224-
$this->assertNotFalse($fastTestPos);
225-
$fastTestLine = substr($output, $fastTestPos, 100);
223+
$fastTestLine = $this->extractLineContaining($output, 'FastTest');
226224
$this->assertStringNotContainsString("\x1b[", $fastTestLine);
227225

228226
// WarningTest should be yellow
229-
$warningTestPos = strpos($output, 'WarningTest');
230-
$this->assertNotFalse($warningTestPos);
231-
$warningTestLine = substr($output, $warningTestPos, 200);
227+
$warningTestLine = $this->extractLineContaining($output, 'WarningTest');
232228
$this->assertStringContainsString("\x1b[33m", $warningTestLine);
233229
$this->assertStringNotContainsString("\x1b[31m", $warningTestLine);
234230

235231
// DangerTest should be red
236-
$dangerTestPos = strpos($output, 'DangerTest');
237-
$this->assertNotFalse($dangerTestPos);
238-
$dangerTestLine = substr($output, $dangerTestPos, 200);
232+
$dangerTestLine = $this->extractLineContaining($output, 'DangerTest');
239233
$this->assertStringContainsString("\x1b[31m", $dangerTestLine);
240234
}
241235

@@ -254,21 +248,27 @@ public function testPrintRespectsThresholdConfiguration(): void
254248
$output = ob_get_clean() ?: '';
255249

256250
// Test1 (0.8s) should not be colored
257-
$test1Pos = strpos($output, 'Test1');
258-
$this->assertNotFalse($test1Pos);
259-
$test1Line = substr($output, $test1Pos, 100);
251+
$test1Line = $this->extractLineContaining($output, 'Test1');
260252
$this->assertStringNotContainsString("\x1b[", $test1Line);
261253

262254
// Test2 (1.2s) should be yellow (>= 1.0 but < 2.0)
263-
$test2Pos = strpos($output, 'Test2');
264-
$this->assertNotFalse($test2Pos);
265-
$test2Line = substr($output, $test2Pos, 200);
255+
$test2Line = $this->extractLineContaining($output, 'Test2');
266256
$this->assertStringContainsString("\x1b[33m", $test2Line);
267257

268258
// Test3 (3.0s) should be red (>= 2.0)
269-
$test3Pos = strpos($output, 'Test3');
270-
$this->assertNotFalse($test3Pos);
271-
$test3Line = substr($output, $test3Pos, 200);
259+
$test3Line = $this->extractLineContaining($output, 'Test3');
272260
$this->assertStringContainsString("\x1b[31m", $test3Line);
273261
}
262+
263+
private function extractLineContaining(string $output, string $search): string
264+
{
265+
$lines = explode("\n", $output);
266+
foreach ($lines as $line) {
267+
if (str_contains($line, $search)) {
268+
return $line;
269+
}
270+
}
271+
272+
return '';
273+
}
274274
}

0 commit comments

Comments
 (0)