Vue meetupでテスト書いている人が少なかったのでオレオレテストを晒してみる Part. 1

# Vue meetupでテスト書いている人が少なかったのでオレオレテストを晒してみる Part. 1

[Vue.js ではじめるシングルページアプリケーションの開発 - HDE BLOG](http://blog.hde.co.jp/entry/2018/03/05/130121)

みなさん Vue.js Tokyo v-meetup #7 お疲れ様でした！！kazuponさんを始めスタッフのおかげで、100人くらいの募集に300人近くの募集が来て、当日は98%(くらい?)の参加率という異例の盛り上がりを見せているVue.js界隈でしたね！！！

当日の様子はkazuponさんがとぅぎゃったー(?)でまとめているので楽しそうな雰囲気が伝わるかと思います。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">「Vue.js v-meetup #7 のTweets まとめ」をトゥギャりました。 <a href="https://t.co/pBeur6B9z1">https://t.co/pBeur6B9z1</a></p>&mdash; 🐤kazupon🐤 (@kazu_pon) <a href="https://twitter.com/kazu_pon/status/999449269722468352?ref_src=twsrc%5Etfw">2018年5月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


テストユーザーとして個人的に一番大好きなLTははりぼてさんのSnapshotによるSVGのテスト [SVG makes your components to testable ] です！！！（私のアイコンはAutocordに対して、はりぼてさんはハッセルで好感度Maxでした）

ただそのときのLTで「私テストやってます」って自信持って手をあげている人が少なかったのが印象的でした😇

なのでVueで簡単なテストのサンプルを書いていくので時間ある方はちょっとずつテストいれていきましょう！！！

> twadaがよく引用するやつを引用しておく（二重引用）
> 
> テストを書く時間がないのではなく、テストを書かないから時間がなくなるのです。 
> 
> by [James Grenning(@jwgrenning) | Twitter](https://twitter.com/jwgrenning)

## 環境とアプリの構築

とりあえずこの段階で必要なものは

- node
- npm
- vue-cli
  - `sudo npm install -g vue-cli`

とします。

バージョン確認（なかったら必要に応じてインストールしてください。）

```console
$ node -v
v10.1.0
$ npm -v
5.6.0
$ vue -V
2.9.3
```

次はVueアプリの作成

```console
$ vue init webpack-simple vue-test-sample
# この後とりあえず全部Enterでもいいかと思います。
```

`To get started:` とメッセージが出てくるので、その指示に従って以下のコマンドを打ちます。

```console
$ cd vue-test-sample
$ npm install
$ npm run dev
```

<img width="1131" alt="スクリーンショット 2018-05-25 0.04.10.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/112929/e1b74aa9-3ed3-72f2-5c1b-0a5a6144ddb4.jpeg">

サンプルアプリケーションが立ち上がりましたのですぐに `vue-test-utils` と `jest` とかの必要なパッケージを入れましょう！

この[Jest を使用した単一ファイルコンポーネントのテスト](https://vue-test-utils.vuejs.org/ja/guides/#jest-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E5%8D%98%E4%B8%80%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88)を見ながらやるといれれます。

```shell
npm install --save-dev jest @vue/test-utils vue-jest babel-jest jest-serializer-vue
```

vue-test-utilsのドキュメント https://vue-test-utils.vuejs.org/ja/

> Jestは、テスト対象のコードのすぐ隣に__tests__ディレクトリを作成することを推奨していますが、適切にテストを構造化することは自由です。 Jestがスナップショットテストを実行するテストファイルの隣に__snapshots__ディレクトリを作成することに注意してください。

`App.vue` をテストする場合は同じ階層に `__tests__` というフォルダを作ってそこにテストを入れるのが一般的です。

```
$ tree
├── package-lock.json
├── package.json
├── src
│   ├── App.vue
│   ├── __tests__
│   ├── assets
│   └── main.js
└── webpack.config.js
```

```
$ cd src
$ tree -L 2
.
├── App.vue
├── __tests__
│   └── App.test.js

```

こんな感じで `App.test.js` ファイルを作成します。

```App.test.js
describe('Counter', () => {

  it('run test !!!!!!!!!', () => {
    expect(1).toBe(1)
  })
})
```

ここでgitの差分だけHot reloadでテストしてくれるやり方を紹介すると

```console
$ git add .
$ git commit -m "Init vue-test-app"
# App.test.jsファイルを編集する (空白文字とかでもよし)
$ yarn jest --watch
# npmだと --watchが動かないキガスル
```

最初は `› Press Enter to trigger a test run.` と出てるので`Enter`を押してあげてください。そうするとこんな感じで差分があるファイルだけ永遠とテストしてくれるので便利です。

<img width="787" alt="スクリーンショット 2018-05-25 1.51.06.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/112929/7d9af87f-e06e-486b-33da-d80be16ff1a7.jpeg">


とりあえず一旦ここまでにしますがテスト導入お疲れ様でした〜！！！！

少しずつテスト増やしていけるチーム作っていきたいですね〜！！

## snapshotテストを追加してみる（マークアップを保存して差分を見れくれる）

```App.test.js
import { shallowMount } from '@vue/test-utils'
import App from '../App.vue'

describe('App.vue', () => {
  it('renders the correct markup', () => {
    const app = shallowMount(App)

    expect(app).toMatchSnapshot() // これだけでスナップショットが作成されます！！！簡単！！
  })
})
```

`__snapshots__` フォルダが作成されています。

```shell-session
yk:vue-test-sample yk$ cd src/
yk:src yk$ tree -L 2
.
├── App.vue
├── __tests__
│   ├── App.test.js
│   └── __snapshots__
├── assets
│   └── logo.png
└── main.js

```

これをしておくと

<img width="1061" alt="スクリーンショット 2018-05-25 2.08.30.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/112929/69bdf480-1d3d-9894-787f-3c37d6d5aaad.jpeg">

予期せぬときに `文字を赤色にしちゃった` 的な意図せぬ変更が検知できます。

```html
<li><a href="https://vuejs.org" style="color:red;" target="_blank">Core Docs</a></li>
```

`style="color:red;"`に反応して

<img width="420" alt="スクリーンショット 2018-05-25 2.11.07.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/112929/e26190df-457b-9734-35a4-ea67d15bc432.jpeg">

差分を検知して `色が赤になってるけど大丈夫？` って聞いてくれます！便利！！

もちろんマークアップの上書きも簡単で

```shell-session
 › 1 snapshot test failed in 1 test suite. Inspect your code changes or press `u` to update them.
```

言葉の通り `u` を押すだけです。そしたらAll green testになります〜

## スナップショットを導入するとき（弊社の場合）

参考になるかまったくわからないのですが（macのプレビューでやっつけで作った図）

<img width="1061" alt="スクリーンショット 2018-05-25 2.08.30.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/112929/2e314081-4958-b0b8-e978-078fdc1030db.jpeg">

- componentsをまとめているcontainer的な要素はsnapshot取らなかったりします
  - 代わりにロジックのテストはしっかり書きます
- containerの中の更に小さいcomponentsはpropsを渡す、もしくはemitするだけの構成にして、Snapshotメインのテストを書いたりします
    - 親からのpropsは`propsData`的なので簡単にstubsを作れるので楽です〜

弊社はロジック層とビュー層を意識的に分けてテストしていますが、他にも会社やチームで最適なテストの書き方を見つけるといいかと思います。Rspecとかの歴史にくらべてフロントエンドのテストはまだ歴史も浅く、ベスト・プラクティスが少なめ（ベタープラクティス?）なので、良い書き方・知恵があれば、みなさんQiitaとかに投稿して知見ためていきましょう〜〜

## まとめ

- vue-test-utils使ってみよう！！
- Snapshotはマークアップの意図しない変更をキャッチしてくれるよ！！
- テストは文化である。文化は時間をかけて醸造していくものである。

以上。読んでくれてありがとうございました〜〜！！！

p.s. 最近Meetupのときつぶやきたいがためにツイッターを始めたのでフォローしろください（ https://twitter.com/yk_hirao ）