v-kansai Vue.js/Nuxt.js meetup #3でスナップショットテストに関する発表をしました。 https://vuekansai.connpass.com/event/114795/
発表中に出てくるvuex-snapshot-test: https://www.npmjs.com/package/vuex-snapshot-test 参考にしたreducer-tester: https://www.npmjs.com/package/reducer-tester
Vuexのアプリケーションをスナップショットテストする#v_kansai Vue.js/Nuxt Meetup #3Masashi Hirano / @shisama
View Slide
Agendaコンポーネントのスナップショットテストaction/mutationのスナップショットテスト
ユニットテスト書いていますか?4
例えば、+1、-1、x2するカウンターアプリ5
コンポーネントのコードCount: {{ $store.state.count }}.+-2x<br/>import Vue from "vue";<br/>import { mapActions } from "vuex";<br/>export default Vue.extend({<br/>methods: {<br/>...mapActions(["increment", "decrement", "multiply"])<br/>}<br/>});<br/> 6
コンポーネントのテストレンダリングした結果をテストしたいDOMを一つ一つ検証するのは大変テストコードを見てもどこの部分のテストかわかりづらい7
スナップショットテストを使う8
スナップショットテストのコードJestや@vue/test-utilsで使うことができるtest("should render", () => {const wrapper = shallowMount(Counter, { store, localVue });expect(wrapper).toMatchSnapshot();});9
テスト実行後__snapshots__というディレクトリの中にスナップショットが生成される10
スナップショットの中身テスト用にレンダリングした結果がスナップショットに書かれている// __snapshots__/Counter.spc.ts.snapexports[`Counter.vue should render 1`] = `Count: 0.+ - 2x`;11
もしコンポーネントに変更があった場合Count: {{ $store.state.count }}.- +- -+ +1+ -12x12
テストコードは修正が不要テスト実行したレンダリング結果を前述のスナップショットと比較差分があった場合はエラーになる13
スナップショットの更新スナップショットの比較の差分が意図したものだったとき-uオプションを付けて実行するとスナップショットを更新14
レビューも簡単変更内容がわかりやすい!15
スナップショットテストの良いところUIのテスト結果がわかりやすいテストコードを簡潔に書けるリグレッションテストが可能コードが変わってもテストコードの修正は不要変更内容がわかりやすい16
action/mutationのスナップショットテスト17
action/mutationのスナップショットテストactionやmutationの実行結果をテストしたい実行する前後のstateの中身がわかるようにしたいスナップショットを保存したいテストコードは簡潔にしたい18
19
vuex-snapshot-test作りましたactionやmutationの実行結果をテストstateの更新前後のdiffをスナップショットTypeScriptをサポート20
コード &使いかたimport snapshot from "vuex-snapshot-test";import store from "@/store";snapshot({store, // state: 0dispatches: [dispatch => dispatch("increment")]});vuex-snapshot-testをimportstoreを渡すactionをdispathする関数を配列で渡す関数は複数指定可能21
テスト実行結果action実行後のstateの更新前後のdiffのスナップショットを生成exports[`store commit increment 1`] = `"Snapshot Diff:- Before+ AfterObject {- \\"count\\": 0,+ \\"count\\": 1,}"`;22
もしバグがあった場合+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
保存しているスナップショットと比較してエラー24
スナップショットの更新も可能-uを付けて実行25
複数の値を持つstateのテスト特定の値のみが変わっていることがわかりやすい他の値が変わっていないこともわかる- Before+ AfterObject {\\"name\\": \\"Masashi Hirano\\"- \\"id\\": \\"shisama\\",+ \\"id\\": \\"shisama_\\",\\"country\\": \\"Japan\\",\\"city\\": \\"Osaka\\",...}"26
mutationをcommitすることも可能actionをdispatchするだけではないmutationを直接commitするテストも書けますsnapshot({store,commits: [commit => commit("increment"),commit => commit("decrement"),commit => commit("multiply", { num: 5 })]});27
initial stateを指定することも可能テスト用にstateを指定できるsnapshot({state: {counter: {value: 3}},mutations,tests: [{type: "increment"}]});28
お願いvuex-snapshot-testぜひ使ってみてフィードバックください気に入ったらスターいただけると嬉しいですIssue、PullRequestはいつでも歓迎しています29
まとめスナップショットテストはメリットが多いコンポーネント以外でもスナップショットテストは使えますテストを書いていない人もスナップショットテストから書き始めてみてはいかがでしょうか30
参考資料スナップショットテスト · Jestどのようにreduxのreducerのテストを書くか? - QiitaJestを使用した単一ファイルコンポーネントのテスト | Vue TestUtils31
ご静聴ありがとうございました32