diff --git a/en/appendices/5-1-upgrade-guide.rst b/en/appendices/5-1-upgrade-guide.rst index 647b16c933..34a8216798 100644 --- a/en/appendices/5-1-upgrade-guide.rst +++ b/en/appendices/5-1-upgrade-guide.rst @@ -41,6 +41,12 @@ Http events when requests are sent. You can use these events to perform logging, caching or collect telemetry. +TestSuite +--------- + +- ``LogTestTrait`` was added. This new trait makes it easy to capture logs in + your tests and make assertions on the presence or absence of log messages. + Validation ---------- diff --git a/en/core-libraries/logging.rst b/en/core-libraries/logging.rst index 188005ca4a..99430519da 100644 --- a/en/core-libraries/logging.rst +++ b/en/core-libraries/logging.rst @@ -295,7 +295,7 @@ following keys: used. See ``syslog`` documentation for more options Creating Log Engines -===================== +==================== Log engines can be part of your application, or part of plugins. If for example you had a database logger called @@ -347,7 +347,7 @@ interface as it only requires you to implement the ``log()`` method. .. _logging-formatters: Logging Formatters ------------------- +================== Logging formatters allow you to control how log messages are formatted independent of the storage engine. Each core provided logging engine comes with @@ -378,6 +378,55 @@ To implement your own logging formatter you need to extend method you need to implement is ``format($level, $message, $context)`` which is responsible for formatting log messages. +.. _log-testing: + +Testing Logs +============ + +To test logging, add ``Cake\TestSuite\LogTestTrait`` to your test case. The +``LogTestTrait`` uses PHPUnit hooks to attach log engines that intercept the log +messages your application is making. Once you have captured logs you can perform +assertions on log messages your application is emitting. For example:: + + namespace App\Test\TestCase\Controller; + + use Cake\TestSuite\LogTestTrait; + use Cake\TestSuite\TestCase; + + class UsersControllerTest extends TestCase + { + use LogTestTrait; + + public function setUp(): void + { + parent::setUp(); + $this->setupLog([ + 'error' => ['scopes' => ['app.security']] + ]); + } + + public function testResetPassword() + { + $this->post('/users/resetpassword', ['email' => 'bob@example.com']); + $this->assertLogMessageContains('info', 'bob@example.com reset password', 'app.security'); + } + } + +You use ``setupLog()`` to define the log messages you wish to capture and +perform assertions on. After logs have been emitted you can make assertions on +the contents of logs, or the absence of them: + +* ``assertLogMessage(string $level, string $expectedMessage, ?string $scope + = null, string $failMsg = '')`` Assert that a log message was found. +* ``assertLogMessageContains(string $level, string $expectedMessage, ?string + $scope = null, string $failMsg = '')`` Assert that a log message contains the + substring. +* ``assertLogAbsent(string $level, ?string $failMsg = '')`` Assert that no log + messages of the given level were captured. + +The ``LogTestTrait`` will automatically clean up any loggers that were +configured. + Log API ======= diff --git a/en/development/testing.rst b/en/development/testing.rst index 8631555d03..22ca1ffac6 100644 --- a/en/development/testing.rst +++ b/en/development/testing.rst @@ -1885,6 +1885,11 @@ Testing Email See :ref:`email-testing` for information on testing email. +Testing Logging +=============== + +See :ref:`log-testing` for information on testing log messages. + Creating Test Suites ====================