Cypressという癖のあるフロントエンドテストツールが面白そう

f:id:bufferings:20190713081853p:plain

## Cypress

最近、Cypressというフロントエンドテストツールを触ってみてる。ブラウザを操作して色々できる。end-to-endのテストがメインではあるかな。

www.cypress.io

コードはこんな感じ ( Writing Your First Test | Cypress Documentation より) 。読みやすい。

describe('My First Test', function() {
  it('Gets, types and asserts', function() {
    cy.visit('https://example.cypress.io')

    cy.contains('type').click()

    // Should be on a new URL which includes '/commands/actions'
    cy.url().should('include', '/commands/actions')

    // Get an input, type into it and verify that the value has been updated
    cy.get('.action-email')
      .type('fake@email.com')
      .should('have.value', 'fake@email.com')
  })
})

これだけで、waitやリトライやタイムアウトも組み込まれてる。

## 仕組み

CypressはSeleniumを使ってない。Seleniumと違ってリモートAPIで操作するのではなくて、直接JavaScriptでDOMを操作してる。面白い。

実際は、iframeで対象ページを読み込んで操作してる。なので same-origin policy を乗り越えるために裏側でごにょっとしてる。詳しくは Web Security | Cypress Documentation に書かれてる。面白い。

## 利点

利点としては

  • リモート操作じゃないから速い
  • UI経由で操作しなくても直接JavaScriptでモデルを触ったりできる

といったものや、他にも

  • wait・リトライ・タイムアウトが組み込まれてるのでテストを書くことに集中できる
  • All-In-Oneになってるからワンコマンドで環境準備ができる
  • DOMのスナップショット機能があるからテストのステップごとにどういう状況だったかを後で確認することができる
  • デバッグができる
  • APIのMockや、ObjectのSpyやStubを簡単に作ることができる

というところがある。便利。内部的には mocha, chai, sinon といったフレームワーク・ライブラリーを使ってる。

## 制約

その分制約も色々あるから注意しておきたい。

  • 1つのテストケースの中では1つのスーパードメインしか対応してない
  • 複数タブや複数ブラウザのテストはできない
  • 今の所Chromeしかサポートされてない

## 有償サービス:Cypress Dashboard

Cypress自体はOSSで無償で利用できる。んで、Cypress Dashboardというサービスが、有償の機能として提供されている。これ、便利そう。

Cypress自体にテストの録画や、失敗したときのスクリーンショットを撮る機能があるんだけど、このCypress Dashboardはテストの結果やその動画などの過去ログを管理してくれる。「このテストが失敗した」ってときに動画を見たりどの処理でエラーになったのかが分かるのは便利そう。

www.cypress.io

個人で使う分には無料のSeedプランで大丈夫かな。OSS用の無料プランもある。

https://www.cypress.io/pricing

## こだわり

公式ドキュメントを一通り読んでみたんだけど、end-to-endのテストに対するこだわりがしっかりあって、それを実現するために色々な制約を受け入れて割り切っている、という感じ。良い。

## 自分の感想

スピードが速いのは素晴らしいんだけど、それだけだとSeleniumじゃなくてCypressを使う強い動機には、僕はならないなと思った。Seleniumだと複数ブラウザに対応してるし、ユーザー操作を再現できるし、あんまりトリックがないし。安心。

だけど、SPAとかみたいにクライアント側で色々やるアプリケーションだと、その裏側をJSで直接簡単に操作したり、DOMのイベントを直接Listenしたりできるのは便利そう。なので、Cypressを使うならそういうところかなと思った。

ということで、LTで、元々はGebの話でもしようかと思ってたんだけど、Cypressの紹介をすることにした。(๑•̀ㅂ•́)و✧

seleniumjp.connpass.com