0

I'm trying to setup unit tests for a plugin I am developing. I just followed the steps at... https://make.wordpress.org/cli/handbook/plugin-unit-tests/

However, when I run phpunit I get the following...

$ phpunit
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml

Warning: Cannot modify header information - headers already sent by (output started at /private/tmp/wordpress-tests-lib/includes/bootstrap.php:68) in /Users/<USERNAME>/Sites/<MYSITE.COM>/wp-load.php on line 64

I am running...

  • Mac OS 10.12.6
  • PHP v5.6.30
  • PHPUnit 4.8.36
  • MAMP Pro 4.2

The error noted, bootstrap.php:68 which is the start of the program outputting the "Installing..." text from the output noted above. Line 68 reads...

system( WP_PHP_BINARY . ' ' . escapeshellarg( dirname( __FILE__ ) . '/install.php' ) . ' ' . escapeshellarg( $config_file_path ) . ' ' . $multisite );  
1

The error is telling you that the code tried to output a HTTP response header with the header() function after the response body has already begun to be sent. As you noted, line 68 of bootstrap.php is calling that script that outputs Installing.... So after that output has already been sent, you can't send a response header.

The next step to debug this is to find out why a response header is being sent. That isn't supposed to be happening, because here we are running the tests from the command line, we're not actually sending a page to the browser.

So, we need to see where header() is being called. The error tells you that it is in wp-load.php on line 64:

    header( 'Location: ' . $path );

This line itself doesn't tell us much, but we find that it is within a big if ... else statement:

/*
 * If wp-config.php exists in the WordPress root, or if it exists in the root and wp-settings.php
 * doesn't, load wp-config.php. The secondary check for wp-settings.php has the added benefit
 * of avoiding cases where the current directory is a nested installation, e.g. / is WordPress(a)
 * and /blog/ is WordPress(b).
 *
 * If neither set of conditions is true, initiate loading the setup process.
 */
if ( file_exists( ABSPATH . 'wp-config.php') ) {

    /** The config file resides in ABSPATH */
    require_once( ABSPATH . 'wp-config.php' );

} elseif ( @file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! @file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {

    /** The config file resides one level above ABSPATH but is not part of another install */
    require_once( dirname( ABSPATH ) . '/wp-config.php' );

} else {

    // snip

    header( 'Location: ' . $path );

    // snip

}

Essentially what this tells us is that wp-load.php is looking for the wp-config.php file, and isn't finding it. So it is initiating the set-up process, and as part of that it is trying to redirect to the installation page by sending the Location header.

So you apparently have not set up your wp-config.php file correctly.

The wp-config.php file was supposed to be set up by the script you ran though, so this is likely an indicator that something failed. In fact, since we are running the tests here, the wp-tests-config.php file is expected to be used instead. So the next step is figuring out why wp-tests-config.php isn't being loaded. You should be able to find that file in the /tmp/wordpress-tests-lib/ directory.

  • Thank you for the detailed explanation! I tried fully reinstalling the test WordPress install (with bash bin/install-w-tests.sh...) but still had the same issue with no errors that I saw in the output. After checking to see where it was looking for the wp-config.php file I noticed it was looking for it in /tmp/wordpress/wp-config.php so I just created a symlink to the one in wordpress-tests-lib using ln -s /tmp/wordpress-tests-lib/wp-tests-config.php /tmp/wordpress/wp-config.php It is now working although I'm not sure why I needed to manually create the symlink. – Scruffy Paws Jul 27 '17 at 16:57
0

That problem sounds like your code is sending text/characters to the screen, then it sends out a page 'header' (the <head> part of an HTML page). PHP doesn't like that; once you put any characters on the screen, you can't send out page headers (the <head> part).

Sometimes it is as simple as a space character in front of the <?php code. Check for that, or any other text sent out before the page header.

  • Actually, this isn't referring to the <head> of an HTML document but to an HTTP response header. But it's true that space in front of an opening PHP tag (or after a closing one) can cause this. That isn't the case this time, however. – J.D. Jul 27 '17 at 12:49
  • @J.D. You are correct, of course. Wrote a quick response, and my old brain couldn't come up with HTTP Response Header. Thanks. – Rick Hellewell Jul 27 '17 at 17:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.