Skip to content

Commit

Permalink
Prevent unrelated error from being displayed if a scenario step has f…
Browse files Browse the repository at this point in the history
…ailed (#6743)

* Prevent unrelated error from being displayed if a scenario step has failed

* Fix conditional asserts by checking test signature instead of object comparison due to cloning

* Code style

* Add test

* Fix code style for test

---------

Co-authored-by: Craig McMahon <craig.mcmahon@sturents.com>
  • Loading branch information
craig-mcmahon and Craig McMahon committed Mar 5, 2024
1 parent fcfa1d0 commit 066deb0
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 10 deletions.
5 changes: 5 additions & 0 deletions src/Codeception/ResultAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,9 @@ public function popLastFailure(): ?FailEvent
{
return array_pop($this->failures);
}

public function getLastFailure(): ?FailEvent
{
return end($this->failures) ?: null;
}
}
34 changes: 24 additions & 10 deletions src/Codeception/Test/Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,16 +169,7 @@ final public function realRun(ResultAggregator $result): void
$status = self::STATUS_OK;
$eventType = Events::TEST_SUCCESS;

if (method_exists($this, 'getScenario')) {
foreach ($this->getScenario()?->getSteps() ?? [] as $step) {
if ($step->hasFailed()) {
$lastFailure = $result->popLastFailure();
if ($lastFailure !== null) {
throw $lastFailure->getFail();
}
}
}
}
$this->checkConditionalAsserts($result);
} catch (UselessTestException $e) {
$result->addUseless(new FailEvent($this, $e, $time));
$status = self::STATUS_USELESS;
Expand Down Expand Up @@ -302,4 +293,27 @@ private function callTestEndHooks(string $status, float $time, ?Throwable $e): v
}
}
}

private function checkConditionalAsserts(ResultAggregator $result): void
{
if (!method_exists($this, 'getScenario')) {
return;
}

$lastFailure = $result->getLastFailure();
if ($lastFailure === null) {
return;
}

if (Descriptor::getTestSignatureUnique($lastFailure->getTest()) !== Descriptor::getTestSignatureUnique($this)) {
return;
}

foreach ($this->getScenario()?->getSteps() ?? [] as $step) {
if ($step->hasFailed()) {
$result->popLastFailure();
throw $lastFailure->getFail();
}
}
}
}
10 changes: 10 additions & 0 deletions tests/cli/RunCest.php
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,16 @@ public function displaysAllFailedConditionalStepsInOneCest(CliGuy $I)
$I->seeInShellOutput(' 13. $I->canSeeFileFound("nothing") at ' . $filename . ':19');
}

public function scenarioFailuresDontShowForIncorrectTest(CliGuy $I)
{
$I->executeCommand('run scenario ExpectedFailureTest --no-ansi', false);
$I->seeInShellOutput('x ExpectedFailureTest: Expected failure');
$I->seeInShellOutput('+ ExpectedFailureTest: Expected exception');
$I->seeInShellOutput('There was 1 failure:');
$I->seeInShellOutput('1) ExpectedFailureTest: Expected failure');
$I->seeInShellOutput('Tests: 2, Assertions: 2, Failures: 1');
}

#[Group('shuffle')]
public function showSeedNumberOnShuffle(CliGuy $I)
{
Expand Down
20 changes: 20 additions & 0 deletions tests/data/claypit/tests/scenario/ExpectedFailureTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

use Codeception\Test\Unit;
use PHPUnit\Framework\AssertionFailedError;

class ExpectedFailureTest extends Unit
{
protected ScenarioGuy $tester;

public function testExpectedFailure()
{
static::fail(':-(');
}

public function testExpectedException()
{
$this->expectException(AssertionFailedError::class);
$this->tester->assertFalse(true);
}
}

0 comments on commit 066deb0

Please sign in to comment.