Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've been working very hard to get PHPUnit to play nice with WordPress (with the help of this, this, this, this, and this), and I think I've gotten pretty close. The code I run directly before my tests looks like this (basically lifted verbatim from this article):

( PHP_SAPI === 'cli' ) || die( 'Access Denied' );

define( 'PHPUNIT_DB_PREFIX', 'phpunit_' );

global $wp_rewrite, $wpdb;

define( 'WP_MEMORY_LIMIT', '100M' );

require_once( dirname( __FILE__ ) . '/../../../../wp-load.php' );
require_once( ABSPATH . 'wp-admin/includes/admin.php' );

wp_set_current_user( 1 );

Seems to work fine, except that functions return different things based on where they are in the file. For instance, outside of a test class, shortcode_exists returns true, whereas within a test case the exact same shortcode_exists statement returns false. What am I doing wrong?

Here are the contents of the entire test file:

[The file has changed since I originally posted this...]

EDIT: Ok, so I've followed J.D.'s tutorial as closely as I could. It feels really close. I'm now getting this error:

PHPUnit_Framework_Error_Warning : copy(data/not-gettexted-0.php): failed to open stream: No such file or directory
#0 [internal function]: PHPUnit_Util_ErrorHandler::handleError(2, 'copy(data/not-g...', '/Applications/w...', 41, Array)
#1 /Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/wordpress-dev/trunk/tools/i18n/t/NotGettextedTest.php(41): copy('data/not-gettex...', 'data/not-gettex...')
#2 [internal function]: NotGettextedTest->test_replace()
#3 phar:///Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/phpunit-lts.phar/phpunit/Framework/TestCase.php(988): ReflectionMethod->invokeArgs(Object(NotGettextedTest), Array)
#4 phar:///Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/phpunit-lts.phar/phpunit/Framework/TestCase.php(838): PHPUnit_Framework_TestCase->runTest()
#5 phar:///Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/phpunit-lts.phar/phpunit/Framework/TestResult.php(648): PHPUnit_Framework_TestCase->runBare()
#6 phar:///Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/phpunit-lts.phar/phpunit/Framework/TestCase.php(783): PHPUnit_Framework_TestResult->run(Object(NotGettextedTest))
#7 phar:///Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/phpunit-lts.phar/phpunit/Framework/TestSuite.php(779): PHPUnit_Framework_TestCase->run(Object(PHPUnit_Framework_TestResult))
#8 phar:///Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/phpunit-lts.phar/phpunit/Framework/TestSuite.php(749): PHPUnit_Framework_TestSuite->runTest(Object(NotGettextedTest), Object(PHPUnit_Framework_TestResult))
#9 phar:///Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/phpunit-lts.phar/phpunit/Framework/TestSuite.php(709): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult), false, Array, Array, false)
#10 phar:///Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/phpunit-lts.phar/phpunit/TextUI/TestRunner.php(350): PHPUnit_Framework_TestSuite->run(Object(PHPUnit_Framework_TestResult), false, Array, Array, false)
#11 phar:///Applications/wordpress-3.8.3-0/apps/wordpress/htdocs/wp-content/plugins/hf-accountability/tests/phpunit-lts.phar/phpunit/TextUI/Command.php(176): PHPUnit_TextUI_TestRunner->doRun(Object(PHPUnit_Framework_TestSuite), Array)
#12 /private/var/folders/r5/0w5bp7b13pndfymz_pgf_zz00000gn/T/ide-phpunit.php(268): PHPUnit_TextUI_Command->run(Array, true)
#13 /private/var/folders/r5/0w5bp7b13pndfymz_pgf_zz00000gn/T/ide-phpunit.php(506): IDE_Base_PHPUnit_TextUI_Command::main()
#14 {main}

Any idea how I can fix that? In the mean time, I'm going to keep checking all the file paths I defined in the several config files.

EDIT EDIT: That last error was resolved by modifying the PhpStorm configuration I was using. You have to both set it to "Use alternative configuration file" and set the test scope to "Defined in the configuration file."

share|improve this question

1 Answer 1

up vote 2 down vote accepted

The reason this is happening is actually not because of anything in the code you've posted, per se, but because of how you have PHPUnit configured. The shortcode callbacks are stored in a global ($shortcode_tags). When you load WP, the shortcode is registered and added to the global. You call shortcode_exists(), it checks $shortcode_tags, and returns true. Then PHPUnit starts running your tests. And it clears out the global variable scope. So, when your test is run, $shortcode_tags no longer exists, so shortcode_exists() reports that your shortcode isn't registered. (PHPUnit will then restore the global scope to what it was before the test, so that tests don't affect the global variables. Running shortcode_exists() after the tests are finished would report true.)

PHPUnit does have the backupGlobals setting, and setting it to false will prevent PHPUnit from touching the global scope. And that should fix your issues. However....

A more excellent way

As the author of this tutorial, I would like to recommend that you set up your tests more like I show there. The reason being that you won't have to write all this bootstrap to get PHPUnit to play with WordPress. You should instead just use WordPress's PHPUnit bootstrap, which, obviously, is already engineered to play nice with WordPress. :-)

share|improve this answer
Thanks for the explanation! +1. I had indeed read through most of your tutorial, but it certainly does look like I'll be examining it more thoroughly now. Thanks for being willing to share your expertise! (BTW, I did attempt to set $backupGlobals equal to false... Hmmm. Guess something wasn't working quite right there.) –  Nathan Arthur Jun 9 at 20:44
You're welcome. backupGlobals needs to be set in the XML config, or as an annotation. –  J.D. Jun 9 at 20:54
Thanks again for the tutorial! It seems to be working—almost, anyway. Could you possibly take a quick glance at the error I'm getting now? –  Nathan Arthur Jun 9 at 21:43
Perhaps it's because I'm using PhpStorm? I'm not convinced it's using my phpunit.xml file even though I've told it to. It appears to be running a lot more tests than my tests-general.php file. –  Nathan Arthur Jun 9 at 21:53
Yes! Figured it out. You have to both set it to "Use alternative configuration file" and set the test scope to "Defined in the configuration file." It appears to be working perfectly now! And accepting... –  Nathan Arthur Jun 9 at 21:55

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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