Index: tests/phpunit/tests/rest-api/rest-post-meta-fields.php
===================================================================
--- tests/phpunit/tests/rest-api/rest-post-meta-fields.php	(revision 40058)
+++ tests/phpunit/tests/rest-api/rest-post-meta-fields.php	(working copy)
@@ -10,13 +10,16 @@
   * @group restapi
   */
 class WP_Test_REST_Post_Meta_Fields extends WP_Test_REST_TestCase {
+	protected static $wp_meta_keys_saved;
 	protected static $post_id;
 
 	public static function wpSetUpBeforeClass( $factory ) {
+		self::$wp_meta_keys_saved = $GLOBALS['wp_meta_keys'];
 		self::$post_id = $factory->post->create();
 	}
 
 	public static function wpTearDownAfterClass() {
+		$GLOBALS['wp_meta_keys'] = self::$wp_meta_keys_saved;
 		wp_delete_post( self::$post_id, true );
 	}
 
Index: tests/phpunit/tests/rest-api/rest-schema-setup.php
===================================================================
--- tests/phpunit/tests/rest-api/rest-schema-setup.php	(revision 40058)
+++ tests/phpunit/tests/rest-api/rest-schema-setup.php	(working copy)
@@ -74,27 +74,71 @@
 	}
 
 	public function test_build_wp_api_client_fixtures() {
-		// Set up for testing the individual endpoints.
-		// Set a current admin user.
-		$administrator = $this->factory->user->create( array(
-			'role' => 'administrator',
+		// Set up data for individual endpoint responses.  We need to specify
+		// lots of different fields on these objects, otherwise the generated
+		// fixture file will be different between runs of PHPUnit tests, which
+		// is not desirable.
+
+		$administrator_id = $this->factory->user->create( array(
+			'role'          => 'administrator',
+			'display_name'  => 'REST API Client Fixture: User',
+			'user_nicename' => 'restapiclientfixtureuser',
+			'user_email'    => 'administrator@example.org',
 		) );
-		wp_set_current_user( $administrator );
+		wp_set_current_user( $administrator_id );
 
-		// Set up data for endpoints.
-		$post_id  = $this->factory->post->create();
-		$page_id  = $this->factory->post->create( array( 'post_type' => 'page' ) );
-		$tag_id   = $this->factory->tag->create( array( 'name' => 'test' ) );
+		$post_id = $this->factory->post->create( array(
+			'post_name'      => 'restapi-client-fixture-post',
+			'post_title'     => 'REST API Client Fixture: Post',
+			'post_content'   => 'REST API Client Fixture: Post',
+			'post_excerpt'   => 'REST API Client Fixture: Post',
+			'post_author'    => 0,
+		) );
+		wp_update_post( array(
+			'ID'           => $post_id,
+			'post_content' => 'Updated post content.',
+		) );
+
+		$page_id = $this->factory->post->create( array(
+			'post_type'      => 'page',
+			'post_name'      => 'restapi-client-fixture-page',
+			'post_title'     => 'REST API Client Fixture: Page',
+			'post_content'   => 'REST API Client Fixture: Page',
+			'post_excerpt'   => 'REST API Client Fixture: Page',
+			'post_date'      => '2017-02-14 00:00:00',
+			'post_date_gmt'  => '2017-02-14 00:00:00',
+			'post_author'    => 0,
+		) );
+		wp_update_post( array(
+			'ID'           => $page_id,
+			'post_content' => 'Updated page content.',
+		) );
+
+		$tag_id = $this->factory->tag->create( array(
+			'name'        => 'REST API Client Fixture: Tag',
+			'slug'        => 'restapi-client-fixture-tag',
+			'description' => 'REST API Client Fixture: Tag',
+		) );
+
 		$media_id = $this->factory->attachment->create_object( '/tmp/canola.jpg', 0, array(
 			'post_mime_type' => 'image/jpeg',
 			'post_excerpt'   => 'A sample caption',
+			'post_name'      => 'restapi-client-fixture-attachment',
+			'post_title'     => 'REST API Client Fixture: Attachment',
+			'post_date'      => '2017-02-14 00:00:00',
+			'post_date_gmt'  => '2017-02-14 00:00:00',
+			'post_author'    => 0,
 		) );
-		wp_update_post( array( 'post_content' => 'Updated content.', 'ID' => $post_id ) );
-		wp_update_post( array( 'post_content' => 'Updated content.', 'ID' => $page_id ) );
+
 		$comment_id = $this->factory->comment->create( array(
-			'comment_approved' => 1,
-			'comment_post_ID'  => $post_id,
-			'user_id'          => 0,
+			'comment_approved'     => 1,
+			'comment_post_ID'      => $post_id,
+			'user_id'              => 0,
+			'comment_date'         => '2017-02-14 00:00:00',
+			'comment_date_gmt'     => '2017-02-14 00:00:00',
+			'comment_author'       => 'Internet of something or other',
+			'comment_author_email' => 'lights@example.org',
+			'comment_author_url'   => 'http://lights.example.org/',
 		) );
 
 		// Generate route data for subsequent QUnit tests.
@@ -196,7 +240,7 @@
 				'name'  => 'UsersCollection',
 			),
 			array(
-				'route' => '/wp/v2/users/1',
+				'route' => '/wp/v2/users/' . $administrator_id,
 				'name'  => 'UserModel',
 			),
 			array(
@@ -217,12 +261,12 @@
 			),
 		);
 
-		// Set up the mocked response and tell jshint to ignore the single quote json objects
-		$mocked_responses = "/*jshint -W109 */\n\nvar mockedApiResponse = {};\n\n";
-		$mocked_responses .= "/**\n";
+		$mocked_responses = "/**\n";
 		$mocked_responses .= " * DO NOT EDIT\n";
 		$mocked_responses .= " * Auto-generated by test_build_wp_api_client_fixtures\n";
 		$mocked_responses .= " */\n";
+		$mocked_responses .= "var mockedApiResponse = {};\n";
+		$mocked_responses .= "/* jshint -W109 */\n";
 
 		foreach ( $routes_to_generate_data as $route ) {
 			$request = new WP_REST_Request( 'GET', $route['route'] );
@@ -231,7 +275,10 @@
 
 			$this->assertTrue( ! empty( $data ), $route['name'] . ' route should return data.' );
 
-			$mocked_responses .= 'mockedApiResponse.' . $route['name'] . ' = ' . wp_json_encode( $data ) . ";\n\n";
+			$fixture = $this->normalize_fixture( $data, $route['name'] );
+			$mocked_responses .= "\nmockedApiResponse." . $route['name'] . ' = '
+				. json_encode( $fixture, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES )
+				. ";\n";
 		}
 
 		// Save the route object for QUnit tests.
@@ -245,4 +292,95 @@
 		wp_delete_attachment( $media_id );
 		wp_delete_comment( $comment_id );
 	}
