Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logging Codeception Errors

I'm pretty new to Codeception and I have come across a problem I cannot figure out. I have about 40 tests in my test suite, and if a test fails, I need to send an email with the reason it failed. For example, if Codeception cannot find an element on the page resulting in a failed test, I need to send an email with just the error, like this:

Failed to verify emailing wish list behaves as expected in ThisClass::thisTest (/home/qauser/codeception_tests///acceptance-mobile/Wishlist/EmailWishlistCest.php) Couldn't see "Success!","//*[@id="wish-list-confirm-popup"]/div/div/div[1]/h4":

I don't want to send the full stack trace, just the actual error. Does anyone know if this is possible?

like image 341
IFISME Avatar asked Jan 20 '17 20:01

IFISME


1 Answers

Codeception exposes a useful collection of events that will come in handy for this use case. Take a look at the Customization: Events section of Codeception's documentation for more information.

I'd recommend intercepting two of the events described on that page:

  • The test.fail event, to aggregate information about each failed test.
  • The test.fail.print event, to process the aggregated data (eg. by sending a summary email) when Codeception has completed the test suite and prints its own summary of the failures to the screen.

To accomplish this, you simply need to build a custom event handler class and register it as an extension in the config file:

# codeception.yml
extensions:
    enabled: [MyCustomEventHandler]

# MyCustomEventHandler.php
<?php
// Note: this was drafted using Codeception 2.0.  Some of the namespaces
// maybe different if you're using a more-recent version of Codeception.
class MyCustomEventHandler extends \Codeception\Platform\Extension
{
    /**
     * @var \Exception[]
     */
    protected $testFailures = [];

    /**
     * Maps Codeception events to method names in this class.
     *
     * Defining an event/method pair in this array essentially subscribes
     * the method as a listener for its corresponding event. 
     *
     * @var array
     */
    public static $events = [
        \Codeception\Events::TEST_FAIL       => 'singleTestJustFailed',
        \Codeception\Events::TEST_FAIL_PRINT => 'allTestFailuresAreBeingDisplayed',
    ];

    /**
     * This method will automatically be invoked by Codeception when a test fails.
     *
     * @param \Codeception\Event\FailEvent $event
     */
    public function singleTestJustFailed(\Codeception\Event\FailEvent $event)
    {
        // Here we build a list of all the failures. They'll be consumed further downstream.
        $this->testFailures[] = $event->getFail();
    }

    /**
     * This method will automatically be invoked by Codeception when it displays
     * a summary of all the test failures at the end of the test suite.
     */
    public function allTestFailuresAreBeingDisplayed()
    {
        // Build the email.
        $emailBody = '';
        foreach ($this->testFailures as $failure) {
            // Methods in scope include: $failure->getMessage(), $failure->getFile(), etc.
            $emailBody .= $failure->getMessage() . "\r\n";
        }

        // Now send the email!
    }
}

Hope this helps!

like image 149
Nate Avatar answered Sep 21 '22 01:09

Nate