この記事について
前回こちらの記事でSnapshotテストとAssertionテストの使い方について考えてみました。
今回からは、AWS CDK(Cloud Development Kit)のAssertionテストについて、具体的な書き方について深掘りしていきます。本記事では第一弾として、Template
クラスのメソッドに焦点を当て、その使い方について紹介します。
対象読者
本記事は、以下のような読者を対象としています。
- インフラストラクチャのコードにテストを導入したいと考えている方
- CDKアプリケーションにテストを導入することを検討している方
- Assertionテストの書き方について知りたい方
この記事では触れないこと
- AWS CDKの基礎的な使い方
- 特定のAWSリソースについての深い技術的解説
動作環境
この記事の内容は以下の環境で動作確認を行っています。
- Node.js 20.15.0
- TypeScript 5.5.2
- AWS CDK v2(2.150.0)
テスト対象となるStack
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
export class CdkTestStudyStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const Bucket = new s3.Bucket(this, 'CdkTestStudyBucket1', {
bucketName: 'hogehoge',
enforceSSL: true,
objectLockEnabled: true,
versioned: true,
});
new s3.Bucket(this, 'CdkTestStudyBucket2', {
objectLockEnabled: true,
removalPolicy: cdk.RemovalPolicy.RETAIN
});
// S3のBucketNameをoutput
new cdk.CfnOutput(this, 'S3BucketName', {
value: Bucket.bucketName,
});
}
}
リソースのプロパティの内容をチェックしたいとき
hasResourceProperties
指定されたプロパティを持つリソースが存在することを確認することができます。
該当のプロパティを持つリソースが1つでもあればテストは成功します。作成されるAWSリソース全てが特定のプロパティを満たしているかを確認したい場合は、次に紹介するallResourcesProperties
を使いましょう。
test("ObjectLockを有効にしているS3バケットが存在すること", () => {
template.hasResourceProperties("AWS::S3::Bucket", {
BucketName: "hogehoge"
});
});
allResourcesProperties
指定したリソース全てが特定のプロパティを持つことを確認することができます。
作成したS3全てがオブジェクトロック有効となっているかを確認したい場合などに有効です。
test("全てのS3バケットでObjectLockが有効になっていること", () => {
template.allResourcesProperties("AWS::S3::Bucket", {
ObjectLockEnabled: true,
});
});
リソースのプロパティ以外の要素をチェックしたいとき
hasResource
指定したタイプのリソースが存在することを確認することができます。
hasResourceProperties
のとき同様、全てのAWSリソースに対してテストしたい場合はallResources
を使いましょう。
test("削除ポリシーがRetainでS3バケットが存在すること", () => {
template.hasResource("AWS::S3::Bucket", {
DeletionPolicy: "Retain",
});
});
allResources
指定したタイプのリソースが存在することを確認することができます。
hasResourcePropertiesのとき同様、全てのAWSリソースに対してテストしたい場合はallResources
を使いましょう。
test("全てのS3バケットの削除ポリシーがRetainであること", () => {
template.allResources("AWS::S3::Bucket", {
DeletionPolicy: "Retain",
});
});
リソースの個数をチェックしたいとき
resourceCountIs
リソースが、指定された数だけ存在することを確認することができます。
test("作成されるS3バケットが2つであること", () => {
template.resourceCountIs("AWS::S3::Bucket", 2);
});
resourcePropertiesCountIs
指定したプロパティを持つリソースが、指定された数だけ存在することを確認することができます。
test("ObjectLockを有効にしているS3バケットが2つ存在すること", () => {
template.resourcePropertiesCountIs("AWS::S3::Bucket", {
ObjectLockEnabled: true,
}, 2);
});
Templateから特定のリソースに関する情報を取得したいとき
CloudFormationTempalteから特定のリソースに関する情報を取得したい場合は、以下のfind〇〇
メソッドを使用します。例としてfindResources
を紹介していますが、Templateのセクションに合わせて、find〇〇
メソッドを同じように使うことができます。
findResources
TemplateのResourcesセクションから、条件に該当する特定のリソースタイプに関する部分を抽出することができます。
例えば、S3 Bucketに関する部分を出力したい場合は以下のように記述します。
const s3 = template.findResources("AWS::S3::Bucket", {});
{
CdkTestStudyBucket13535E829: {
Type: 'AWS::S3::Bucket',
Properties: {
BucketName: 'hogehoge',
ObjectLockEnabled: true,
VersioningConfiguration: [Object]
},
UpdateReplacePolicy: 'Retain',
DeletionPolicy: 'Retain'
},
CdkTestStudyBucket2D584685D: {
Type: 'AWS::S3::Bucket',
Properties: { ObjectLockEnabled: true },
UpdateReplacePolicy: 'Retain',
DeletionPolicy: 'Retain'
}
}
リソースタイプのみ指定する場合は該当リソースに関する部分が全て抽出されるため、Propertiesを指定することでリソースを限定することもできます。
const s3 = template.findResources("AWS::S3::Bucket", {
Properties: {
BucketName: "hogehoge",
},
});
{
CdkTestStudyBucket13535E829: {
Type: 'AWS::S3::Bucket',
Properties: {
BucketName: 'hogehoge',
ObjectLockEnabled: true,
VersioningConfiguration: [Object]
},
UpdateReplacePolicy: 'Retain',
DeletionPolicy: 'Retain'
}
}
Templateのセクションに特定の値が含まれているか確認したいとき
CloudFormationTemplateから各セクションに特定の値が含まれているか確認したい場合は、以下のhas〇〇
メソッドを使用します。例としてhasOutputs
を紹介していますが、Templateのセクションに合わせて、has〇〇
メソッドを同じように使うことができます。
hasOutputs
TemplateのOutputsセクションに、条件に該当する記述が含まれている確認することができます。例えば、S3 BucketをOutputsに含めているか確認する場合は以下のように記述します。
test("S3のBucketNameをOutputしていること", () => {
const s3 = template.findResources("AWS::S3::Bucket", {
Properties: {
BucketName: "hogehoge",
},
});
template.hasOutput('S3BucketName', {
Value: {
Ref: Object.keys(s3)[0]
}
});
});
まとめ
本記事ではアサーションテストで使用するメソッドのうち、Templateクラスのメソッドについて紹介しました。
hasResourceProperties
やresourceCountIs
などのメソッドは特に利用頻度も高く、Assertionテストを作成する上で知っておくべきメソッドだと感じました。
次回はより詳細なAssertionテストを作成するために欠かせない、Matchクラスのメソッドについて深掘りしたいと思います。
参考