Make WordPress Core

Opened 2 years ago

Last modified 2 years ago

#48300 new defect (bug)

metadata registered using register_meta() do not persist through several tests

Reported by: leogermani Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 5.1
Component: Build/Test Tools Keywords:
Focuses: rest-api Cc:


When you register a metadata using register_meta() function, or one of its variants, such as register_post_meta(), the metadata is present in the response of get_registered_meta_keys() only in the first test of a file...

I found this issue writing tests for a plugin, in a structure created based on the wp scaffold plugin-tests cli command.

How to reproduce

Write a plugin with jus this simple code:


add_action('init', 'test_register_post_meta');
function test_register_post_meta() {
        register_post_meta('post', 'test_meta', [
                'show_in_rest' => true,
                'single' => true,
                'type' => 'number',
                'description' => 'test metadata'

And then run these simple tests:


class TestRegisterPostMeta extends \WP_UnitTestCase {

        function test_register_post_meta() {
                $registered_meta = get_registered_meta_keys('post', 'post');
                $this->assertArrayHasKey('test_meta', $registered_meta); // it passes!
        function test_register_post_meta_again() {
                $registered_meta = get_registered_meta_keys('post', 'post');
                $this->assertArrayHasKey('test_meta', $registered_meta); // it fails! 

This is very odd, but the second test, which is identical to the first, fails.

Change History (7)

This ticket was mentioned in Slack in #cli by leogermani. View the logs.

2 years ago

#2 @TimothyBlynJacobs
2 years ago

  • Focuses rest-api added
  • Version changed from 5.2.3 to 5.1

Introduced in #46007.

#3 @leogermani
2 years ago

@jnylen0 could you comment on this?

#4 @jnylen0
2 years ago

Tests should not affect the global state for other tests, so we reset the registered meta keys after each test.

A better way to do this might be to save the registered meta keys in setUp before each test runs, and then restore them in tearDown.

In the meantime you'll need to arrange for your meta keys to be registered at the beginning of your tests, for example in the setUp method of any relevant test classes.

#5 @leogermani
2 years ago

Hi @jnylen0 thanks for your comment.

I'm not sure I was clear, but the metadata are being registered in the plugin, so they should be available in all tests, just like registered post types are... (right?)

Yes, for now, I'm re-registering everything in the setUp method, but I'm assuming this is a workaround while this is not fixed...

It's just no clear to me if you consider this a bug that we could work on or not.

thanks again

#6 @peterwilsoncc
2 years ago

The WP Test Suite's tear down functions returns the global state to a before the init action fires. I'm not sure where it gets reset too from memory though.

To refire the init hooks you can include do_action( 'init' ) in your set up functions. You can see an example of this in tests/phpunit/tests/customize/selective-refresh-ajax.php's do_customize_boot_actions() method.

#7 @jnylen0
2 years ago

I'll defer to other committers who have been active more recently, but yes, I think this is a legitimate bug. Plugins should be able to test their post types and meta values without jumping through hoops.

A better way to do this might be to save the registered meta keys in setUp before each test runs, and then restore them in tearDown.

This would fix it. Though now that I think about it, probably need to do the same for setUpBeforeClass and tearDownAfterClass also.

@peterwilsoncc this resetting of global state happens "piecemeal" and in several different places, it's not as clean as what you seem to be describing. The specific code that causes this issue with metadata was added in [44633].

Note: See TracTickets for help on using tickets.