🏂

CypressでRSSなどのXMLをテストする

2022/03/06に公開

CypressでRSSやsitemapなどのXML形式の出力をテストする機会があったのでその方法を簡単に残しておきます。

XMLの文字列からXMLDocumentを取得する

リクエスト先のXMLページが意図した内容になっているかどうかを文字列のままでテストするのは大変です。はじめに文字列からXMLDocumentオブジェクトを生成しておけば、document.querySelector()などのメソッドを使って楽にテストを書くことができます。

文字列からXMLDocumentを取得するにはDOMParserparseFromString()を使います。モダンブラウザで標準でサポートされているためライブラリ等は不要です。

Cypressの場合には以下のようにXMLのURLにアクセスしたうえでXMLDocumentを取得すれば良いかと思います。

const parser = new DOMParser();

cy.request('xmlページのURL').then((res) => {
  const doc = parser.parseFromString(res.body, 'application/xml');
});

実際にRSSのテストを書いてみる

例えば以下のようなRSSのページがあるとします。

/rss.xml
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
  <title>RSSのタイトル</title>
  <description>RSSの説明</description>
  <link>https://example.com</link>
  <item>
    <title>item0のタイトル</title>
    <description>item0の説明</description>
    <link>http://example.com/item0</link>
    <pubDate>Fri, 04 Mar 2022 02:10:52 GMT</pubDate>
  </item>
  <item>
    <title>item1のタイトル</title>
    <description>item1の説明</description>
    <link>http://example.com/item1</link>
    <pubDate>Fri, 04 Mar 2022 02:10:52 GMT</pubDate>
  </item>
…略…

このRSSの内容が意図したものになっているかどうかの簡単なテストをCypressで書いてみます。

rss.spec.ts
const parser = new DOMParser();

it('RSSが適切に出力されている', () => {
  cy.request('/rss.xml').then((res) => {
    const doc = parser.parseFromString(res.body, 'application/xml');
    // titleが適切か
    expect(doc.querySelector('channel > title')?.textContent).to.eq('RSSのタイトル');
    // linkのURLは適切か
    expect(doc.querySelector('channel > link')?.textContent).to.eq('https://example.com');
    // 各itemをテストするためにitemを一覧で取得する
    const items = doc.querySelectorAll('item');
    // itemの数は適切か
    expect(items.length).to.eq(2);
    // 1つめのitemのtitleに適切な文字列が含まれているか
    expect(items[0].querySelector('title')?.textContent).to.contain('item0のタイトル')
   // 2つめのitemのtitleに適切な文字列が含まれているか
    expect(items[1].querySelector('title')?.textContent).to.contain('item1のタイトル');
  });
});

こんな感じでXMLであってもHTMLと同じようにテストができます。

余談ですが、出力内容がRSSの標準規格に則っているかどうかはW3CのFeed Validation Serviceでチェックするのが良さそうです。APIがあるとのことなので、このチェックもGitHub Actionsなどで自動化できないか今度試してみようと思います。

Discussion