14
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

WordPressでカスタムフィードを作って、その出力に対してPHPUnitでテスト

Last updated at Posted at 2015-07-18

WordPressでadd_feed()を使ってカスタムなフィードを作った際に、たとえば期待した要素が追加されているかとかそういうのをPHPUnitで確認する方法。

テスト用のソースは以下のような感じ

/**
 * @runTestsInSeparateProcesses
 */
class YahooFeed_Test extends WP_UnitTestCase
{
	public function setUp()
	{
		parent::setUp();

		$this->factory->post->create_many( 25 );
	}

	public function tearDown() {
		parent::tearDown();
		$GLOBALS['wp_rewrite']->init();
	}

	/**
	 * @test
	 */
	public function do_feed()
	{
		$this->go_to( '/?feed=my-feed' );

		ob_start();
		load_template( ABSPATH . 'wp-includes/feed-rss2.php' );
		$feed = ob_get_clean();
		$xml = xml_to_array( $feed );

		$channel = xml_find( $xml, 'rss', 'channel' );
		$this->assertTrue( empty( $channel[0]['attributes'] ) );

		$title = xml_find( $xml, 'rss', 'channel', 'title' );
		$this->assertSame( get_option( 'blogname' ), $title[0]['content'] );

		$desc = xml_find( $xml, 'rss', 'channel', 'description' );
		$this->assertSame( get_option( 'blogdescription' ), $desc[0]['content'] );

		$link = xml_find( $xml, 'rss', 'channel', 'link' );
		$this->assertSame( get_option( 'siteurl' ), $link[0]['content'] );

		$pubdate = xml_find( $xml, 'rss', 'channel', 'lastBuildDate' );
		$this->assertSame( strtotime( get_lastpostmodified(  ) ), strtotime( $pubdate[0]['content'] ) );

		$items = xml_find( $xml, 'rss', 'channel', 'item' );
		$this->assertSame( intval( get_option( 'posts_per_page' ) ), count( $items ) );

		$enclosures = xml_find( $xml, 'rss', 'channel', 'item', 'enclosure' );
		$this->assertSame( intval( get_option( 'posts_per_page' ) ), count( $enclosures ) );
	}
}

解説

header()対策

load_template(ABSPATH . 'wp-includes/feed-rss2.php');という部分でRSSフィード用のテンプレートを読み込んでいるが、この時にいきなり出力が始まってしまうので、出力バッファリングを使って変数に放り込む必要がある。

また、@runTestsInSeparateProcessesを入れておかないとワーニングが出てしまうので入れておくこと。

ダミーの記事を自動的に放り込む

RSSフィードのテストをするには実際に記事を放り込む必要がある。

WordPressのユニットテスト用のフレームワークには件数を指定するだけで、ダミーの記事を放り込んでくれる便利な関数がある。

$this->factory->post->create_many( 25 );

go_to()は超便利

たとえばプラグインの中で、is_feed( 'my-feed' )を使って条件分岐を行っている時に、以下のコードを入れることで、$postとか$wp_rewriteとかの値がこのURLに実際にアクセスしたのと同じ値になる。

$this->go_to( '/?feed=my-feed' );

ためしに以下のようなテストを書くとパスするはず。

$this->go_to( '/');
$this->assertSame( true, is_home() );

これは超便利!!

xml_find()でXMLに期待した要素があるかチェック

たとえば以下のコードは、rss\channel\titleといった具合にXMLを掘っていって、取得できたタイトルの値がget_option( 'blogname' )と一致しているかどうかをチェックしている。

$title = xml_find( $xml, 'rss', 'channel', 'title' );
$this->assertSame( get_option( 'blogname' ), $title[0]['content'] );

また、今回の案件では<enclosure />という要素を追加する必要があったので、以下のコードでそれがあることを確認している。

$enclosures = xml_find( $xml, 'rss', 'channel', 'item', 'enclosure' );
$this->assertSame( intval( get_option( 'posts_per_page' ) ), count( $enclosures ) );

Rewrite対策

たとえば、$this->go_to( '/feed/my-feed' );みたいなことをいきなりやってもテスト用のWordPress環境はデフォルトのパーマリンク設定なので404になってしまう。

そんな時はsetUp()に以下のようなコードをいれておくとオッケー。

update_option( 'permalink_structure', '/archives/%post_id%' );
$GLOBALS['wp_rewrite']->init();
flush_rewrite_rules();
14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?