AWS CDK测试初探:掌握Assertion测试模式

本系文将深入讲解AWS CDK(云开发工具包)中的Assertion测试方法。在本文的第一部分,我们将重点介绍Template类的方法及其具体用法。

谁适合阅读这篇文章

如果你正考虑为基础设施代码添加测试,或者计划为CDK应用程序引入测试,那么这篇文章会为你提供一些有用的思路。此外,如果你对Assertion测试的编写有浓厚的兴趣,那么你也将在这里找到值得参考的示例和指导。

这篇文章不涉及的内容

我们不会在本文中讲解AWS CDK的基本使用步骤,也不会深入探讨特定AWS资源的高级技术细节。本文的核心将集中在测试的具体实现上,帮助你更好地理解如何在CDK项目中应用Assertion测试。

运行环境

本文的内容已在以下环境中进行过测试和验证:

  • Node.js 20.15.0
  • TypeScript 5.5.2
  • AWS CDK v2(2.150.0)

测试对象

TypeScript 复制代码
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
    });
  
    
    new cdk.CfnOutput(this, 'S3BucketName', {
      value: Bucket.bucketName,
    });
  }
}

检查资源的属性内容

当你想要验证某个资源的特定属性时,可以使用hasResourceProperties方法。通过该方法,你可以确认是否存在具有指定属性的资源,从而确保资源的配置符合预期。

TypeScript 复制代码
test("验证存在启用了ObjectLock的S3桶", () => {
  template.hasResourceProperties("AWS::S3::Bucket", {
    BucketName: "hogehoge"
  });
});

allResourcesProperties

allResourcesProperties方法用于确认指定的所有资源是否都具有特定的属性。当你想验证所有创建的S3桶是否都启用了Object Lock等属性时,这个方法将非常有用。

TypeScript 复制代码
test("验证所有的S3存储桶都启用了ObjectLock", () => {
  template.allResourcesProperties("AWS::S3::Bucket", {
    ObjectLockEnabled: true,
  });
});

检查资源属性以外的元素

当你想验证资源的其他元素(例如类型)时,可以使用hasResource方法。这个方法能够帮助你确认是否存在指定类型的资源。

如果你需要针对所有AWS资源进行测试,类似于hasResourceProperties的情况,可以使用allResources方法来实现。这样你可以确认项目中所有相关资源是否符合预期配置。

TypeScript 复制代码
test("验证存在删除策略为Retain的S3存储桶", () => {
  template.hasResource("AWS::S3::Bucket", {
    DeletionPolicy: "Retain",
  });
});

allResources

allResources方法用于验证是否存在指定类型的资源。当你需要测试所有的AWS资源时,类似于使用hasResourceProperties的情况,你可以使用allResources来确认所有相关资源是否符合预期配置。

TypeScript 复制代码
test("验证所有的S3存储桶的删除策略都是Retain", () => {
  template.allResources("AWS::S3::Bucket", {
    DeletionPolicy: "Retain",
  });
});

检查资源数量

当你想要验证某个特定类型的资源是否存在指定的数量时,可以使用resourceCountIs方法。该方法可以帮助你确认项目中是否存在预期数量的资源,以确保资源的数量配置符合要求。

TypeScript 复制代码
test("验证创建的S3存储桶数量为2", () => {
  template.resourceCountIs("AWS::S3::Bucket", 2);
});

resourcePropertiesCountIs

resourcePropertiesCountIs方法用于验证具有指定属性的资源是否存在指定的数量。通过这个方法,你可以确保项目中具有某些特定属性的资源数量符合预期要求。这对于确保资源配置的一致性和准确性非常有用。

TypeScript 复制代码
test("验证存在两个启用了ObjectLock的S3存储桶", () => {
  template.resourcePropertiesCountIs("AWS::S3::Bucket", {
    ObjectLockEnabled: true,
  }, 2);
});

从模板中获取特定资源信息

如果你想从CloudFormation模板中提取与特定资源相关的信息,可以使用find〇〇系列方法。以findResources为例,它能够从模板的Resources部分中筛选出符合条件的特定资源类型。

举个例子,假如你需要输出与S3存储桶相关的部分,可以这样写:

TypeScript 复制代码
const s3 = template.findResources("AWS::S3::Bucket", {});

根据模板的不同部分,你可以灵活使用类似的find〇〇方法,获取你需要的资源信息。

TypeScript 复制代码
{
  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来限定需要提取的特定资源。这样可以帮助你在大量资源中精确找到符合特定条件的资源配置。

TypeScript 复制代码
const s3 = template.findResources("AWS::S3::Bucket", {
  Properties: {
    BucketName: "hogehoge",
  },
});
TypeScript 复制代码
{
  CdkTestStudyBucket13535E829: {
    Type: 'AWS::S3::Bucket',
    Properties: {
      BucketName: 'hogehoge',
      ObjectLockEnabled: true,
      VersioningConfiguration: [Object]
    },
    UpdateReplacePolicy: 'Retain',
    DeletionPolicy: 'Retain'
  }
}

确认模板的某个部分是否包含特定值

如果你想从CloudFormation模板中确认某个特定部分是否包含特定的值,可以使用has〇〇系列方法。例如,使用hasOutputs可以确认模板的Outputs部分是否包含符合条件的内容。

例如,如果你想检查S3 Bucket是否被包含在Outputs部分中,可以这样写:

TypeScript 复制代码
test("验证S3的BucketName是否被输出", () => {
  const s3 = template.findResources("AWS::S3::Bucket", {
    Properties: {
      BucketName: "hogehoge",
    },
  });

  template.hasOutput('S3BucketName', {
    Value: { 
      Ref: Object.keys(s3)[0]
    }
  });
});

你可以根据模板的不同部分使用相应的has〇〇方法,以便确认特定值是否存在。

总结

在本文中,我们介绍了在Assertion测试中使用的Template类方法。像hasResourceProperties和resourceCountIs这样的方法使用频率较高,是编写Assertion测试时必须了解的关键方法。

下一篇文章中,我们将深入探讨创建更详细的Assertion测试时不可或缺的Match类方法。

参考

class Template · AWS CDK

相关推荐
李兆龙的博客39 分钟前
从一到无穷大 #105:OpenAI Habitat II——多租户演进、全球读取优化与 CDC 平台
云计算·存储
yyuuuzz13 小时前
跨境站点日志时区混乱的排查记录
运维·服务器·网络·云计算·aws·1024程序员节
Maynor9962 天前
免费 Cloudflare 只有 10 个 D1?满了之后的「穷鬼打法」:表前缀复用同一个库
数据库·后端·云计算·cloudflare
A-刘晨阳2 天前
【云原生】nerdctl 部署及使用指南
运维·docker·kubernetes·云计算·1024程序员节·nerdctl
我是高手高手高高手3 天前
安装宝塔,阿里云(有系统和数据两个盘)
阿里云·云计算
FY@-@4 天前
VMware ESXi 7.0 实验全记录:嵌套安装 → 网络配置 → 存储 → Windows 10 虚拟机部署
运维·网络·windows·云计算
DolitD4 天前
国产信创+实时云渲染:数字孪生智慧矿山UE5流畅推流
3d·信息可视化·云计算·图形渲染·数据可视化
做运维的阿瑞4 天前
Terraform 模块版本管理:约束语法、源类型与升级策略
云原生·云计算·terraform
做运维的阿瑞4 天前
Terraform 模块组合:VPC、安全组、EC2 的输出传递与依赖编排
云原生·云计算·terraform
FY@-@4 天前
云计算基础(下):虚拟化原理与 DAS/NAS/SAN 存储
运维·服务器·云计算