Development's tests are a mandatory step for guarantee the validity and viability of the code. Sometimes, the tests writing are not trivial. For instance, a method can do an HTTP redirection :

class MyClass
{
    /**
     * Method to redirect to https://vfac.fr
    **/
    public function doRedirection()
    {
        header('Location: https://vfac.fr');
        return true;
    }
}

With this type of method, I can test with PHPUnit with the following code :

/**
 * @test
**/
public function testDoRedirection()
{
    $MyClass = new MyClass();
    $MyClass->doRedirection();

    $this->assertContains(
        'Location: https://vfac.fr', xdebug_get_headers()
    );
}

Problem during tests:

There was 1 error:

1) MyClass::testDoRedirection
Cannot modify header information - headers already sent by (output started at /app/vendor/phpunit/phpunit/src/Util/Printer.php:110)

To fix this problem, we must add a simple annotation to our code test : @runInSeparateProcess

Indicates that a test should be run in a separate PHP process.

The test become:

/**
 * @test
 * @runInSeparateProcess
**/
public function testDoRedirection()
{
    $MyClass = new MyClass();
    $MyClass->doRedirection();

    $this->assertContains(
        'Location: https://vfac.fr', xdebug_get_headers()
    );
}

Be careful, a lot of developers add an exit(); after an 'header()' call. This is a bad approach, because scripts execution are totaly stopped, including PHPUnit for the associated test ! The consequence of the presence of this instruction is you will be not alert if the test failed and the code coverage will could not be generated for this test.

Next Post Previous Post