WP Unit test Codeception gotcha

Getting around a Codeception issue in WordPress “unit” tests.

The problem

I keep running on this issue now and then especially when testing plugins or themes that require a fixture to be in place using the WP Browser module for Codeception.
Given the typical Codeception tests folder structure

/src
/tests
    _bootstrap.php <<< loaded
    /acceptance
        _bootstrap.php
    /functional
        _bootstrap.php <<< not loaded
    /unit
        _bootstrap.php

adding set up methods in the bootstrap file marked “not loaded” will not work.
Ideally, I’m using the latest plugin I’m developing as an example, the /tests/functional/_bootstrap.php file should contain this

<?php
// Here you can initialize variables that will be available to your tests

// register the taxonomy the plugin will use 
tests_add_filter('init', function(){
    register_taxonomy( 'user-group', 'user' );
});

// activate the plugin
activate_plugin( 'user-groups-content-restriction/user-groups-content-restriction.php' );

and the test case should run after the global and the functional _bootstrap.php files have been included.

<?php
class ugcr_TermManagerTest extends \WP_UnitTestCase {

    protected $backupGlobals = false;

    /**
     * @var ugcr_TermManager
     */
    protected $sut;

    public function setUp() {

        // before
        parent::setUp();

        // your set up methods here
        $this->sut = new ugcr_TermManager();
    }

    public function tearDown() {
        // your tear down methods here

        // then
        parent::tearDown();
    }

    /**
     * @test
     * it should add all the terms on activation if none present
     */
    public function it_should_add_all_the_terms_on_activation_if_none_present() {
        $terms = $this->sut->get_terms();

        $this->assertCount( 0, get_terms( 'user-group' ) );

        $this->sut->insert_terms();

        $this->assertCount( count( $terms ), get_terms( 'user-group', [ 'hide_empty' => false ] ) );
    }
}

This will not work at the moment and the issue is a known one. The Codeception team has proved amazing and will fix the issue as soon as they have the energy to do so.

Fix

That’s not always the case and will not work if the plugin has critical operations tied to WordPress hooks like init but will work in this specific case; the code that should be executed in the _bootstrap.php file I ’ve simply moved to the setUp method of the test case:

<?php

class ugcr_TermManagerTest extends \WP_UnitTestCase {

    protected $backupGlobals = false;

    /**
     * @var ugcr_TermManager
     */
    protected $sut;

    public function setUp() {

        // before
        parent::setUp();

        // your set up methods here
        activate_plugin( 'user-groups-content-restriction/user-groups-content-restriction.php' );
        register_taxonomy( 'user-group', 'user' );
        $this->sut = new ugcr_TermManager();
    }

    public function tearDown() {
        // your tear down methods here

        // then
        parent::tearDown();
    }

    /**
     * @test
     * it should add all the terms on activation if none present
     */
    public function it_should_add_all_the_terms_on_activation_if_none_present() {
        $terms = $this->sut->get_terms();

        $this->assertCount( 0, get_terms( 'user-group' ) );

        $this->sut->insert_terms();

        $this->assertCount( count( $terms ), get_terms( 'user-group', [ 'hide_empty' => false ] ) );
    }
} 

Working test set-up