Welcome to Abdul Malik Ikhsan's Blog

How to Avoid –stderr When Running phpunit for Functional/Integration Testing

Posted in Teknologi, testing by samsonasik on March 3, 2020

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 Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: