From 02acbf38f537507b3291f1cb4797aa8c2dec5302 Mon Sep 17 00:00:00 2001 From: KevinBKozan Date: Thu, 28 Jun 2018 13:59:08 -0500 Subject: [PATCH 1/3] MQE-1087: Test _after hook does not run if test fails with exception - TestContextExtension now handles error events, and runs _after block if the test errored out. --- .../Extension/TestContextExtension.php | 66 +++++++++++++++---- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php b/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php index b51ebda0f..708e27726 100644 --- a/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php +++ b/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php @@ -23,7 +23,8 @@ class TestContextExtension extends \Codeception\Extension */ public static $events = [ Events::TEST_FAIL => 'testFail', - Events::STEP_AFTER => 'afterStep' + Events::STEP_AFTER => 'afterStep', + Events::TEST_END => 'testError' ]; /** @@ -38,22 +39,61 @@ public function testFail(\Codeception\Event\FailEvent $e) // Do not attempt to run _after if failure was in the _after block // Try to run _after but catch exceptions to prevent them from overwriting original failure. if ($context != TestContextExtension::TEST_PHASE_AFTER) { - try { - $actorClass = $e->getTest()->getMetadata()->getCurrent('actor'); - $I = new $actorClass($cest->getScenario()); - call_user_func(\Closure::bind( - function () use ($cest, $I) { - $cest->executeHook($I, 'after'); - }, - null, - $cest - )); - } catch (\Exception $e) { - // Do not rethrow Exception + $this->runAfterBlock($e, $cest); + } + } + + /** + * Codeception event listener function, triggered on test error. + * @param \Codeception\Event\TestEvent $e + * @return void + */ + public function testError(\Codeception\Event\TestEvent $e) + { + $cest = $e->getTest(); + + //Access private TestResultObject to find stack and if there are any errors (as opposed to failures) + $testResultObject = call_user_func(\Closure::bind( + function () use ($cest) { + return $cest->getTestResultObject(); + }, + $cest + )); + $errors = $testResultObject->errors(); + if (!empty($errors)) { + $stack = $errors[0]->thrownException()->getSerializableTrace(); + $context = $this->extractContext($stack, $cest->getTestMethod()); + // Do not attempt to run _after if failure was in the _after block + // Try to run _after but catch exceptions to prevent them from overwriting original failure. + if ($context != TestContextExtension::TEST_PHASE_AFTER) { + $this->runAfterBlock($e, $cest); } } } + /** + * Runs cest's after block, if necessary. + * @param Symfony\Component\EventDispatcher\Event $e + * @param \Codeception\TestInterface $cest + * @return void + */ + private function runAfterBlock($e, $cest) + { + try { + $actorClass = $e->getTest()->getMetadata()->getCurrent('actor'); + $I = new $actorClass($cest->getScenario()); + call_user_func(\Closure::bind( + function () use ($cest, $I) { + $cest->executeHook($I, 'after'); + }, + null, + $cest + )); + } catch (\Exception $e) { + // Do not rethrow Exception + } + } + /** * Extracts hook method from trace, looking specifically for the cest class given. * @param array $trace From c8132f71c18f075784baab4918fb0e7532a7deb8 Mon Sep 17 00:00:00 2001 From: KevinBKozan Date: Thu, 28 Jun 2018 14:22:14 -0500 Subject: [PATCH 2/3] MQE-1087: Test _after hook does not run if test fails with exception - static check fix --- .../Extension/TestContextExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php b/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php index 708e27726..34552550b 100644 --- a/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php +++ b/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php @@ -74,7 +74,7 @@ function () use ($cest) { /** * Runs cest's after block, if necessary. * @param Symfony\Component\EventDispatcher\Event $e - * @param \Codeception\TestInterface $cest + * @param \Codeception\TestInterface $cest * @return void */ private function runAfterBlock($e, $cest) From 7ea11f2782c9ef560f49c01eb6cf72e278f379a2 Mon Sep 17 00:00:00 2001 From: KevinBKozan Date: Thu, 5 Jul 2018 15:12:32 -0500 Subject: [PATCH 3/3] MQE-1087: Test _after hook does not run if test fails with exception - getSerializableTrace -> getTrace --- .../Extension/TestContextExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php b/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php index 34552550b..c0bf78f19 100644 --- a/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php +++ b/src/Magento/FunctionalTestingFramework/Extension/TestContextExtension.php @@ -61,7 +61,7 @@ function () use ($cest) { )); $errors = $testResultObject->errors(); if (!empty($errors)) { - $stack = $errors[0]->thrownException()->getSerializableTrace(); + $stack = $errors[0]->thrownException()->getTrace(); $context = $this->extractContext($stack, $cest->getTestMethod()); // Do not attempt to run _after if failure was in the _after block // Try to run _after but catch exceptions to prevent them from overwriting original failure.