Codeception / robo-paracept

Robo tasks for Codeception tests parallel execution
MIT License
57 stars 59 forks source link

Execution time on the merged html report is incorrect (0s) #119

Closed ccsuperstar closed 1 year ago

ccsuperstar commented 1 year ago

On merged report.html, execution time = 0s

Capture d’écran 2022-11-15 à 14 16 10

On each html report, we have execution time formatted in "minutes:seconds.milliseconds" and not as attended (103.29s) for example (since Codeception 5 I think)

Capture d’écran 2022-11-15 à 14 16 16

Maybe related to $timeTaken = $this->timer->stop()->asString(); in HtmlReporter

public function asString(): string
    {
        $result = '';

        if ($this->hours > 0) {
            $result = sprintf('%02d', $this->hours) . ':';
        }

        $result .= sprintf('%02d', $this->minutes) . ':';
        $result .= sprintf('%02d', $this->seconds);

        if ($this->milliseconds > 0) {
            $result .= '.' . sprintf('%03d', $this->milliseconds);
        }

        return $result;
    }

I have modified countExecutionTime() method, but it is to test that it works, not the solution to apply, I am well aware of it

private function countExecutionTime(DOMDocument $dstFile): void
    {
        $xpathHeadline = "//h1[text() = 'Codeception Results ']";
        $nodeList = (new DOMXPath($dstFile))
            ->query($xpathHeadline);
        if (!$nodeList) {
            throw XPathExpressionException::malformedXPath($xpathHeadline);
        }

        $pregResult = preg_match(
            '#^Codeception Results .* \((?<timesum>\d+\:\d+\.\d+|\d+\.\d+s)\)$#',
            $nodeList[0]->nodeValue,
            $matches
        );

        if (false === $pregResult) {
            throw new RuntimeException('Regexpression is malformed');
        }

        if (0 === $pregResult) {
            return;
        }

        if (str_contains($matches['timesum'], 's')) {
            $matches['timesum'] = str_replace('s', '', $matches['timesum']);
        } else {
            sscanf($matches['timesum'], "%d:%d.%d", $minutes, $seconds, $milliseconds);
            $matches['timesum'] = isset($milliseconds)
                ? ($minutes * 60 + $seconds) . '.' . $milliseconds
                : $minutes * 60 + $seconds;
        }

        if (!$this->maxTime) {
            $this->executionTimeSum += (float)$matches['timesum'];
        } else {
            $this->executionTime[] = (float)$matches['timesum'];
        }
    }

Moreover, in a parallel run context, each run has an execution time. The final merge of the reports aggregates each of the reports However, in my opinion, the execution time of the final merge should be the execution time of the longest run and not the sum of the execution times of each run.

Is it possible to stock all reports execution time in array and make finally $this->executionTimeSum = max($executionTimeArray);

My proposal here #120