Komponententests mit einem benutzerdefinierten WordPress-Plugin mit verschachtelten Plugin-Abhängigkeiten

Lesezeit: 10 Minuten

Benutzer-Avatar
Brieuc

Also habe ich ein benutzerdefiniertes Plugin erstellt und Unit-Tests implementiert.

Bisher war es einfach, eine WooCommerce-Abhängigkeit und eine private Plugin-Abhängigkeit (Iconic Plugin) hinzuzufügen.

Das Problem ist, dass das Iconic-Plugin von WooCommerce abhängig ist. Bei jedem Test denkt es, dass WooCommerce nicht aktiviert ist.

Daher wird es nicht korrekt instanziiert.

Ikonisches Plugin

class Iconic_Private_Plugin() {

    /**
     * Constructor
     */
    public function __construct() {

        public $bar;

        if ( ! Iconic_Private_Core_Helpers::is_plugin_active( 'woocommerce/woocommerce.php' ) && ! Iconic_Private_Core_Helpers::is_plugin_active( 'woocommerce-old/woocommerce.php' ) ) {
            return;
            // It stops right here!!!
        }

        $this->bar = "foo"; // Not assigned!!!

    }

}
global $iconic_private_plugin; // Methods can be accessed from global variable $iconic_private_plugin.
$iconic_private_plugin = new Iconic_Private_Plugin();

Hier also, was ich aus Bash-Befehlen, Bootstrap- und Einheitentests gemacht habe.

install-wp-tests.sh

install_dependencies() {
    WP_SITE_URL="http://localhost:8080"
    WP_PLUGIN_DIR=$(pwd)
    WP_DB_DATA="$WP_PLUGIN_DIR/tests/data/db.sql"

    cd "$WP_CORE_DIR"
    curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
    php wp-cli.phar core config --dbname=$DB_NAME --dbuser=$DB_USER --dbpass=$DB_PASS --dbhost=$DB_HOST --dbprefix=wptests_
    php wp-cli.phar db import $WP_DB_DATA
    php wp-cli.phar search-replace "http://local.wordpress.test" "$WP_SITE_URL"
    php wp-cli.phar theme install twentyseventeen --activate
    php wp-cli.phar plugin install https://downloads.wordpress.org/plugin/woocommerce.${WC_VERSION}.zip --activate
    php wp-cli.phar plugin install https://downloads.wordpress.org/plugin/posts-to-posts.${P2P_VERSION}.zip --activate
    php wp-cli.phar plugin install $WP_PLUGIN_DIR/plugins/iconic-private-plugin.zip --activate
    php wp-cli.phar plugin list
}

bootstrap.php

/**
 * Setup the unit testing environment.
 */
public function __construct() {
    // phpcs:disable WordPress.PHP.DiscouragedPHPFunctions, WordPress.PHP.DevelopmentFunctions
    ini_set( 'display_errors', 'on' );
    error_reporting( E_ALL );
    // phpcs:enable WordPress.PHP.DiscouragedPHPFunctions, WordPress.PHP.DevelopmentFunctions

    // Ensure server variable is set for WP email functions.
    // phpcs:disable WordPress.VIP.SuperGlobalInputUsage.AccessDetected
    if ( ! isset( $_SERVER['SERVER_NAME'] ) ) {
        $_SERVER['SERVER_NAME'] = 'localhost';
    }
    // phpcs:enable WordPress.VIP.SuperGlobalInputUsage.AccessDetected

    $this->tests_dir    = dirname( __FILE__ );
    $this->plugin_dir   = dirname( $this->tests_dir );
    $this->wp_tests_dir = getenv( 'WP_TESTS_DIR' ) ? getenv( 'WP_TESTS_DIR' ) : rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress-tests-lib';

    // load test function so tests_add_filter() is available.
    require_once $this->wp_tests_dir . '/includes/functions.php';

    // load Dependencies.
    tests_add_filter( 'muplugins_loaded', array( $this, 'my_custom_plugin_manually_load_plugin' ) );

    // install WC.
    tests_add_filter( 'setup_theme', array( $this, 'install_wc' ) );

    // load the WP testing environment.
    require_once $this->wp_tests_dir . '/includes/bootstrap.php';
}

/**
 * Install WooCommerce after the test environment and WC have been loaded.
 */
public function install_wc() {
    // Clean existing install first.
    define( 'WP_UNINSTALL_PLUGIN', true );
    define( 'WC_REMOVE_ALL_DATA', true );
    include (ABSPATH . 'wp-content/plugins/woocommerce/uninstall.php');
    WC_Install::install();
    // Reload capabilities after install, see https://core.trac.wordpress.org/ticket/28374
    if ( version_compare( $GLOBALS['wp_version'], '4.7', '<' ) ) {
        $GLOBALS['wp_roles']->reinit();
    } else {
        $GLOBALS['wp_roles'] = null; // WPCS: override ok.
        wp_roles();
    }
    echo esc_html( 'Installing WooCommerce...' . PHP_EOL );
}


/**
 * Load Dependencies
 */
