Coverage in integration tests

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?

Topic integration-tests unit-tests testing Wordpress

Category Web

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.