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();