public function my_custom_plugin_manually_load_plugin() {
    $this->plugins_dir = ABSPATH . str_replace( site_url() . "https://stackoverflow.com/", '', plugins_url() ) . "https://stackoverflow.com/";

    // Load dependencies.
    require_once $this->plugins_dir . 'woocommerce/woocommerce.php';
    require_once $this->plugins_dir . 'iconic/iconic-private-plugin.php';

    // Load plugin.
    require_once $this->plugin_dir . '/my-custom-plugin.php';

    global $my_custom_plugin;
    $my_custom_plugin = new My_Custom_Plugin_Class();
}

Meine Unit-Tests

<?php
/**
 * Sql test case.
 */
class SqlTest extends WP_UnitTestCase {

    /**
     * Set up fixtures before class for all tests in SqlTest Class.
     *
     * @param object $factory passed by WP_UnitTestCase.
     */
    public static function wpSetUpBeforeClass( $factory ) {
        self::createFixtures();
        self::createSettings();
    }

    public function setUp() {
        self::set_active_plugins();
    }

    public static function set_active_plugins() {
        activate_plugin(ABSPATH . 'wp-content/plugins/woocommerce/woocommerce.php');
        activate_plugin(ABSPATH . 'wp-content/plugins/iconic/iconic-private-plugin.php');
    }

    /**
     * Warehouses fixtures
     */
    public static function createFixtures() {
        // [...]
    }

    /**
     * Create timeslots
     */
    public static function createSettings() {
        $settings = array (
            // [...]
        );

        update_option( 'iconic_private_plugin_settings', $settings );
        global $iconic_private_plugin;
        $iconic_private_plugin->settings = $settings;
    }

    /**
     * Test for custom_function.
     */
    public function test_custom_function() {
        global $my_custom_plugin, $iconic_private_plugin;

        echo $iconic_private_plugin->bar; // Has not been assigned!!! (but it should be.

        print_r($iconic_private_plugin); 
        // Class properties are empty, since construct method stop at WooCommerce activation check. (same as above example)

        $this->assertTrue(true);
    }

}

Wie Sie sehen, habe ich sogar versucht, die Plugins zwischen den einzelnen Tests direkt in der Datenbank zu aktivieren (setUp-Funktion).

Ich denke also, das Problem könnte von bootstrap.php kommen

Ich konnte im Internet keine Dokumentation oder ähnliche Probleme finden.

Das einzige, was nah genug war:

WordPress-Plugin phpunit testet mit Abhängigkeiten

Ich lasse mich auch von WooCommerce-Tests inspirieren Konfiguration.

Irgendwelche Ideen, was ich falsch mache?

AKTUALISIEREN

Nach der Antwort von T.Todua habe ich einige Warnungen in die Konsole geworfen. Die Instanziierung der Abhängigkeit wurde jedoch gelöst, und die Tests funktionieren wie beabsichtigt.

Aber da es diese Warnungen gibt, frage ich mich, ob es der richtige Weg ist, dies zu tun und / oder wie diese Warnungen behoben werden können.

Alle diese Warnungen scheinen mit der Freemius-Abhängigkeit zusammenzuhängen (nur eine hier, da es mehr oder weniger die gleichen gibt).

