1

EDIT:

I've created the mwe as a small test plugin: https://github.com/dingo-d/test-plugin


Original question:

I'm writing tests for my plugin and one thing makes no sense to me and I'm not sure if I'm doing something wrong, or is it just PHPUnit behaving in a certain way.

In a class I have a register()method where I add my hooks.

When I write a test, I usually instantiate my class (even though I shouldn't because I'm running integration test so when I load my test the plugin with all its hooks should be working if I'm not mistaken), and I call the register() method.

For instance I have a Menu class that looks something like this:

<?php

final class Menu implements Service {

  public function register() : void {
    add_action( 'after_setup_theme', [ $this, 'register_menu_positions' ] );
  }

  public function register_menu_positions() : void {
    register_nav_menus(
      [
        'headerMenu' => esc_html__( 'Main Menu', 'my-plugin' ),
        'footerMenu' => esc_html__( 'Footer Menu', 'my-plugin' ),
      ]
    );
  }
}

When I set up my test

<?php
class Menus_Test extends \WP_UnitTestCase {

  protected $admin_menu;

  /**
   * Test suite setUp method
   */
  public function setUp() {
    parent::setUp();

    $this->admin_menu = new Menu();
    $this->admin_menu->register();
  }

  /**
   * Test suite tearDown method
   */
  public function tearDown() {
    parent::tearDown();
  }

  public function test_registered_hooks() {
    $this->assertEquals( has_action( 'after_setup_theme', [ $this->admin_menu, 'register_menu_positions' ] ), 10 );
  }

  /**
   * Test that menus are correctly registered
   */
  public function test_registered_menus() {
    $menus = get_registered_nav_menus();

    $this->assertArrayHasKey( 'headerMenu', $menus );
    $this->assertArrayHasKey( 'footerMenu', $menus );
  }
}

and when I run it, the coverage will be green for the register method, and the test will pass (the assertions that I have headerMenu and footerMenu registered is ok), but the coverage for my register_menu_positions method will be red. Like it's not covered by the test.

When I add

<?php
  public function test_registered_menus() {

    $this->admin_menu->register_menu_positions();

    $menus = get_registered_nav_menus();

    $this->assertArrayHasKey( 'headerMenu', $menus );
    $this->assertArrayHasKey( 'footerMenu', $menus );
  }

The coverage turns green.

But the test passes even without it! Because it's an integration test and it tests if my code works with WordPress.

Why is that?

I used wp-cli scaffold to set up tests, and I'm using "phpunit/phpunit": "^7" for testing (via composer).

Is it just a PHPUnit not understanding the WordPress hooks system or?

Edit:

Ok, another bizzare thing.

I wrote a test that looks like this

public function test_if_custom_post_types_are_registered() {
  $post_types = get_post_types();

  $documentation = \My_Plugin\Custom_Post_Type\Documentation::POST_TYPE_SLUG;
  $email         = \My_Plugin\Custom_Post_Type\Email_Templates::POST_TYPE_SLUG;
  $faq           = \My_Plugin\Custom_Post_Type\Faq::POST_TYPE_SLUG;

  $this->assertTrue( isset( $post_types[ $documentation ] ) );
  $this->assertTrue( isset( $post_types[ $email ] ) );
  $this->assertTrue( isset( $post_types[ $faq ] ) );
}

The test passes, because my CPT's are registered and present in the get_post_types list (I've checked by printing it out), and yet the code that is responsible for registering CPTs is not green.

Wierdest part is that, when I do a print_r('TEST PASSES HERE') in my actual code (in the register() method where I put my hooks) and run the test, I can see the output before the test results

> @php ./vendor/bin/phpunit -c phpunit.xml.dist --no-coverage --colors=always
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
TEST PASSES HERE IN CPT REGISTER!!!!!!!TEST PASSES HERE IN CPT REGISTER!!!!!!!TEST PASSES HERE IN CPT REGISTER!!!!!!!Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.

PHPUnit Pretty Result Printer 0.20.3 by Codedungeon and contributors.
==> Configuration: ~/vagrant-local/www/infinum/project/public_html/wp-content/plugins/my-plugin/phpunit-printer.yml

PHPUnit 7.5.14 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.3.7 with Xdebug 2.7.2
Configuration: /Users/infinum-denis/vagrant-local/www/infinum/project/public_html/wp-content/plugins/my-plugin/phpunit.xml.dist


 ==> Login_Test                                 ✓  ✓  ✓
 ==> Plugin_Test                                ✓  ✓  ✓

Time: 2.19 seconds, Memory: 42.50 MB

OK (6 tests, 11 assertions)

So what's the deal with this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.