| 导读 | 之前写过一个 StackExchange.Redis 的一个扩展,测试项目依赖 redis,所以之前测试一直只是在本地跑一下,最近通过 Github Action 中的 Service Container 来通过 CI 来跑测试,分享一下如何使用 service container 来跑测试,不仅仅是 Redis,数据库等依赖也可以使用这样的方式来测试。 |

jobs:
# Label of the runner job
runner-job:
# You must use a Linux environment when using service containers or container jobs
runs-on: ubuntu-latest
# Service containers to run with `runner-job`
services:
# Label used to access the service container
redis:
# Docker image
image: redis:alpine
# Set health checks to wait until redis has started
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps port 6379 on service container to the host
- 6379:6379
上面是一个 redis service container 配置示例的一部分,需要注意的是使用 service container 的时候必须要使用 Linux 环境,因为 service container 的本质就是 docker run 了一个 container,通过一定的规则配置来实现在跑 CI 的环境可以访问的这个 service。
上面的示例配置了一个 redis 的 service container,并将容器服务的 6379 端口映射到 host 的 6379 端口,这样 host 上的服务就可以通过 127.0.0.1:6379/localhost:6379 访问到使用 docker 跑起来的 redis 服务(redis service container)了。
steps:
# Downloads a copy of the code in your repository before running CI tests
- name: Check out repository code
uses: actions/checkout@v2
# Performs a clean installation of all dependencies in the `package.json` file
# For more information, see https://docs.npmjs.com/cli/ci.html
- name: Install dependencies
run: npm ci
- name: Connect to Redis
# Runs a script that creates a Redis client, populates
# the client with data, and retrieves data
run: node client.js
# Environment variable used by the `client.js` script to create
# a new Redis client.
env:
# The hostname used to communicate with the Redis service container
REDIS_HOST: localhost
# The default Redis port
REDIS_PORT: 6379
上面的这种形式是在 host 上跑的,也就是直接在跑 CI 的服务器上跑的,有些情况下环境的配置比较麻烦的情况下也可以直接在指定的 docker 镜像为基础的 docker container 里跑 CI,需要注意的是 docker container 里跑 CI 的时候和直接在 host 上跑 CI 网络上有区别, host 可能就是直接访问 localhost,container 访问就是 service 名称,来看下面的 container 的一个示例:
jobs:
# Label of the container job
container-job:
# Containers must run in Linux based operating systems
runs-on: ubuntu-latest
# Docker Hub image that `container-job` executes in
container: node:10.18-jessie
# Service containers to run with `container-job`
services:
# Label used to access the service container
redis:
# Docker Hub image
image: redis
# Set health checks to wait until redis has started
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
可以看到大部分是一样的,只是多了一个 container 的配置,这样实际的 CI 就是在这个 container 里执行的,创建的执行 CI 的 container 和 service container 是在同一个 network 下,可以直接通过服务名称来访问
steps:
# Downloads a copy of the code in your repository before running CI tests
- name: Check out repository code
uses: actions/checkout@v2
# Performs a clean installation of all dependencies in the `package.json` file
# For more information, see https://docs.npmjs.com/cli/ci.html
- name: Install dependencies
run: npm ci
- name: Connect to Redis
# Runs a script that creates a Redis client, populates
# the client with data, and retrieves data
run: node client.js
# Environment variable used by the `client.js` script to create a new Redis client.
env:
# The hostname used to communicate with the Redis service container
REDIS_HOST: redis
# The default Redis port
REDIS_PORT: 6379
提供一个我目前在用的一个 service container,和上面的示例基本是类似的,有需要的可以参考一下:
name: dotnetcore
on: [push]
jobs:
# Label of the container job
redis-integration-test:
# Containers must run in Linux based operating systems
runs-on: ubuntu-latest
# # Docker image that `job` executes in
# container: mcr.microsoft.com/dotnet/sdk:5.0
# Service containers to run with `container-job`
# https://docs.github.com/en/free-pro-team@latest/actions/guides/creating-redis-service-containers
services:
# Label used to access the service container
redis:
# Docker Hub image
image: redis:alpine
# Set health checks to wait until redis has started
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps port 6379 on service container to the host
- 6379:6379
steps:
- uses: actions/checkout@v1
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x
- name: dotnet info
run: dotnet --info
- name: build
run: bash build.sh --target=test
CI 执行日志:
从日志上我们可以看出来比普通的 CI 执行会多出两个步骤,一个是初始化 container,一个是清理 container
完整的CI 日志可以在这里看到:https://github.com/WeihanLi/WeihanLi.Redis/runs/1400006789?check_suite_focus=true
虽然我的场景是 redis,但是不仅仅是 redis,很多应用外的依赖比如说数据库,甚至MQ等都是可以通过 service container 来做一个完善的集成测试,没有尝试过的快去试试吧~~
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/124814.html