How can I properly set up dependencies in automated testing?

I’m trying to set up automated tests for my WP- and BP-dependent plugin, as described in:

  • https://codex.buddypress.org/developer/automated-testing/
  • https://make.wordpress.org/core/handbook/automated-testing/
  • https://codex.buddypress.org/developer/automated-testing/writing-automated-tests-for-buddypress-dependent-plugins/

And so I’ve initialized a testing framework by:

  • running wp scaffold plugin-tests
  • adding lines to check out BP from svn to bin/install-wp-tests.sh
  • loading BP with the loader described in the above manual page

But I can’t quite seem to load the stack properly. Either it complains that BP functions are undefined, or that WP functions are undefined, or that my plugin’s functions are undefined. Here’s my install script, and here’s my bootstrap file. What I am doing wrong? Here’s a paste of the bootstrap file, for convenience:

<?php

// set a flag so that certain functions know we're running tests. 
define( 'RUNNING_TESTS', TRUE ); 

$wp_tests_dir = getenv( 'WP_TESTS_DIR' );
if ( ! $wp_tests_dir ) $wp_tests_dir="/tmp/wordpress-tests-lib";
define( 'WP_TESTS_DIR', $wp_tests_dir ); 

$bp_tests_dir = getenv( 'BP_TESTS_DIR' ); 
if ( ! $bp_tests_dir ) $bp_tests_dir="/tmp/buddypress/tests/phpunit";
define( 'BP_TESTS_DIR', $bp_tests_dir ); 

echo 'Done defining stuff! '; 

require_once $wp_tests_dir . '/includes/bootstrap.php';

require_once $wp_tests_dir . '/includes/functions.php';

echo 'Done requiring test dirs! ' ; 

// this is my debugging file, which ensures that tests won't fail 
// if there's a call to `_log()`. 
require dirname( __FILE__ ) . '/debug.php';

function _manually_load_plugin() {
    require BP_TESTS_DIR . '/includes/loader.php';


    // override this class to load mock data
    require dirname( __FILE__ ) . '/class-MockMLAAPI.php'; 

    // don't get the whole plugin now, just a few classes, because 
    // to test them individually we feed them mock data above. 
    require dirname( __FILE__ ) . '/../class-CustomAuthentication.php';

    // Requiring this file gives you access to BP_UnitTestCase
    require $bp_tests_dir . '/includes/testcase.php';

}
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );

1 Answer
1

I think the main problem here is that you are loading WordPress’s bootstrap too early. Changing to this should fix it (I’ve interspersed comments explaining why things are in the order they are in):

// This file contains tests_add_filter(), so we need to load it
// so that we can hook the _manually_load_plugin() function to
// muplugins_loaded. We can't use add_action() because WordPress
// isn't loaded yet, and we can't load it quite yet (see below).
require_once $wp_tests_dir . '/includes/functions.php';

// This function loads the plugin and dependencies. We need to
// define it and hook it to muplugins_loaded before including 
// WordPress's bootstrap, since that will load WordPress. If
// we don't hook this up first, the hook will be fired when
// WordPress is loaded, and adding a hook to this after that
// will have no effect.
function _manually_load_plugin() {

     /* Code in here is probably the same. */
}
tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );

// Now that our function is hooked up, we can load WordPress, and
// the plugin and dependencies will be loaded when the hook gets
// called.
require_once $wp_tests_dir . '/includes/bootstrap.php';

Leave a Comment