Also wohl nichts mit diesem Problem zu tun.

Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
PHP Warning:  fopen(/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/iconic-private-plugin.php): failed to open stream: No such file or directory in /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-includes/functions.php on line 4918
PHP Stack trace:
PHP   1. {main}() /usr/local/bin/phpunit:0
PHP   2. PHPUnit\TextUI\Command::main() /usr/local/bin/phpunit:570
PHP   3. PHPUnit\TextUI\Command->run() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:148
PHP   4. PHPUnit\TextUI\Command->handleArguments() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:159
PHP   5. PHPUnit\TextUI\Command->handleBootstrap() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:788
PHP   6. PHPUnit\Util\Fileloader::checkAndLoad() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:991
PHP   7. PHPUnit\Util\Fileloader::load() phar:///usr/local/bin/phpunit/phpunit/Util/Fileloader.php:48
PHP   8. include_once() phar:///usr/local/bin/phpunit/phpunit/Util/Fileloader.php:64
PHP   9. My_Plugin_Unit_Tests_Bootstrap::instance() /Users/brieuc/Workspace/php/my-plugin/web/wp-content/plugins/my-plugin-geo/tests/bootstrap.php:150
PHP  10. My_Plugin_Unit_Tests_Bootstrap->__construct() /Users/brieuc/Workspace/php/my-plugin/web/wp-content/plugins/my-plugin-geo/tests/bootstrap.php:145
PHP  11. require_once() /Users/brieuc/Workspace/php/my-plugin/web/wp-content/plugins/my-plugin-geo/tests/bootstrap.php:80
PHP  12. require_once() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress-tests-lib/includes/bootstrap.php:105
PHP  13. do_action() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-settings.php:295
PHP  14. WP_Hook->do_action() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-includes/plugin.php:453
PHP  15. WP_Hook->apply_filters() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-includes/class-wp-hook.php:310
PHP  16. My_Plugin_Unit_Tests_Bootstrap->load_wds() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-includes/class-wp-hook.php:286
PHP  17. require_once() /Users/brieuc/Workspace/php/my-plugin/web/wp-content/plugins/my-plugin-geo/tests/bootstrap.php:93
PHP  18. jckWooDeliverySlots->__construct() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/iconic-private-plugin.php:3209
PHP  19. jckWooDeliverySlots->load_classes() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/iconic-private-plugin.php:114
PHP  20. Iconic_Private_Core_Licence::run() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/iconic-private-plugin.php:175
PHP  21. Iconic_Private_Core_Licence->__construct() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/inc/class-core-licence.php:49
PHP  22. Iconic_Private_Core_Licence::configure_freemius() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/inc/class-core-licence.php:60
PHP  23. fs_dynamic_init() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/inc/class-core-licence.php:88
PHP  24. Freemius::instance() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/inc/vendor/freemius/start.php:506
PHP  25. Freemius->__construct() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/inc/vendor/freemius/includes/class-freemius.php:2217
PHP  26. Freemius->get_plugin_name() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/inc/vendor/freemius/includes/class-freemius.php:469
PHP  27. Freemius->set_name() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/inc/vendor/freemius/includes/class-freemius.php:8627
PHP  28. Freemius->get_plugin_data() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/inc/vendor/freemius/includes/class-freemius.php:8648
PHP  29. get_plugin_data() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-content/plugins/iconic-private-plugin/inc/vendor/freemius/includes/class-freemius.php:8475
PHP  30. get_file_data() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-admin/includes/plugin.php:84
PHP  31. fopen() /private/var/folders/1n/7zbwzbgj1vz7y89rbjb5hg340000gn/T/wordpress/wp-includes/functions.php:4918

  • Zustimmen! Aber … Funktionen, die getestet werden müssen, rufen mehrere Funktionen aus dieser Abhängigkeit auf. Ich sehe kaum ein, wie ich es verspotten und dann beibehalten könnte.

    – Brieuc

    14. Februar 2019 um 12:59 Uhr

  • Es ist also kein UnitTest, sondern ein Funktionstest

    – DevDonkey

    14. Februar 2019 um 13:14 Uhr

  • Ist es möglich, dass die Plugin-Datei bereits vor Ihnen enthalten war? set_active_plugin ? Wenn dies der Fall ist, wird die Plugin-Klasse möglicherweise instanziiert, ohne dass Woocommerce noch aktiv ist. Überprüfen Sie, was enthalten ist php.net/manual/en/function.get-included-files.php in set_active_plugin Vor activate_plugin(ABSPATH . 'wp-content/plugins/iconic/iconic-private-plugin.php');

    – Andreas

    15. Februar 2019 um 10:29 Uhr


  • @DevDonkey Sie haben Recht, dieser spezielle Test wäre eher ein Funktionstest. Ich würde lieber Unit-Tests verwenden, aber ich glaube nicht, dass ich die Abhängigkeit verspotten könnte. Danke für den Beitrag :).

    – Brieuc

    18. Februar 2019 um 9:03 Uhr

  • @Andrew war es und ich konnte das Plugin mit diesem Hook nicht aktivieren. Aber wie von T.Todua beantwortet, hat die Anforderung von wp-admin/includes/plugin.php den Trick getan (zumindest um WooCommerce zu aktivieren, bevor das andere Plugin benötigt wird.

    – Brieuc

    18. Februar 2019 um 9:05 Uhr

Was wäre, wenn Sie verwendet würden

private function force_activate( $plugin ) {
    if( ! function_exists('activate_plugin') ) {
        require_once ABSPATH . 'wp-admin/includes/plugin.php';
    }

    if( ! is_plugin_active( $plugin ) ) {
        activate_plugin( $plugin );
    }
}



...

// Load dependencies.
require_once $this->plugins_dir . 'woocommerce/woocommerce.php';
$this->force_activate('woocommerce/woocommerce.php');
require_once $this->plugins_dir . 'iconic/iconic-private-plugin.php';

  • Es scheint, es würde den Trick tun ;). Es scheint, dass das Plugin gut instanziiert ist. Ich habe einige andere Fehler, die jetzt ausgelöst werden, aber ich werde sicherstellen, dass es nicht damit zusammenhängt.

    – Brieuc

    18. Februar 2019 um 8:59 Uhr

  • @Brieuc Ich denke, das ist ein anderer Fall. Sie sollten dafür besser eine neue Frage mit einem bestimmten Titel öffnen. Und am liebsten bei s.tk/wp

    – T. Todua

    18. Februar 2019 um 12:26 Uhr

  • Vielen Dank! Ich hatte einige Zweifel daran :).

    – Brieuc

    18. Februar 2019 um 12:29 Uhr

1229060cookie-checkKomponententests mit einem benutzerdefinierten WordPress-Plugin mit verschachtelten Plugin-Abhängigkeiten

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy