testcli UT运行环境构建工具

基于 docker-compose 实现跨平台跨语言环境的容器依赖管理方案,以解决运行ut场景下的 (mysql, redis, mc)容器依赖问题。

这个是testing/lich的二进制工具版本(Go请直接使用库版本:github.com/go-kratos/kratos/pkg/testing/lich)

功能和特性

  • 自动读取 test 目录下的 yaml 并启动依赖
  • 自动导入 test 目录下的 DB 初始化 SQL
  • 提供特定容器内的 healthcheck (mysql, mc, redis)
  • 提供一站式解决 UT 服务依赖的工具版本 (testcli)

编译安装

使用本工具/库需要前置安装好 docker & docker-compose@v1.24.1^

Method 1. With go get

  1. go get -u github.com/go-kratos/kratos/tool/testcli
  2. $GOPATH/bin/testcli -h

Method 2. Build with Go

  1. cd github.com/go-kratos/kratos/tool/testcli
  2. go build -o $GOPATH/bin/testcli
  3. $GOPATH/bin/testcli -h

Method 3. Import with Kratos pkg

  1. import "github.com/go-kratos/kratos/pkg/testing/lich"

构建数据

Step 1. create docker-compose.yml

创建依赖服务的 docker-compose.yml,并把它放在项目路径下的 test 文件夹下面。例如:

  1. mkdir -p $YOUR_PROJECT/test
  1. version: "3.7"
  2. services:
  3. db:
  4. image: mysql:5.6
  5. ports:
  6. - 3306:3306
  7. environment:
  8. - MYSQL_ROOT_PASSWORD=root
  9. volumes:
  10. - .:/docker-entrypoint-initdb.d
  11. command: [
  12. '--character-set-server=utf8',
  13. '--collation-server=utf8_unicode_ci'
  14. ]
  15. redis:
  16. image: redis
  17. ports:
  18. - 6379:6379

一般来讲,我们推荐在项目根目录创建 test 目录,里面存放描述服务的yml,以及需要初始化的数据(database.sql等)。

同时也需要注意,正确的对容器内服务进行健康检测,testcli会在容器的health状态执行UT,其实我们也内置了针对几个较为通用镜像(mysql mariadb mc redis)的健康检测,也就是不写也没事(^^;;

Step 2. export database.sql

构造初始化的数据(database.sql等),当然也把它也在 test 文件夹里。

  1. CREATE DATABASE IF NOT EXISTS `YOUR_DATABASE_NAME`;
  2. SET NAMES 'utf8';
  3. USE `YOUR_DATABASE_NAME`;
  4. CREATE TABLE IF NOT EXISTS `YOUR_TABLE_NAME` (
  5. `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键'
  6. PRIMARY KEY (`id`),
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='YOUR_TABLE_NAME';

这里需要注意,在创建库/表的时候尽量加上 IF NOT EXISTS,以给予一定程度的容错,以及 SET NAMES ‘utf8’; 用于解决客户端连接乱码问题。

Step 3. change your project mysql config

  1. [mysql]
  2. addr = "127.0.0.1:3306"
  3. dsn = "root:root@tcp(127.0.0.1:3306)/YOUR_DATABASE?timeout=1s&readTimeout=1s&writeTimeout=1s&parseTime=true&loc=Local&charset=utf8mb4,utf8"
  4. active = 20
  5. idle = 10
  6. idleTimeout ="1s"
  7. queryTimeout = "1s"
  8. execTimeout = "1s"
  9. tranTimeout = "1s"

Step 1 我们已经指定了服务对外暴露的端口为3306(这当然也可以是你指定的任何值),那理所应当的我们也要修改项目连接数据库的配置~

Great! 至此你已经完成了运行所需要用到的数据配置,接下来就来运行它。

运行

开头也说过本工具支持两种运行方式:testcli 二进制工具版本和 go package 源码包,业务方可以根据需求场景进行选择。

Method 1. With testcli tool

已支持的 flag: -f,—nodown,down,run

  • -f,指定 docker-compose.yaml 文件路径,默认为当前目录下。
  • —nodown,指定是否在UT执行完成后保留容器,以供下次复用。
  • down,teardown 销毁当前项目下这个 compose 文件产生的容器。
  • run,运行你当前语言的单测执行命令(如:golang为 go test -v ./)

example:

  1. testcli -f ../../test/docker-compose.yaml run go test -v ./

Method 2. Import with Kratos pkg

  • Step1. 在 Dao|Service 层中的 TestMain 单测主入口中,import “github.com/go-kratos/kratos/pkg/testing/lich” 引入testcli工具的go库版本。
  • Step2. 使用 flag.Set(“f”, “../../test/docker-compose.yaml”) 指定 docker-compose.yaml 文件的路径。
  • Step3. 在 flag.Parse() 后即可使用 lich.Setup() 安装依赖&初始化数据(注意测试用例执行结束后 lich.Teardown() 回收下~)
  • Step4. 运行 go test -v ./看看效果吧~

example:

  1. package dao
  2. import (
  3. "flag"
  4. "os"
  5. "strings"
  6. "testing"
  7. "github.com/go-kratos/kratos/pkg/conf/paladin"
  8. "github.com/go-kratos/kratos/pkg/testing/lich"
  9. )
  10. var (
  11. d *Dao
  12. )
  13. func TestMain(m *testing.M) {
  14. flag.Set("conf", "../../configs")
  15. flag.Set("f", "../../test/docker-compose.yaml")
  16. flag.Parse()
  17. if err := paladin.Init(); err != nil {
  18. panic(err)
  19. }
  20. if err := lich.Setup(); err != nil {
  21. panic(err)
  22. }
  23. defer lich.Teardown()
  24. d = New()
  25. if code := m.Run(); code != 0 {
  26. panic(code)
  27. }
  28. }

注意

因为启动mysql容器较为缓慢,健康检测的机制会重试3次,每次暂留5秒钟,基本在10s内mysql就能从creating到服务正常启动! 当然你也可以在使用 testcli 时加上 —nodown,使其不用每次跑都新建容器,只在第一次跑的时候会初始化容器,后面都进行复用,这样速度会快很多。