Slide 1

Slide 1 text

Vuex のアプリケー ションを スナップショットテストする #v_kansai Vue.js/Nuxt Meetup #3 Masashi Hirano / @shisama

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Agenda コンポー ネントのスナップショットテスト action/mutation のスナップショットテスト

Slide 4

Slide 4 text

ユニットテスト書いていますか? 4

Slide 5

Slide 5 text

例えば、+1、-1、x2 するカウンター アプリ 5

Slide 6

Slide 6 text

コンポー ネントのコー ド
Count: {{ $store.state.count }}. + - 2x
import Vue from "vue"; import { mapActions } from "vuex"; export default Vue.extend({ methods: { ...mapActions(["increment", "decrement", "multiply"]) } }); 6

Slide 7

Slide 7 text

コンポー ネントのテスト レンダリングした結果をテストしたい DOM を一つ一つ検証するのは大変 テストコー ドを見てもどこの部分のテストかわかりづらい 7

Slide 8

Slide 8 text

スナップショットテストを使う 8

Slide 9

Slide 9 text

スナップショットテストのコー ド Jest や@vue/test-utils で使うことができる test("should render", () => { const wrapper = shallowMount(Counter, { store, localVue }); expect(wrapper).toMatchSnapshot(); }); 9

Slide 10

Slide 10 text

テスト実行後 __snapshots__ というディレクトリの中にスナップショットが生成され る 10

Slide 11

Slide 11 text

スナップショットの中身 テスト用にレンダリングした結果がスナップショットに書かれている // __snapshots__/Counter.spc.ts.snap exports[`Counter.vue should render 1`] = `
Count: 0. + - 2x
`; 11

Slide 12

Slide 12 text

もしコンポー ネントに変更があった場合
Count: {{ $store.state.count }}. - + - - + +1 + -1 2x
12

Slide 13

Slide 13 text

テストコー ドは修正が不要 テスト実行したレンダリング結果を前述のスナップショットと比較 差分があった場合はエラー になる 13

Slide 14

Slide 14 text

スナップショットの更新 スナップショットの比較の差分が意図したものだったとき -u オプションを付けて実行するとスナップショットを更新 14

Slide 15

Slide 15 text

レビュー も簡単 変更内容がわかりやすい! 15

Slide 16

Slide 16 text

スナップショットテストの良いところ UI のテスト結果がわかりやすい テストコー ドを簡潔に書ける リグレッションテストが可能 コー ドが変わってもテストコー ドの修正は不要 変更内容がわかりやすい 16

Slide 17

Slide 17 text

action/mutation のスナップショットテスト 17

Slide 18

Slide 18 text

action/mutation のスナップショットテスト action やmutation の実行結果をテストしたい 実行する前後のstate の中身がわかるようにしたい スナップショットを保存したい テストコー ドは簡潔にしたい 18

Slide 19

Slide 19 text

19

Slide 20

Slide 20 text

vuex-snapshot-test 作りました action やmutation の実行結果をテスト state の更新前後のdiff をスナップショット TypeScript をサポー ト 20

Slide 21

Slide 21 text

コー ド & 使いかた import snapshot from "vuex-snapshot-test"; import store from "@/store"; snapshot({ store, // state: 0 dispatches: [dispatch => dispatch("increment")] }); vuex-snapshot-test をimport store を渡す action をdispath する関数を配列で渡す 関数は複数指定可能 21

Slide 22

Slide 22 text

テスト実行結果 action 実行後のstate の更新前後のdiff のスナップショットを生成 exports[`store commit increment 1`] = ` "Snapshot Diff: - Before + After Object { - \\"count\\": 0, + \\"count\\": 1, }" `; 22

Slide 23

Slide 23 text

もしバグがあった場合 +1 しなければいけないけど、 間違って-1 してしまった場合 mutations: { - increment: state => state.count++, + increment: state => state.count--, decrement: state => state.count--, multiply: (state, payload) => state.count = state.count * payload.num }, 23

Slide 24

Slide 24 text

保存しているスナップショットと比較してエラー 24

Slide 25

Slide 25 text

スナップショットの更新も可能 -u を付けて実行 25

Slide 26

Slide 26 text

複数の値を持つstate のテスト 特定の値のみが変わっていることがわかりやすい 他の値が変わっていないこともわかる - Before + After Object { \\"name\\": \\"Masashi Hirano\\" - \\"id\\": \\"shisama\\", + \\"id\\": \\"shisama_\\", \\"country\\": \\"Japan\\", \\"city\\": \\"Osaka\\", ... }" 26

Slide 27

Slide 27 text

mutation をcommit することも可能 action をdispatch するだけではない mutation を直接commit するテストも書けます snapshot({ store, commits: [ commit => commit("increment"), commit => commit("decrement"), commit => commit("multiply", { num: 5 }) ] }); 27

Slide 28

Slide 28 text

initial state を指定することも可能 テスト用にstate を指定できる snapshot({ state: { counter: { value: 3 } }, mutations, tests: [ { type: "increment" } ] }); 28

Slide 29

Slide 29 text

お願い vuex-snapshot-test ぜひ使ってみてフィー ドバックください 気に入ったらスター いただけると嬉しいです Issue、PullRequest はいつでも歓迎しています 29

Slide 30

Slide 30 text

まとめ スナップショットテストはメリットが多い コンポー ネント以外でもスナップショットテストは使えます テストを書いていない人もスナップショットテストから書き始めて みてはいかがでしょうか 30

Slide 31

Slide 31 text

参考資料 スナップショットテスト · Jest どのようにredux のreducer のテストを書くか? - Qiita Jest を使用した単一ファイルコンポー ネントのテスト | Vue Test Utils 31

Slide 32

Slide 32 text

ご静聴ありがとうございました 32