JestのSnapshot Serializerを利用してAWS CDKのスナップショットテストのアセットの差分を無視する
こんにちは。サービスグループの武田です。
先日、AWS CDKのスナップショットテストで発生するアセットの差分を無視する方法を紹介しました。
これを見た同僚から、別の方法もあるよ!と教えてもらったので調べてやってみました。
Snapshot Serializerを利用する
AWS CDKのユニットテストはライブラリとしてJestが利用されています。実はJestにはシリアライズ用のモジュールを追加する機能があり、これを利用することでハッシュ値の出力を操作できます。
モジュールの追加方法は次の2種類が提供されています。
jest.config
のsnapshotSerializers
に指定する- 各テストケースで
expect.addSnapshotSerializer
を呼んで追加する
1は複数のテストケースで共有したい場合に便利です。2はテストケースごとにモジュールを切り替えたい場合などに便利です。今回は設定ファイルで設定する1の方法を試してみました。
ベースとなるプロジェクトは前述のエントリで作成したものを利用します。実際に試してみたい方は前述のエントリを参考にしてみてください。
やってみた
まずはモジュールを定義します。
module.exports = { test: (val: any) => typeof val === 'string', serialize: (val: any) => { return `"${val.replace(/AssetParameters([A-Fa-f0-9]{64})(\w+)|(\w+) (\w+) for asset\s?(version)?\s?"([A-Fa-f0-9]{64})"/, '[HASH REMOVED]')}"`; }, };
このモジュールを使用するように、設定ファイルを編集します。
module.exports = { roots: ['<rootDir>/test'], testMatch: ['**/*.test.ts'], transform: { '^.+\\.tsx?$': 'ts-jest' }, snapshotSerializers: ['<rootDir>/test/snapshot-plugin.ts'] };
最後にテストケースを次のように変更します。すっきりしていますね。
import '@aws-cdk/assert/jest'; import { SynthUtils } from '@aws-cdk/assert'; import * as cdk from '@aws-cdk/core'; import * as CdkIgnoreTestAssets from '../lib/cdk-ignore-test-assets-stack'; test('Snapshot Test', () => { const app = new cdk.App(); const stack = new CdkIgnoreTestAssets.CdkIgnoreTestAssetsStack(app, 'cdkIgnoreTestAssetsStack'); expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); });
モジュールの有無によるスナップショットの差分は次のようになりました。
@@ -1,17 +1,17 @@ Object { "Parameters": Object { - "AssetParametersbca73d9caf09b131f3b33cc87844d2707c6ac9c9abc18644c670eec939b26496ArtifactHashFAEC5CD3": Object { - "Description": "Artifact hash for asset \"bca73d9caf09b131f3b33cc87844d2707c6ac9c9abc18644c670eec939b26496\"", + "[HASH REMOVED]": Object { + "Description": "[HASH REMOVED]", "Type": "String", }, - "AssetParametersbca73d9caf09b131f3b33cc87844d2707c6ac9c9abc18644c670eec939b26496S3Bucket170AB6D6": Object { - "Description": "S3 bucket for asset \"bca73d9caf09b131f3b33cc87844d2707c6ac9c9abc18644c670eec939b26496\"", + "[HASH REMOVED]": Object { + "Description": "[HASH REMOVED]", "Type": "String", }, - "AssetParametersbca73d9caf09b131f3b33cc87844d2707c6ac9c9abc18644c670eec939b26496S3VersionKeyF774BA74": Object { - "Description": "S3 key for asset version \"bca73d9caf09b131f3b33cc87844d2707c6ac9c9abc18644c670eec939b26496\"", + "[HASH REMOVED]": Object { + "Description": "[HASH REMOVED]", "Type": "String", }, }, "Resources": Object { "LambdaFunctionBF21E41F": Object { @@ -19,11 +19,11 @@ "LambdaFunctionServiceRoleC555A460", ], "Properties": Object { "Code": Object { "S3Bucket": Object { - "Ref": "AssetParametersbca73d9caf09b131f3b33cc87844d2707c6ac9c9abc18644c670eec939b26496S3Bucket170AB6D6", + "Ref": "[HASH REMOVED]", }, "S3Key": Object { "Fn::Join": Array [ "", Array [ @@ -32,11 +32,11 @@ 0, Object { "Fn::Split": Array [ "||", Object { - "Ref": "AssetParametersbca73d9caf09b131f3b33cc87844d2707c6ac9c9abc18644c670eec939b26496S3VersionKeyF774BA74", + "Ref": "[HASH REMOVED]", }, ], }, ], }, @@ -45,11 +45,11 @@ 1, Object { "Fn::Split": Array [ "||", Object { - "Ref": "AssetParametersbca73d9caf09b131f3b33cc87844d2707c6ac9c9abc18644c670eec939b26496S3VersionKeyF774BA74", + "Ref": "[HASH REMOVED]", }, ], }, ], }, 17 | const stack = new CdkIgnoreTestAssets.CdkIgnoreTestAssetsStack(app, 'cdkIgnoreTestAssetsStack'); 18 | > 19 | expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); | ^ 20 | }); 21 | at Object.<anonymous>.test (test/cdk-ignore-test-assets.test.ts:19:46)
ハッシュ値の部分が[HASH REMOVED]
に置き換わってますね!
まとめ
JestのSnapshot Serializerというものを知らなかったので教えてくれた同僚には感謝です。jest.config
でモジュールを指定すれば、各テストケースで対応する必要もないため楽ですね。ケースバイケースで使い分けていきましょう。