Search code examples
phpphpunit

"PHPUnit test explorer" VS Code extension giving "session_start(): Session cannot be started after headers have already been sent" error


I am new to PHP unit testing using "PHPUnit test explorer" VS Code extension.

I am getting below error while running php unit test:

session_start(): Session cannot be started after headers have already been sent

Error stacktrace:

DbconTest
  ❌ testAdd 6 ms
     ┐ 
     ├ session_start(): Session cannot be started after headers have already been sent
     │ 
     │ D:\AJ\xampp\htdocs\somename\dbcon.php:28
     │ D:\AJ\xampp\htdocs\somename\dbcon.php:13
     │ D:\AJ\xampp\htdocs\somename\tests\DbconTest.php:11
     │ D:\AJ\xampp\htdocs\somename\vendor\phpunit\phpunit\phpunit:98
     ┴ 

Below is my code:

DbconTest.php =>

<?php

use PHPUnit\Framework\TestCase;

require_once __DIR__ . 'dbcon.php';

class DbconTest extends TestCase
{
    public function testAdd()
    {
        $db_con = new Dbcon();
        $result = $db_con->add(1, 2);
        $this->assertEquals(3, $result);
    }

}
?>

dbcon.php =>

<?php
include_once dirname(__DIR__).'config.php';

class Dbcon {
    public $con;
    private $valid_data_types;

    public function add($a, $b) {
        return $a + $b;
    }

    function __construct() {
        $this->create_connection();

        $this->valid_data_types = [
            'integer' => 'i',
            'float'   => 'd',
            'double'  => 'd',
            'blob'    => 'b',
            'string'  => 's',
            'NULL'    => 's',
        ];
    }

    function create_connection() {
        ob_start();
        if (! isset($_SESSION)) {
            session_start();
        }
        $this->con = mysqli_connect(HOST, USER, PASS) or die(mysqli_connect_error());
        mysqli_select_db($this->con, DB_NAME) or die(mysqli_error($this->con));
    }
}
?>

Please help

Thanks in advance :)


Solution

  • To understand where exactly the unwanted sending of headers occurred, you can write code:

     function create_connection() {
        headers_sent($file, $line);
        echo "$file: $line";
        # Most likely it will be vendor/phpunit/phpunit/src/Util/Printer.php: 104
        
    

    To avoid conflicts with this location, you can configure each test to run in isolation from the others via phpunit.xml:

    <phpunit
       ...
       processIsolation="true"
    >
    

    Also note that ob_start() will no longer be needed, and it is better to remove it, or take care of executing ob_end_clean(); after the test is completed. Otherwise, the system will not be able to correctly display the results of the tests and will mark them as Risky