Cypress導入経緯と実例

センシンロボティクス開発部の鄒です。

# アジェンダ
1.エンドツーエンド (E2E) テスト比べる
2.Cypress重要な観念
3.Cucumber導入
4.結論とメリット

# エンドツーエンド (E2E) テスト比べる

## 比べる方法

**一番目ポイント：どのくらい人は使ってる**
*npmとかgithubとかに確認*

一つツールを導入するときに、どのぐらいエンジニアを使っているのも大事です。
どうしてそう言うと、つまり、もし、問題がある時にネットで解決方法がある可能性が高いです。

例えば、npmの状況に見ると、Cypress、Selenium、Puppeteerが人気ですね。

![npm download comparison chart](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596658/20d06234-0018-60d9-3032-27c2ec2c9e12.png)

![npm download comparison table](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596658/10aa4146-3df6-8c78-b5e2-5f5aba982969.png)




あと、もしツールはオープンソースなら、Githubの状況も確認した方が良いと思います。

Cypressのstarは25.2K、TestCafeのstarは8.6K
Cypressのopen issueは1363 open, 5463 closed
TestCafeのopen issueは494 open, 2790 closed



つまり、Cypressもっと人気ですが、TestCafeはもっとissueを解決しています。

**二番目ポイント：専門会社の分析**

ThoughtWorksっていう会社は定期的に技術のレポート「Technology Radar」を発表します。
Cypressは二回入りました。TestCafeは一回しかない。



**三番目ポイント：機能比べる**

| 項目 | Cypress | TestCafe | Selenium |
|:----------:|:-----------:|:------------:|:------------:|
| 環境構築    | 簡単        | 簡単         | 難しい         |
| ブラウザ     | 多様      | 多様       | 多様       |
| 歴史       | 2015        | 2015         | 2004       |
| 原理        | async          | async           |  block wait      |

# Cypress重要な観念

昔Seleniumを使った時にエレメントをローディングために、よくwait(秒数)を使った。でも、失敗したら、retryしなかった。
Cypressでは、4秒以内にretryしています。なので、特別なwait(秒数)はいらなくなった。
そして、秒数を増えるのも可能です。

```
cy.get('#email', {timeout: 15000})
```

# Cucumber導入

Cucumberを導入するとテストケースは理解しやすくなります。

**ディレクトリの構築**

Cypressのディレクトリ

- integration
    - login.spec.js



Cucumberのディレクトリ

- integration
    - login.feature
    - login
        - login.js

**コードの実例**

Cypressの例

login.spec.js

```
context('ログイン画面', () => {
    beforeEach(() => {
      cy.visit(Cypress.env('sensyn_host') + 'login#/')
      cy.fixture('user.json').as('usersData')   
    })
  
    it('登録していないアカウントでログイン', () => {
      cy.get('@usersData').then(user => {
        cy.get('#email')
          .type(user.wrong_email).should('have.value', user.wrong_email)
        cy.get('#password')
          .type(user.wrong_password)
      })
  
      cy.get('.btn-default').click()
      cy.get('.alert-danger').should('contain', 'ログインに失敗しました。');
    })
  })
```


Cucumberの例

login.feature

```
Feature: アカウント
Description: ログイン、ログアウト機能

Background: ログイン画面に移行
  Given ログイン画面に移行
  Then ログイン画面になる

/* Case 1 */
Scenario: 登録していないアカウントでログイン
  Given 登録していないアカウントを入力
  When ログインボタンをクリック
  Then ログインエラーが表示される
```

login.js

```
import { Given, When, And, Then } from "cypress-cucumber-preprocessor/steps";

Given('ログイン画面に移行', () => {
    cy.visit(Cypress.env('sensyn_host') + 'login/')
})
Then(`ログイン画面になる`, () => {
  cy.url().should('eq', Cypress.env('sensyn_host') + 'login/')
})

Given(`登録していないアカウントを入力`, () => {
  cy.fixture('user.json').as('usersData')
  cy.get('@usersData').then(user => {
    cy.get('#email')
      .type(user.wrong_email).should('have.value', user.wrong_email)
    cy.get('#password')
      .type(user.wrong_password)
  })
})
When(`ログインボタンをクリック`, () => {
  cy.get('.btn-default').click()
})
Then(`ログインエラーが表示される`, () => {
  cy.get('.alert-danger').should('contain', 'ログインに失敗しました。');
})
```

# 結論とメリット

Cypressの導入はとても便利です。基本機能の品質は上がります。レコーディングのプラグインもあるので、開発時に使って早くなると思います。

TestCafeには開発IDE（有料）があって、レコーディング機能も使えるので、開発ははやくなるそうかもしれない。

結論としては、どちらても、リリースの品質が高くなると思います。

# Ref
* [npm Trend](https://www.npmtrends.com/cypress-vs-testcafe-vs-nightwatch-vs-puppeteer-vs-selenium-webdriver)
* [Cypress Github](https://github.com/cypress-io/cypress/issues)
* [TestCafe Github](https://github.com/DevExpress/testcafe)
* [thoughtworks radar](https://www.thoughtworks.com/radar)