Open21

E2Eテストのあれやこれや

nus3nus3

Next.jsプロジェクトにE2Eテストを導入したい

nus3nus3

Reactのドキュメントに出てくるライブラリはCypresspuppeteer
https://ja.reactjs.org/docs/testing-environments.html

このようなシナリオの場合は、Cypress のようなフレームワークや puppeteer のようなライブラリを使うことで、複数のルート間をナビゲートし、ブラウザのみならず、必要に応じてバックエンド側の副作用についても検証を行うことができるでしょう。

nus3nus3

cypress
テストランナだけだと無料でWebダッシュボード機能は有料っぽい

https://www.cypress.io/

nus3nus3

導入手順

  1. yarn add cypress --dev
  2. yarn run cypress open
  3. コマンド登録 "cypress:open": "cypress open"
  4. コマンド登録 "cypress:run": "cypress run"
  5. tsconfigの設定変更
  6. cypressディレクトリにisolatedModulesをfalseにしたtsconfig追加
nus3nus3

'basic_spec.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module.

exportしてないからダメだよってエラーが出る

https://stackoverflow.com/questions/56577201/why-is-isolatedmodules-error-fixed-by-any-import/56577324

cypressディレクトリにtsconfig追加しよかな

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "isolatedModules": false
  },
}
nus3nus3

いつアサーションするの→アサーションを明示的に書かなくてもアサーションしてるよ
https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#When-To-Assert

visitは200かどうかチェックしてるし、getはdomあるか見てるしtypeはtypeできるかどうか以下略・・・

cy.visit() expects the page to send text/html content with a 200 status code.
cy.request() expects the remote server to exist and provide a response.
cy.contains() expects the element with content to eventually exist in the DOM.
cy.get() expects the element to eventually exist in the DOM.
.find() also expects the element to eventually exist in the DOM.
.type() expects the element to eventually be in a typeable state.
.click() expects the element to eventually be in an actionable state.
.its() expects to eventually find a property on the current subject.

https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Default-Assertions

nus3nus3

初回のcypress openで作成されるディレクトリたち

  • fixtures テスト時のテストデータをjson形式で定義できる
  • intergration 結合テストの定義ファイル置くところ
  • plugins なんかplugin作れるんでしょう
  • support カスタムコマンドを定義できるところ
nus3nus3

jestとmocha(cypress)が混合する(テストで使うexpectとか)問題
root直下のtsconfigではcypressディレクトリをincludeしないような設定にする

例) src直下とtest直下のファイルだけコンパイル対象にしたい

tsconfig.json
{
  "exclude": ["node_modules", "deployments", ".next", "out"],
  "include": [
    "next-env.d.ts",
    "globals.d.ts",
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.js",
    "test/**/*.ts"
  ]
}

cypress直下はcypress直下のファイルだけコンパイル対象にする

cypress/tsconfig.json
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "isolatedModules": false,
    "types": ["cypress"]
  },
  "include": ["../node_modules/cypress", "./**/*.ts"]
}
nus3nus3

E2Eテスト方針

nus3nus3

どのようにcicdに組み込むか
本番環境やstg環境へのテストはどうするか?(定期的に実行するかしないかとか)

nus3nus3

TODO

  • E2Eが実行された後のvideoをどこかに残しときたい
  • エクセルファイルをアップロードする操作の実装方法
  • stagingからmainへのプルリク作成時のみにe2eテストをstaging環境にて実行するCICDの設定
nus3nus3

e2e実行時のvideoやscreenshotを通知したい
slack or プルリクのコメントに追加する?

ciでcypress実行した時に生成されたscreenshotとvideoファイルをslackで通知する感じでもよさげ

nus3nus3

circleciの設定

cypressを実行するのに必要な依存パッケージ
https://docs.cypress.io/guides/getting-started/installing-cypress.html#Linux

今回はcircleci/node:14.16.0-browsersのイメージ使ったから問題なかった

cypressのキャッシュがないとci上で動かないとの事だったのでyarn cypress:installcypress installしてる

executors:
  with_browsers:
    working_directory: /home/circleci/src/
    docker:
      - image: circleci/node:14.16.0-browsers

  e2e:
    executor: with_browsers
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: install cypress
          command: yarn cypress:install
      - run:
          name: e2e test
          command: yarn cypress:staging:run
      - store_artifacts:
          path: cypress/videos
      - store_artifacts:
          path: cypress/screenshots