How to Avoid –stderr When Running phpunit for Functional/Integration Testing
When you do a Functional/Integration test with session and/or header relation. It will force you to use --stderr
when running phpunit, or it will got error, eg: you’re testing that on logout when session exists as user, page will be redirected to login page with status code 302, and it got the following error:
$ vendor/bin/phpunit test/Integration/LogoutPageTest.php PHPUnit 8.5.2 by Sebastian Bergmann and contributors. Logout Page (AppTest\Integration\LogoutPage) ✘ Open logout page as auser redirect to login page ┐ ├ Failed asserting that 500 matches expected 302. │ ╵ /Users/samsonasik/www/mezzio-authentication-with-authorization/test/Integration/LogoutPageTest.php:36 ┴ Time: 155 ms, Memory: 10.00 MB FAILURES! Tests: 1, Assertions: 1, Failures: 1.
You can use --stderr
option on running it:
$ vendor/bin/phpunit test/Integration/LogoutPageTest.php --stderr PHPUnit 8.5.2 by Sebastian Bergmann and contributors. Logout Page (AppTest\Integration\LogoutPage) √ Open logout page as auser redirect to login page Time: 150 ms, Memory: 8.00 MB OK (1 test, 2 assertions)
or define stderr=true
in phpunit.xml
configuration:
<?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true" testdox="true" stderr="true"> <!-- testsuites, filter, etc config --> </phpunit>
Marking all test to be using stderr
is a workaround, as not all tests actually require that, eg: unit test doesn’t need that. To avoid it, we can define @runTestsInSeparateProcesses
and @preserveGlobalState disabled
in the controller class that require that, so, the test class will be like the following:
<?php declare(strict_types=1); namespace AppTest\Integration; use Laminas\Diactoros\ServerRequest; use Laminas\Diactoros\Uri; use Mezzio\Authentication\UserInterface; use PHPUnit\Framework\TestCase; /** * @runTestsInSeparateProcesses * @preserveGlobalState disabled */ class LogoutPageTest extends TestCase { private $app; protected function setUp(): void { $this->app = AppFactory::create(); } public function testOpenLogoutPageAsAuserRedirectToLoginPage() { $sessionData = [ 'username' => 'samsonasik', 'roles' => [ 'user', ], ]; $_SESSION[UserInterface::class] = $sessionData; $uri = new Uri('/logout'); $serverRequest = new ServerRequest([], [], $uri); $response = $this->app->handle($serverRequest); $this->assertEquals(302, $response->getStatusCode()); $this->assertEquals('/login', $response->getHeaderLine('Location')); } }
That’s it!
leave a comment