This guide explains how to use the asset hash normalization utility for consistent CDK snapshot testing across different environments.
CDK snapshot tests often fail in CI/CD environments because asset hashes change between different environments. This happens because:
- Asset hashes are generated based on content and environment variables
- Different machines or CI/CD environments produce different hashes
- This causes snapshot tests to fail even when there are no actual changes to the infrastructure
We've created a utility function that normalizes asset hashes and other environment-specific values in CloudFormation templates before comparing them with snapshots.
import { normalizeTemplate } from '../../test-utils/normalize-template';
import { App } from 'aws-cdk-lib';
import { Template } from 'aws-cdk-lib/assertions';
import { YourStack } from '../lib/your-stack';
import { normalizeTemplate } from '../../test-utils/normalize-template';
test('YourStack creates the expected resources', () => {
const app = new App();
const stack = new YourStack(app, 'TestStack');
// Get the CloudFormation template
const template = Template.fromStack(stack);
// Normalize the template before snapshot comparison
const normalizedTemplate = normalizeTemplate(template.toJSON());
// Compare with snapshot
expect(normalizedTemplate).toMatchSnapshot();
});
After adding the normalization to your tests, update your snapshots:
npm test -- -u
The utility currently normalizes:
-
S3 Asset Keys: Replaces asset hashes in S3Key properties
- Pattern with extension:
[64 hex chars].zip
→NORMALIZED_ASSET_HASH.zip
- Pattern without extension:
[64 hex chars]
→NORMALIZED_ASSET_HASH
- Pattern with extension:
-
Docker Image Digests: Replaces image digests
- Pattern:
sha256:[digest]
→NORMALIZED_IMAGE_DIGEST
- Pattern:
When creating new test files that use snapshot testing:
- Import the normalization utility
- Apply it to your template before comparing with snapshots
- Update your snapshots with the
-u
flag
If you encounter other environment-specific values that need normalization, you can extend the utility at typescript/test-utils/normalize-template.ts
.
Example of adding a new normalization rule:
// Inside the normalizeValues function
if (key === 'NewPropertyToNormalize' && typeof obj[key] === 'string' && /pattern-to-match/.test(obj[key])) {
obj[key] = 'NORMALIZED_VALUE';
}
If you're still seeing snapshot test failures:
- Check for new patterns: There might be new types of asset hashes or environment-specific values that need normalization
- Verify imports: Make sure you're importing and using the utility correctly
- Check snapshot updates: Ensure you've updated your snapshots after adding normalization
- Always normalize before snapshot comparison: This ensures consistent results
- Update snapshots deliberately: Only use the
-u
flag when you expect changes - Review snapshot diffs: When updating snapshots, review the changes to ensure they're expected
- Keep the utility updated: As new patterns emerge, add them to the normalization utility