Next.jsでつくった多言語サイトテンプレートをCypressでテストする
GAOGAOアドベントカレンダー「今年もGAOGAOまつりです Advent Calendar 2022」 の20日目の記事です。
今回は、NextJSで作成した、多言語サイト用のテンプレートにCypressテストを導入した記事を書きます。
テスト戦略の考え方としては、テスティングピラミッド、テスティングトロフィー等の考え方が広く知られています。これらの考え方は、ユニットテスト、インテグレーションテストを重視し、コストのかかるE2Eテストは極力重要な部分に絞り込みましょうというスタンスが主流かと思います。
一方、チャンネル登録者数114万人のプログラミング系Youtuberのカイルさんは、E2Eテストは昔とくらべてかきやすくなったので、ユニットテスト、インテグレーションテストよりも、E2Eテストをどんどん書いていきましょうというスタンスを表明されており、新鮮に感じました。
Now lot of people that share my opinion this say that you should take that extra time and write a bunchi of integration tests. I think that’s fine but honestly I prefer end-to-end test over integration test.
Stop Writing So Many Test (Youtube動画)
カイルさんの動画に影響をうけて、私も頑張って、Cypressのテストを書いていきたいと思います。
まず、テスト対象のサイトと、テストシナリオを整理します。
テスト対象のサイト
以前の記事で紹介した、日、英、中参加国対応の多言語サイトテンプレートになります。
テストシナリオ
ロケール毎(日、英、中)に、正しく言語切り替えが行われてるか確認する。
確認対象は、トップページ、記事一覧ページ、記事詳細ページ
言語の切替については、以下の方針をとります。
1)ユーザーは言語毎のURLにアクセスし、それに応じて適正な言語コンテンツが表示されるか確認する。
2)ユーザーはルートURLにアクセスし、ブラウザの言語設定に応じて、適正な言語コンテンツが表示されるか確認する。
1)の言語毎のURLで切り替えるタイプのテストコード。
it('by url routing - en', () => {
// Top Page
cy.visit('/en-US')
cy.get('h1>span').should('have.text', 'Multilingual Site')
// News List Page
cy.get('ul > :nth-child(1) > a').click()
cy.get('h1').should('have.text', 'News List')
// News Article Page
cy.get('main >div > a.newsLink:nth-child(1)').click()
cy.get('h2').should('have.text', 'I, myself, am a cat.')
})
2)のブラウザの言語設定で切り替えるタイプのテストコード
cy.visitの第二引数で、onBeforeLoadメソッドを使用し、訪問先のwindowオブジェクトを取得。
そして、Object.definePropertyでブラウザの言語を設定します。
関連ドキュメント
・cy.visitの引数:cypress公式
・Object.defineProperty():MDN
it('English Locale Test', () => {
cy.visit('/', {
onBeforeLoad(window) {
Object.defineProperty(window.navigator, 'language', { value: 'en-US' })
Object.defineProperty(window.navigator, 'languages', { value: ['en'] })
Object.defineProperty(window.navigator, 'accept_languages', { value: ['en'] })
},
headers: {
'Accept-Language': 'en'
}
})
cy.get('h1>span').should('have.text', 'Multilingual Site')
// News List Page
cy.get('ul > :nth-child(1) > a').click()
cy.get('h1').should('have.text', 'News List')
// News Article Page
cy.get('main >div > a.newsLink:nth-child(1)').click()
cy.get('h2').should('have.text', 'I, myself, am a cat.')
})
stack overflowの記事も参考になります。いろいろな手法がディスカッションされています。
以上になります、皆様良いクリスマス、良いお年をお迎えください。
Discussion