+
+	/**
+	 * This array contains normalized versions of object IDs and other values
+	 * that can change depending on how PHPUnit is executed.  For details on
+	 * how they were generated, see #39264.
+	 */
+	private static $fixture_replacements = array(
+		'PostsCollection.0.id' => 3,
+		'PostsCollection.0.guid.rendered' => 'http://example.org/?p=3',
+		'PostsCollection.0.link' => 'http://example.org/?p=3',
+		'PostsCollection.0._links.self.0.href' => 'http://example.org/?rest_route=/wp/v2/posts/3',
+		'PostsCollection.0._links.replies.0.href' => 'http://example.org/?rest_route=%2Fwp%2Fv2%2Fcomments&post=3',
+		'PostsCollection.0._links.version-history.0.href' => 'http://example.org/?rest_route=/wp/v2/posts/3/revisions',
+		'PostsCollection.0._links.wp:attachment.0.href' => 'http://example.org/?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3',
+		'PostsCollection.0._links.wp:term.0.href' => 'http://example.org/?rest_route=%2Fwp%2Fv2%2Fcategories&post=3',
+		'PostsCollection.0._links.wp:term.1.href' => 'http://example.org/?rest_route=%2Fwp%2Fv2%2Ftags&post=3',
+		'PostModel.id' => 3,
+		'PostModel.guid.rendered' => 'http://example.org/?p=3',
+		'PostModel.link' => 'http://example.org/?p=3',
+		'postRevisions.0.author' => '2',
+		'postRevisions.0.id' => 4,
+		'postRevisions.0.parent' => 3,
+		'postRevisions.0.slug' => '3-revision-v1',
+		'postRevisions.0.guid.rendered' => 'http://example.org/?p=4',
+		'postRevisions.0._links.parent.0.href' => 'http://example.org/?rest_route=/wp/v2/posts/3',
+		'PagesCollection.0.id' => 5,
+		'PagesCollection.0.guid.rendered' => 'http://example.org/?page_id=5',
+		'PagesCollection.0.link' => 'http://example.org/?page_id=5',
+		'PagesCollection.0._links.self.0.href' => 'http://example.org/?rest_route=/wp/v2/pages/5',
+		'PagesCollection.0._links.replies.0.href' => 'http://example.org/?rest_route=%2Fwp%2Fv2%2Fcomments&post=5',
+		'PagesCollection.0._links.version-history.0.href' => 'http://example.org/?rest_route=/wp/v2/pages/5/revisions',
+		'PagesCollection.0._links.wp:attachment.0.href' => 'http://example.org/?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5',
+		'PageModel.id' => 5,
+		'PageModel.guid.rendered' => 'http://example.org/?page_id=5',
+		'PageModel.link' => 'http://example.org/?page_id=5',
+		'pageRevisions.0.author' => '2',
+		'pageRevisions.0.id' => 6,
+		'pageRevisions.0.parent' => 5,
+		'pageRevisions.0.slug' => '5-revision-v1',
+		'pageRevisions.0.guid.rendered' => 'http://example.org/?p=6',
+		'pageRevisions.0._links.parent.0.href' => 'http://example.org/?rest_route=/wp/v2/pages/5',
+		'MediaCollection.0.id' => 7,
+		'MediaCollection.0.guid.rendered' => 'http://example.org/?attachment_id=7',
+		'MediaCollection.0.link' => 'http://example.org/?attachment_id=7',
+		'MediaCollection.0._links.self.0.href' => 'http://example.org/?rest_route=/wp/v2/media/7',
+		'MediaCollection.0._links.replies.0.href' => 'http://example.org/?rest_route=%2Fwp%2Fv2%2Fcomments&post=7',
+		'MediaModel.id' => 7,
+		'MediaModel.guid.rendered' => 'http://example.org/?attachment_id=7',
+		'MediaModel.link' => 'http://example.org/?attachment_id=7',
+		'TagsCollection.0.id' => 2,
+		'TagsCollection.0._links.self.0.href' => 'http://example.org/?rest_route=/wp/v2/tags/2',
+		'TagsCollection.0._links.wp:post_type.0.href' => 'http://example.org/?rest_route=%2Fwp%2Fv2%2Fposts&tags=2',
+		'TagModel.id' => 2,
+		'UsersCollection.1.id' => 2,
+		'UsersCollection.1.link' => 'http://example.org/?author=2',
+		'UsersCollection.1._links.self.0.href' => 'http://example.org/?rest_route=/wp/v2/users/2',
+		'UserModel.id' => 2,
+		'UserModel.link' => 'http://example.org/?author=2',
+		'me.id' => 2,
+		'me.link' => 'http://example.org/?author=2',
+		'CommentsCollection.0.id' => 2,
+		'CommentsCollection.0.post' => 3,
+		'CommentsCollection.0.link' => 'http://example.org/?p=3#comment-2',
+		'CommentsCollection.0._links.self.0.href' => 'http://example.org/?rest_route=/wp/v2/comments/2',
+		'CommentsCollection.0._links.up.0.href' => 'http://example.org/?rest_route=/wp/v2/posts/3',
+	);
+
+	private function normalize_fixture( $data, $path ) {
+		if ( isset( self::$fixture_replacements[ $path ] ) ) {
+			return self::$fixture_replacements[ $path ];
+		}
+
+		if ( ! is_array( $data ) ) {
+			return $data;
+		}
+
+		foreach ( $data as $key => $value ) {
+			if ( is_string( $value ) && (
+				'date' === $key ||
+				'date_gmt' === $key ||
+				'modified' === $key ||
+				'modified_gmt' === $key
+			) ) {
+				$data[ $key ] = '2017-02-14T00:00:00';
+			} else {
+				$data[ $key ] = $this->normalize_fixture( $value, "$path.$key" );
+			}
+		}
+
+		return $data;
+	}
 }
