4

I have been researching this issue for days and although many people ask this question I never found a clear and concise answer.

I am running:

  • PHP Unit: Version 3.7.21
  • WordPress: Version 3.5.1
  • OS: Ubuntu 11.10
  • MySQL: Version 5.1.69-0ubuntu0.11.10.1
  • PHP: Version 5.3.6-13ubuntu3.10

Long story short, I have the basic wordPress core downloaded into a directory on my computer. I have successfully downloaded and installed pear and phpunit. I tested phpunit by writing basic tests on simple php files which worked fine. My issue is when I run phpunit on a wordpress site (which I have not changed the core WP files of).

I get the error:

"PHP Fatal error: Call to a member function main() on a non-member object in /< root_directory>/functions.php on line 779".

This error corresponds to this code-segment:

function wp( $query_vars = '' ) {
    global $wp, $wp_query, $wp_the_query;
    $wp->main( $query_vars ); // Line 779

    if ( !isset($wp_the_query) )
        $wp_the_query = $wp_query;
}

After some intense internet crawling I found many people had errors on this exact line so I know there is some general thing like an environment setting or our setup process that gave us all this error.

Some solutions I have read and tried that did not work for me:

  • Change the required file in your "index.php" file.
  • Place a require of "load.php" above the head in your "index.php" file.
  • Re-install WordPress
  • Change boot-strap and phpunit environments.

I have been a web-developer for 5 years but I have never used WordPress for one of my clients before. Once I can get this set up writing the unit tests will be easy; but I have no idea what is causing this issue. Any links to guides/tutorials or clear explanations would be greatly appreciated. Thank you for your time.

--EDIT-- The test file I am running is:

<?php   
//include PHPUnit
require_once('PHPUnit/Autoload.php');
//include the code to be tested
require_once('../index.php');

// extend the PHPUnit class
class StackTest extends PHPUnit_Framework_TestCase {

    public function testOne(){
        $this->assertTrue(TRUE);
        $this->assertEquals(2,2);
        $this->assertTrue(1<3);
    }
}
?>

I didn't use any WordPress specific function tests; I just ran basic tests that work when I don't access the homepage of my WordPress site and fail when I do.

Also another note; I properly set up my config file and my database. The site works perfectly fine, it is just the PHPUnit tests are unable to successfully run the websites files.

  • 1
    What does your test look like? The issue here is that the wp() function is requiring certain global variables which, apparently, haven't been set up yet. If I can see your setup/teardown/test methods I might be able to help. – EAMann Jun 14 '13 at 20:37
  • I have not tried running WP specific tests yet; I just had a test file that tried getting access to the "index.php" of my WordPress site. Even if it doesn't have a WP specific command, I can post it. – Devon Bernard Jun 14 '13 at 20:38
  • 1
    I managed to get up and running with tests thanks to WP CLI, here's a tutorial : wp-cli.org/blog/plugin-unit-tests.html – paul Jun 14 '13 at 21:32
3

Unit tests for WordPress are a tricky thing. If you need to test the code with a live database, etc. I would suggest using the official WordPress test suite. I've gotten unit tests running for a plugin using that method before, but it wasn't pretty, and was fairly unreliable. If you need to do it that way, though, I personally wouldn't think of doing it with anything but the official test suite.

There's tons of information on the official repository on the core make blog. In your test suite's bootstrap file you need to set up any options that you need to override. Normally, that's going to be active plugins (so you can test your plugin):

$GLOBALS['wp_tests_options'] = array(
  'active_plugins' => array( 'plugin-folder/plugin-file.php' ), // Relative to WP Plugin directory
);

After that, you need to include the includes/bootstrap.php file from the core test suite. Once that's done, your tests ought to run as "expected".

In my experience, however, those kinds of tests never run as expected, since the database and all of the WordPress code introduce an insane amount of hidden dependencies and state to your tests. Because of that, I prefer to just mock the WordPress api and run my tests without all those dependencies and all that state.

To do that, I use WP_Mock. It lets you simulate the WordPress environment with fine-grained control. For example, if you have a function that needs to add a filter to 'the_content' and then call the_content(), the following code for WP_Mock lets you test that:

WP_Mock::expectFilterAdded( 'the_content', 'some_callback_you_expect', 10, 2 );
WP_Mock::wpFunction( 'the_content', array(
  'times' => 1,
  'args'  => array(),
) );
your_function();

If the expectations set forth in WP_Mock are not met, it throws an exception, causing the test to fail.

  • Thank you John for your explanation. I will try and implement your tutorial sometime soon; and I will make sure to accept it when I get the tests running correctly. – Devon Bernard Jun 15 '13 at 0:16
  • By following the Official Wordpress Test Suite guide you posted, and the guide I found here gist.github.com/xentek/3482677 . I was able to successfully get everything up and running. Thanks John. – Devon Bernard Jun 17 '13 at 16:25

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.