[wp-trac] [WordPress Trac] #51752: Enable the static variable in wp_get_environment_type() to be reset

WordPress Trac noreply at wordpress.org
Wed Nov 11 20:54:02 UTC 2020


#51752: Enable the static variable in wp_get_environment_type() to be reset
----------------------------+----------------------
 Reporter:  stevegrunwell   |       Owner:  (none)
     Type:  enhancement     |      Status:  closed
 Priority:  normal          |   Milestone:
Component:  Bootstrap/Load  |     Version:  5.5
 Severity:  normal          |  Resolution:  wontfix
 Keywords:                  |     Focuses:
----------------------------+----------------------

Comment (by stevegrunwell):

 Apologies that the example provided was overly-simplistic, but the
 hundreds of tests for the platform-wide plugin I maintain wouldn't fit
 well here 😅

 My concern stems from the fact that once the static variable is set,
 there's no way to change it without spawning a new PHP process; a small
 performance gain for production, but a road-block when it comes to
 testing.

 Imagine the following scenario in a plugin:

 {{{#!php
 <?php

 if ( 'production' !== wp_get_environment_type() ) {
     add_action( 'admin_notices', 'myplugin_show_non_production_notice' );
 }
 }}}

 It would be difficult to test that the action gets hooked in a staging
 environment if another test had previously called
 `wp_get_environment_type()`, as the static variable has polluted the
 global state. [https://ttmm.io/tech/singleton-alternative/ It's the same
 issue we've been fighting forever with the popularity of the Singleton
 pattern], only PHP's reflection doesn't allow us to reset static variables
 in functions.

 I definitely understand the concerns posed by @TimothyBlynJacobs and
 @johnbillion, however, and I see now that adding a bypass parameter isn't
 the way to go.

 WordPress is a tightly-coupled application by nature, which can introduce
 some challenges when testing. This is one of the things I've been aiming
 to address with [https://github.com/assertwell/phpunit-global-state the
 assertwell/phpunit-global-state Composer package]; if anyone comes across
 this ticket at a later date and is like "well, how the heck ''do'' I test
 that branch, [https://www.php.net/manual/en/book.runkit7.php runkit] may
 be your best bet (taking care to restore the original function or risk an
 even worse headache):

 {{{#!php
 <?php

 namespace Tests;

 use AssertWell\PHPUnitGlobalState\Functions;
 use WP_UnitTestCase;

 class MyPluginTest extends WP_UnitTestCase {
         use Functions;

         /**
          * @test
          */
         public function
 it_should_display_a_notice_if_in_non_production_environments() {
                 $this->redefineFunction( 'wp_get_environment_type',
 function () {
                         return 'staging';
                 } );

                 ( new MyPlugin() )->add_hooks();

                 $this->assertIsNumeric(
                         has_action( 'admin_notices',
 'myplugin_show_non_production_notice' ),
                         'Expected a staging notice to be displayed in non-
 production environments.'
                 );
         }

         /**
          * @test
          */
         public function
 it_should_not_display_a_notice_in_production_environments() {
                 $this->redefineFunction( 'wp_get_environment_type',
 function () {
                         return 'production';
                 } );

                 ( new MyPlugin() )->add_hooks();

                 $this->assertFalse(
                         has_action( 'admin_notices',
 'myplugin_show_non_production_notice' ),
                         'The staging notice should not appear in
 production environments.'
                 );
         }
 }
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/51752#comment:3>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list