HugoのE2EをCypressでやってみた

Photo by Ferenc Almasi on Unsplash

このブログにCIとしてE2EテストフレームワークのCypressを入れてみた。 他のテストフレームワークを試してはいないが

くらいで選定した。

構成

今回はGitHub ActionsでCIを実行。Cypressをインストールするだけでローカルサーバも起動されテストがすぐにできる。 しかし、GitHub Actionsで実行する場合は、別途テストサーバを起動する必要があるため、 start-server-and-test をインストールして利用設定が必要。

npm install cypress start-server-and-test --save-dev

GitHub Actionsでサーバ起動するためのscriptを定義しておく

  "scripts": {
    "start-server": "npx serve public -p 1313",
    "cy:run": "npx cypress run",
    "ci": "start-server-and-test start-server http://localhost:1313 cy:run"
  },

GitHub Actions側は以下。cypress-io/github-action@v2build でHugoのビルドを実施。startでサーバを起動。wait-onでテストサーバ起動を待機させる。

jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2
        with:
          submodules: true  # Fetch Hugo themes
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '14.x'

      - name: Cache dependencies
        uses: actions/cache@v2
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-            

      - name: Install dependencies
        run: npm ci

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: '0.83.0'
          extended: true

      - name: Cypress run
        uses: cypress-io/github-action@v2
        with:
          build: npm run build:prod
          start: npm run ci
          wait-on: 'http://localhost:1313'

Cypress設定

cypress.json を以下のように設定。cypressリソースとテストファイルのディレクトリを分けたかったのでディレクトリ設定を追加。 Timeout系はデフォルト値長い印象があったので短くした。CIの時間短縮したいのでデフォルトスクリーンショットや動画取得をOFF。ほしいときに取得する形にした。

{
  "baseUrl": "http://localhost:1313",
  "pageLoadTimeout": 15000,
  "requestTimeout": 10000,
  "responseTimeout": 15000,
  "integrationFolder": "tests/integration",
  "downloadsFolder": "cypress/downloads",
  "screenshotsFolder": "cypress/screenshots",
  "supportFile": "cypress/support/index.js",
  "testFiles": "**/*.*",
  "videosFolder": "cypress/videos",
  "screenshotOnRunFailure": false,
  "video": false
}

E2Eテスト

テストを少し書いてから、Cypressのベストプラクティスというドキュメントを発見したので読んでみた。

Best Practices - Cypress Documentation

最初テストは既存のCSSクラスなどをセレクターで探してテストするようにしていたが、ベストプラクティスにテスト用の data-* 属性を設定してマークアップに依存しない書き方がよいと書かれていたので data-cy 属性を利用してテストするように書き直した。

たとえばHTMLは

<h1 data-cy="title">タイトルです</h1>

テストは

cy.get('[data-cy="title"]').should('contain', 'タイトル')

という感じ。これだとマークアップやスタイルを変えてもE2Eに大きな影響がなくて安心。

まとめ

HugoのE2E CIを導入してみた。GitHub Actionsで実行できるようにするための調整に時間がかかったが比較的素早く導入できた。 ベストプラクティスドキュメントがCypressの公式ドキュメントに記載されているのはとても助かった。

See Also