0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

jestのsnapshotでテストの運用コストを削減する

Last updated at Posted at 2025-01-23

概要

node.jsでintegrationテストを運用しているのですが、運用していて仕様変更等によりレスポンスの変更が発生します。
小さな変更でも多くのテストコードを修正していたのですが、メンテナンス性を考えてsnapshotテストを運用するようにしました。
今回はそのメリット・デメリット含めて実際に感じたことを書いていこうと思います

snap shotテスト導入のきっかけ

普段integrationのテストを実装する際にちょっとしたレスポンスの変更に対しても各ケースで値の状態を検証するコードを直す必要があり、テストケースが増えることによりテストコードの修正コストが大きくなったためです

やってみよう

それでは早速やっていきたいと思います

snapshotを使わないテスト

describe('/api/v1/sample2', () => {
	it('get message', async () => {
		const response = await request(app).get('/api/v1/sample');

		// response bodyの確認
        // このレスポンスの中身が増えたり、値が変わったりした場合の検証が大変
        expect(response.body).toEqual({
            "_id": "67922c0e4fee2d8abbbb292d",
            "index": 0,
            "guid": "07e645ac-c31f-4353-9721-9bccfb6a77ef",
            "isActive": false,
            "balance": "$1,520.47",
            ...中略
            "tags": [
        			...中略
            ],
            "friends": [
        			...中略
            ],
        });
	});
})

実装を見るだけだとあまり感じませんが、レスポンスが増えたり、テストケースが多い場合だとそれだけ修正コストがかかってきます

snapshotテストを使った場合

snapshoテストについて見ていきたいと思います。
ちなみにjestでsnapshotを出力するにはtoMatchSnapshot()を呼ぶことによりsnapshotが出力されるようになります

describe('/api/v1/sample2', () => {
	it('get message', async () => {
		const response = await request(app).get('/api/v1/sample');

		// 出力したsnap shotがマッチしているかを確認
		expect(response.body).toMatchSnapshot();
	});
})

この方法だとレスポンスを追加した場合であってもsnap shotの更新だけで済むので運用コスト的には軽く済みます。
出力されるsnap shotは下記のような形

exports[`/api/v1/sample2 get message 1`] = `
{
    "_id": "67922c0e4fee2d8abbbb292d",
    "index": 0,
    "guid": "07e645ac-c31f-4353-9721-9bccfb6a77ef",
    "isActive": false,
    "balance": "$1,520.47",
    ...中略
    "tags": [
            ...中略
    ],
    "friends": [
            ...中略
    ],
}`;

このように、snap shotからどういったレスポンスが返るのかが確認できるため、レビュー時にはこのsnap shotをベースにレビューができるといったようなメリットもあります。

snap shotテストで運用するデメリット

snap shotテストは手軽に取り入れることができるのと、運用コストが軽く済むのはいいことですがもちろんデメリットもあります。
デメリットとしては実装者がsnap shotを作業的に更新するだけになってしまいがちなこと
またレビュワーもsnap shotの変更の確認漏れが起こってしまいがちになってしまうことです。
対応策としてやってみたこととしては、テストの実装観点として正常系を期待しているのか、異常系を期待しているのかはテストで実装(assertion)するようにしています。

describe('/api/v1/sample2', () => {
	it('get message', async () => {
		const response = await request(app).get('/api/v1/sample');
		
        // 正常かどうかを確認するためステータスチェックは入れる
		expect(response.status).toBe(200);
        
		expect(response.body).toMatchSnapshot();
	});
})

最後に

自動テストは素晴らしいツールですが、アプリケーションの規模が大きくなるにつれ運用のコストが上がってしまうことも少なくありません。
こういったものを活用してより運用コストを下げつつもちゃんとしたテストのプロセスを回していける状態にしたいですね。
ではでは

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?