全く JavaScript のテストを書いたことがなかったので、書いてみましたら。RSpec みたいでとてもフレンドリーでした。

mocha で Unit テストして、nightmare で E2E テストしてみたいと思います。


サンプルアプリをまずは用意します。

ボタンをクリックしていって、3の倍数のときは... FizzBuzz です。

fizzbuzz.gif


ソース

メインのコードは以下です。 div の id はテストで使います。

src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import FizzBuzzApp from './FizzBuzzApp'

ReactDOM.render(
  <FizzBuzzApp />,
  document.getElementById('root')
src/FizzBuzzApp.js
import React, { Component } from 'react'

export default class FizzBuzzApp extends Component {
  constructor(props) {
    super(props)
    this.state = {count: 0}
  }
  countUp() {
    this.setState({count: this.state.count + 1})
  }
  convertFizzBuzz(int) {
    if (int == 0) {
      return 'Click button'
    } else if ((int % 3 == 0) && (int % 5 == 0)) {
      return 'FizzBuzz'
    } else if (int % 3 == 0) {
      return 'Fizz'
    } else if (int % 5 == 0) {
      return 'Buzz'
    } else {
      return String(int)
    }
  }
  render() {
    return (
      <div>
        <h1>FizzBuzz</h1>
        <button id="button" onClick={() => this.countUp()}>Button</button>
        <div id="result" >{this.convertFizzBuzz(this.state.count)}</div>
      </div>
    )
  }
}

雛形はこちらを使っています

React の小さいアプリをつくるための starter-kit

https://github.com/mochizukikotaro/react-starter-kit/


まずは Unit テスト


mocha インストール

$ nmp i mocha -D

eslint の調整

ぼくはこれを設定しないで、atom の eslint で怒られたりしていました。it がないぞーとか describe がないぞーとかです。

.eslintrc.json
{
  "env": {
    "mocha": true
  }
}

はじめてのテスト

ファイル名はなんでも大丈夫です。

test/index.js
import assert from 'assert'

describe('addition', () => {
  it('1+1=2', () => {
    assert.equal(1+1, 2)
  })
});

rspec とそっくりですね!


はじめてのテストを実行してみる

ES2015 で書いてますので、ちょっとオプションを渡して叩きます。

$ mocha --compilers js:babel-register test/index.js

スクリーンショット 2018-04-16 21.03.29.png


つぎにメソッドのテストをする

こんな風にかけます。3 つの it がありまして、よく見ると後ろの 2 つは失敗しそうです。

test/FizzBuzzApp.js
import assert from 'assert'
import FizzBuzzApp from '../src/FizzBuzzApp'

describe('FizzBuzzApp', () => {
  const fizzBuzzApp = new FizzBuzzApp()
  describe('convertFizzBuzz', () => {

    it('return Fizz when count is 3', () => {
      assert.equal(fizzBuzzApp.convertFizzBuzz(3), 'Fizz')
    })

    it('return Fizz when count is 4', () => {
      assert.equal(fizzBuzzApp.convertFizzBuzz(4), 'Fizz')
    })

    it('return Fizz when count is 5', () => {
      assert.equal(fizzBuzzApp.convertFizzBuzz(5), 'Fizz')
    })

  });
});

そもそもアプリケーションでファイルを分割していて、 export しているので、テストが書きやすくなっている気がします。


実行してみる。

mocha --compilers js:babel-register test/FizzBuzzApp.js

無事 2 つは失敗してくれました。

スクリーンショット 2018-04-16 21.14.29.png

(あとは、適当に直しましょう。


つぎに E2E テスト


nightmare をインストール

$ npm i nightmare -D

E2E テストを書いてみる

アクセスしたら「Click button」と表示されてることをテストしてみます。

test/e2e.js
import Nightmare from 'nightmare'
import assert from 'assert'

describe('FizzBuzzApp E2E', () => {
  const nightmare = Nightmare({show: false})
  const URL = 'http://localhost:8080'

  it('アクセスしたら「Click button」と表示されていること', (done) => {
    nightmare
      .goto(URL)
      .evaluate(() => {
        return document.getElementById('result').innerText
      })
      .then((text) => {
        assert.equal(text, 'Click button')
        done()
      })
  })
})

実行

別タブで npm start しておいて。

$ mocha --compilers js:babel-register --timeout 3000  test/e2e.js

1 回クリックしたら「1」と表示されることを確認

test/e2e.js_抜粋
it('1 回クリックしたら 1 と表示されること', (done) => {
  nightmare
    .goto(URL)
    .click('#button')
    .evaluate(() => {
      return document.getElementById('result').innerText
    })
    .then((text) => {
      assert.equal(text, '1')
      done()
    })
})

15 回クリックしたら「FizzBuzz」と表示されることを確認

test/e2e.js_抜粋
  it('15 回クリックしたら FizzBuzz と表示されること', (done) => {
    nightmare
      .goto(URL)
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .click('#button')
      .evaluate(() => {
        return document.getElementById('result').innerText
      })
      .then((text) => {
        assert.equal(text, 'FizzBuzz')
        done()
      })
  })

何度も click してる...


15 回...

test/e2e.js_抜粋
it('15 回クリックしたら FizzBuzz と表示されること', (done) => {
  let page = nightmare.goto(URL)
  for(let i=0; i<15; i++) {
    page = page.click('#button')
  }
  page.evaluate(() => {
      return document.getElementById('result').innerText
    })
    .then((text) => {
      assert.equal(text, 'FizzBuzz')
      done()
    })
})

スクリーンショット 2018-04-17 11.58.10.png


以上、ありがとうございました。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.