本教程介绍如何对使用 Cloud Functions 构建的应用自动执行端到端测试。 Cloud Build 运行测试流水线,HashiCorp Terraform 设置并删除运行测试所需的 Google Cloud 资源。Cloud Build 触发器会在每次代码提交后启动流水线。
在设计应用和评估架构选择时,可测试性是一项关键考虑因素。创建并定期运行一系列全面的测试(包括自动化单元测试、集成测试和端到端系统测试)对于验证应用是否按预期运行至关重要。如需详细了解如何针对不同的 Cloud Functions 场景进行各类测试,请参阅测试最佳做法指南。
创建和运行单元测试通常较简单,因为这些测试是独立的并且独立于执行环境。但是,集成和系统测试则较复杂,尤其是在云环境中。使用无服务器技术(例如 Cloud Functions)的应用尤其需要使用端到端系统测试。这些应用通常由事件驱动且松散耦合,并且可能是独立部署的应用。对于验证函数是否正确响应 Google Cloud 执行环境中的事件,全面的端到端测试至关重要。
架构
以下架构图展示了您在本教程中使用的组件。
该架构包含以下组件:
- 托管并运行 Cloud Build 流水线的
build
项目。 - 为受测示例应用托管 Google Cloud 资源的
test
项目。- 无服务器 Web 性能监控教程中描述的应用用作示例应用。
- 系统会为每次构建迭代创建并销毁示例应用的 Google Cloud 资源。Firestore 数据库例外。该数据库是一次性创建,由所有后续构建重复使用。
目标
- 创建一个 Cloud Build 流水线,对使用 Cloud Functions 构建的示例应用运行单元测试和端到端测试。
- 在构建中使用 Terraform 来设置和销毁应用所需的 Google Cloud 资源。
- 使用专用 Google Cloud 测试项目保持测试环境独立。
- 在 Cloud Source Repositories 中创建一个 Git 代码库,并添加一个 Cloud Build 触发器以在提交后运行端到端构建。
费用
本教程使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理。
准备工作
-
选择或创建 Cloud 项目。这是托管示例应用的
test
项目。 - 记下
test
项目的 Google Cloud 项目 ID。 在下一部分设置环境时,您将需要此 ID。 - 启用该项目Cloud Build、Cloud Functions 和 Cloud Source Repositories API。
- 在控制台中,转到 Firestore 页面。 转到 Firestore 页面
- 创建 Firestore 数据库。
- 选择或创建其他 Google Cloud 项目。这是托管 Cloud Build 流水线的
build
项目。
转到“管理资源”页面
确保您的 Google Cloud 项目已启用结算功能。
设置环境
在本教程中,您将在 Cloud Shell 中运行命令。Cloud Shell 是一个已安装 Google Cloud CLI 的 shell 环境,其中包括 Google Cloud CLI 以及已为当前项目设置的值。初始化 Cloud Shell 可能需要几分钟。
在控制台中,为
build
项目打开 Cloud Shell。为您之前复制的
test
Google Cloud 项目 ID 设置变量:export TEST_PROJECT=your-test-project-id
替换以下内容:
your-test-project-id
:您的test
Google Cloud 项目的 ID。
将当前
build
Google Cloud 项目的项目 ID 和项目编号设置为变量:export BUILD_PROJECT=$(gcloud config get-value core/project) export BUILD_PROJECT_NUM=$(gcloud projects list \ --filter="$BUILD_PROJECT" --format="value(PROJECT_NUMBER)")
为部署地区设置变量:
export REGION=us-central1
虽然本教程使用的是
us-central1
地区,但您可以将其更改为支持 Cloud Functions 的任何地区。克隆包含本教程中使用的示例应用代码的代码库:
git clone \ https://github.com/GoogleCloudPlatform/solutions-serverless-web-monitoring.git
转到项目目录:
cd solutions-serverless-web-monitoring
使用 Terraform 创建测试基础架构
本教程使用 Terraform 在测试项目中自动创建和销毁 Google Cloud 资源。为每次构建创建独立资源有助于将测试彼此隔离。隔离测试时,可以并发进行构建,并且可以针对特定资源作出测试断言。在每次构建结束时销毁资源有助于最大限度地降低费用。
本教程部署了无服务器 Web 监控教程中所述的应用。该应用包含一组 Cloud Functions 函数、Cloud Storage 存储分区、Pub/Sub 资源和一个 Firestore 数据库。Terraform 配置定义创建这些资源所需的步骤。Firestore 数据库不是由 Terraform 部署;该数据库是一次性创建,并由所有测试重复使用。
Terraform 配置文件 main.tf
中的以下代码示例展示了部署 trace
Cloud Functions 函数所需的步骤。如需了解完整配置,请参阅完整文件。
在此步骤中,您将运行 Terraform 配置以部署测试资源。 在稍后的步骤中,Cloud Build 会自动部署资源。
在 Cloud Shell 中,初始化 Terraform:
docker run -v $(pwd):/app -w /app hashicorp/terraform:0.12.0 init
您需要使用公共 Terraform Docker 映像。Docker 已安装在 Cloud Shell 中。当前工作目录以卷的形式装载,因此 Docker 容器可以读取 Terraform 配置文件。
使用 Terraform
apply
命令创建资源:docker run -v $(pwd):/app -w /app hashicorp/terraform:0.12.0 apply \ --auto-approve \ -var "project_id=$TEST_PROJECT" \ -var "region=$REGION" \ -var "suffix=$TEST_PROJECT"
该命令包含一些变量,这些变量指定您希望在其中创建测试资源的 Google Cloud 项目和地区。此外,它还包含一个用于在此步骤中创建命名资源的后缀。 在稍后的步骤中,Cloud Build 会自动提供合适的后缀。
此操作需要几分钟时间才能完成。
确认已在
test
项目中创建资源:gcloud functions list --project $TEST_PROJECT
输出会显示名称以之前提供的后缀结束的三个 Cloud Functions 函数。
运行端到端测试
在本部分中,您将针对在上一部分中部署的测试基础架构运行端到端测试。
以下代码段展示了这些测试。这些测试会同时验证成功和失败情况。测试流水线总结如下:
- 首先,测试调用
trace
函数。此调用会通过触发其他函数的应用启动事件流。 - 然后,测试验证每个函数的行为,并确认对象已写入 Cloud Storage、结果永久存储到 Firestore,并在失败时生成 Pub/Sub 提醒。
如需运行端到端测试,请完成以下步骤:
在 Cloud Shell 中,创建新的
virtualenv
环境。virtualenv
实用程序已安装在 Cloud Shell 中。virtualenv venv
激活
virtualenv
环境:source venv/bin/activate
安装所需的 Python 库:
pip install -r requirements.txt
运行端到端测试:
python -m pytest e2e/ --tfstate terraform.tfstate
传递 Terraform 状态文件,该文件包含在上一部分中创建的测试资源的详细信息。
测试可能需要几分钟时间才能完成。系统会显示一条消息,指示已通过两项测试。您可以忽略任何警告。
使用 Terraform
destroy
命令删除测试资源:docker run -v $(pwd):/app -w /app hashicorp/terraform:0.12.0 destroy \ --auto-approve \ -var "project_id=$TEST_PROJECT" \ -var "region=$REGION" \ -var "suffix=$TEST_PROJECT"
确认资源已被销毁:
gcloud functions list --project $TEST_PROJECT
不再存在名称以之前提供的后缀结束的任何 Cloud Functions 函数。
提交 Cloud Build 流水线
在本部分中,您将使用 Cloud Build 自动执行测试流水线。
设置 Cloud Build 权限
您可以使用 Cloud Build 服务帐号运行 Cloud Build。 由构建执行的系统测试创建 Cloud Functions 函数、Cloud Storage 存储分区、Pub/Sub 资源和 Firestore 文档并与之交互。为此,Cloud Build 具有以下要求:
- 测试项目中的适当的 Identity and Access Management (IAM) 角色。
- 能够充当 Cloud Functions 运行时服务帐号。
默认情况下,Cloud Functions 使用 App Engine 服务帐号 (
your-test-project-id@appspot.gserviceaccount.com
) 作为运行时服务帐号,其中your-test-project-id
是test
Google Cloud 项目的名称。
在此过程中,您需要添加适当的角色,然后添加 Cloud Build 服务帐号。
在 Cloud Shell 中,将适当的 IAM 角色添加到默认 Cloud Build 服务帐号:
for role in cloudfunctions.developer pubsub.editor storage.admin datastore.user; do \ gcloud projects add-iam-policy-binding $TEST_PROJECT \ --member="serviceAccount:$BUILD_PROJECT_NUM@cloudbuild.gserviceaccount.com" \ --role="roles/$role"; \ done
将 Cloud Build 服务帐号添加为测试项目中 App Engine 服务帐号的
serviceAccountUser
:gcloud iam service-accounts add-iam-policy-binding \ $TEST_PROJECT@appspot.gserviceaccount.com \ --member="serviceAccount:$BUILD_PROJECT_NUM@cloudbuild.gserviceaccount.com" \ --role=roles/iam.serviceAccountUser \ --project $TEST_PROJECT
提交手动构建
构建执行四个逻辑任务:
- 运行单元测试
- 部署示例应用
- 运行端到端测试
- 销毁示例应用
查看 cloudbuild.yaml
文件中的以下代码段。该代码段说明了使用 Terraform 部署示例应用以及运行端到端测试的各个 Cloud Build 步骤。
如需向 Cloud Build 提交手动构建并运行端到端测试,请执行以下操作:
在 Cloud Shell 中,输入以下命令:
gcloud builds submit --config cloudbuild.yaml \ --substitutions=_REGION=$REGION,_TEST_PROJECT_ID=$TEST_PROJECT
构建需要几分钟时间才能运行。构建步骤如下:
Cloud Build 使用替换来提供为您创建的测试资源指定 Google Cloud 项目和地区的变量。
Cloud Build 在
build
Google Cloud 项目中运行构建。测试资源在单独的test
项目中创建。
构建日志会流式传输到 Cloud Shell,以便您跟踪构建进度。日志流会在构建完成时终止。系统会显示一些消息,指示最终的
terraform-destroy
构建步骤已成功且构建已完成。
自动执行测试
持续集成 (CI) 的一个关键原则是定期运行一系列全面的自动化测试。通常,每次在提交到共享代码库时都会运行构建-测试流水线。此设置有助于确认对每次向共享代码库的提交都进行了测试和验证,以便您的团队尽早发现问题。
在接下来的各部分中,您将执行以下操作:
- 在 Cloud Source Repositories 中创建 Git 代码库。
- 添加 Cloud Build 触发器以在每次提交时运行端到端构建。
- 将代码推送到代码库以触发构建。
创建 Cloud Source Repository 和 Cloud Build 触发器
在 Cloud Shell 中,创建新的 Cloud Source Repository:
gcloud source repos create serverless-web-monitoring
在控制台中,打开 Cloud Build 触发器页面。
点击创建触发器。
此时会打开创建触发器页面。
填写以下选项:
- 在名称字段中,输入
end-to-end-tests
。 - 在事件下,选择推送到分支。
- 在来源下,选择
serverless-web-monitoring
作为您的代码库,选择^master$
作为您的分支。 - 在配置下,选择 Cloud Build 配置文件(yaml 或 json)。
- 在 Cloud Build 配置文件位置字段中,输入
cloudbuild.yaml
。 要添加变量替换以指定将在其中创建测试资源的 Google Cloud 地区,请点击添加变量:
- 变量:
_REGION
值:
your-test-region
替换以下内容:
your-test-region
:Cloud Shell 中$REGION
变量的值。
- 变量:
要添加其他变量替换以指定将托管测试资源的项目的 ID,请点击添加变量:
- 变量:
_TEST_PROJECT_ID
值:
your-test-project
替换以下内容:
your-test-project
:Cloud Shell 中$TEST_PROJECT
变量的值。
- 变量:
- 在名称字段中,输入
点击创建以保存您的构建触发器。
启动构建
在 Cloud Shell 中,将代码库添加为 git 配置中的新远程:
git remote add csr \ https://source.developers.google.com/p/$BUILD_PROJECT/r/serverless-web-monitoring
要触发构建,请将代码推送到代码库:
git push csr master
列出最新构建:
gcloud builds list --limit 3
输出将显示
WORKING
状态的构建,指示该构建已按预期触发。复制
WORKING
构建的 ID 以供下一步使用。将构建日志流式传输到控制台:
gcloud builds log --stream
build-id
替换以下内容:
build-id
:您在上一步中复制的WORKING
构建的 ID。
日志流会在构建完成时终止。系统会显示一些消息,指示最终的
terraform-destroy
构建步骤已成功且构建已完成。
清除数据
为避免因本教程中使用的资源导致您的 Google Cloud 帐号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
- 在控制台中,打开管理资源页面。
- 在项目列表中,选择要删除的项目,然后点击删除。
- 在对话框中输入项目 ID,然后点击关闭以删除项目。
后续步骤
- 访问 Google Cloud CI/CD 开发者中心。
- 阅读相关博文,了解如何通过测试和 CI/CD 避免生产环境中的错误。
- 完成相关的无服务器 Web 监控教程。
- 完成使用 Cloud Build 实现 GitOps 形式的持续交付教程。
- 探索有关 Google Cloud 的参考架构、图表、教程和最佳做法。查看我们的 Cloud Architecture Center。