Slide 1

Slide 1 text

Test mockを Snapshot testする 2023-09-14 ひむら ともひこ

Slide 2

Slide 2 text

自己紹介 ひむら ともひこ 最近遊びたいこと(希望) ● 要求管理の仕組みをつくって遊びたい ● さらっとリリースバーンアップが書けるツールつくって遊びたい

Slide 3

Slide 3 text

最近の自分のちょっとした 課題を解決したいだけの人生だった

Slide 4

Slide 4 text

概要 Test MockをSnapshot testする ● なぜ Test MockをSnapshot testするか ● Test Mockとは ● Snapshot testとは ● Test MockをSnapshot testしてみる

Slide 5

Slide 5 text

なぜTest mockをSnapshot testするか

Slide 6

Slide 6 text

ちょっと楽しいから

Slide 7

Slide 7 text

別にやらなくていい

Slide 8

Slide 8 text

もしかしたら 考え方の幅が広がるかも ぐらいの小ネタです

Slide 9

Slide 9 text

Test mockとはなにか

Slide 10

Slide 10 text

みんな大好き(?) Mockオブジェクト

Slide 11

Slide 11 text

Test mockとは何か 単体テストをする際などに、 テスト対象から外部への呼び出しを正しく行ってい るか検証するためのオブジェクト 呼び出されたメソッドやその引数を記録している。 (呼び出し記録自体はTest spyでも行うが検証する場 合はMockと呼ばれる)

Slide 12

Slide 12 text

具体例

Slide 13

Slide 13 text

Test mock - Jestを使った例 ● JestはJavaScriptで使われるテスティングフレームワーク ● Test mockになっている関数を作る機能がある(mock関数) ● mock関数の呼び出しはmockプロパティに記録される const say = jest.fn() // mock関数 sayを作成している。 sayは呼び出せる say(‘hello’) // 引数 Helloで呼び出す say(‘bye’) // 引数 byeで呼び出す console.log(say.mock) /* ~> { calls: [ [ 'Hello' ], [ 'bye' ] ], // 引数 Helloとbyeで呼び出しがあった contexts: [ undefined, undefined ], // 実行環境の情報 instances: [ undefined, undefined ], invocationCallOrder: [ 1, 2 ], results: [ // 各呼び出しの戻り値の情報 { type: 'return', value: undefined }, { type: 'return', value: undefined } ], lastCall: [ 'bye' ] } */

Slide 14

Slide 14 text

say関数を検証する例 expect(say.mock.calls.length).toBe(2) // 2回呼び出されたことを検証する expect(say.mock.calls[0].toEqual([‘Hello’]) // 1回目の呼び出しの引数を検証する

Slide 15

Slide 15 text

Snapshot testとはなにか

Slide 16

Slide 16 text

みんな大好き(?) 期待値の自動生成ができる

Slide 17

Slide 17 text

Snapshot testとはなにか ● 初回はテスト対象の出力を保存する ● 2回目以降は保存した出力と比較する ● 意図しない変更を検知するのに役立つテクニック

Slide 18

Slide 18 text

具体例

Slide 19

Slide 19 text

Snapshot test - Jestを使った例 test(“Snapshot Testの例”, () => { const output = { calls: [‘hello’] } // 関数の出力とする expect(output).toMatchSnapshot() // まだ出力を保存していない場合は保存する }); /* __snapshot__ ディレクトリにファイル名に .snap をつけたファイルに以下が保存される // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Snapshot Testの例 1`] = ` { "calls": [ "hello", ], } `; */

Slide 20

Slide 20 text

Snapshot Testの例 test(“Snapshot Testの例”, () => { const output = { calls: [‘bye’] } // 関数の出力とする値をわざと変更する expect(output).toMatchSnapshot() // 出力が保存済みなので、保存された結果と比較 }); /* – 実行時の出力 Error: expect(received).toMatchSnapshot() Snapshot name: `Snapshot Testの例 1` { "calls": [ - "hello", + "bye", ], }

Slide 21

Slide 21 text

Test mockをSnapshot testしてみる

Slide 22

Slide 22 text

説明する必要があるだろうか…

Slide 23

Slide 23 text

Test mockをSnapshot testする function greeting(say) { say(‘hello’); say(‘bye’); } test(‘greeting’, () => { const say = jest.fn(); greeting(say); expect(say.mock).toMatchSnapshot(); });

Slide 24

Slide 24 text

Test mockをSnapshot testする - 処理を変更 function greeting(say) { say(‘こにゃにゃちわー’); say(‘ほなら’); } test(‘greeting’, () => { const say = jest.fn(); greeting(say); expect(say.mock).toMatchSnapshot(); });

Slide 25

Slide 25 text

Test mockをsnapshot testする - 実行してみる Snapshot name: `greeting 1` - Snapshot - 3 + Received + 3 @@ -1,12 +1,12 @@ { "calls": [ [ - "hello", + "こにゃにゃちわー ", ], [ - "bye", + "ほなら", ], ], "contexts": [ undefined, undefined, @@ -18,11 +18,11 @@ "invocationCallOrder": [ 1, 2, ], "lastCall": [ - "bye", + "ほなら", ], "results": [ { "type": "return", "value": undefined,

Slide 26

Slide 26 text

Test mockをSnapshot testするの用途 ● 自動テスト書かれていないコードのさくっと自動テストをつくる ○ リファクタリングに役に立つ ● mockを使いたいが丁寧に検証するのが面倒なとき ○ 手抜きだけど、ないよりはましな場合がある ● 丁寧に検証する前の確認として ○ mockプロパティみたほうがはやくないか?

Slide 27

Slide 27 text

Jest以外でどうやるか ● 調べてない ● 調べかけてたけど、やりやすい環境がそもそも他に… ● そのため、このネタはお蔵入りした

Slide 28

Slide 28 text

まとめ

Slide 29

Slide 29 text

まとめ Test mockをSnapshot testする ● Test mock ○ 期待どおりメソッドや関数が呼び出されるか確認するためのテク ● Snapshot test ○ 実行結果を保存し、テストの期待値とするテク ● Test mockをSnapshot testする ○ mockに対して呼び出しに変化ないか簡単にテストできるテク