/images/author.jpg

【Golang】基于录制,自动生成go test接口自动化用例

背景 之前写过一篇博客,介绍怎么用Python通过解析抓包数据,完成自动化用例的编写。最近这段时间在使用go test,所以就在想能不能也使用代码来生成自动化用例,快速提升测试用例覆盖率。说干就干。 框架 首先介绍一下我们使用的测框架: 项 信息 安装 备注 GO版本 go1.12.9 darwin/amd64 略 测试框架 ginkgo go get -u github.com/onsi/ginkgo/ginkgo 断言库 testify/assert go get github.com/stretchr/testify 官方配套的断言库是gomega ginkgo初始化 初始化: cd path/to/package/you/want/to/test && ginkgo bootstrap 创建示例用例:ginkgo generate (需要手动添加测试用例) 运行测试: go testor ginkgo 注:-v加上参数可打印运行信息 抓包&运行脚本 使用抓包工具(如Charles)抓包,把数据包导出为har格式,保存在当前目录下 如何安装抓包工具在本文就不赘述了,抓包,过滤出想要的数据,导出,保存的格式注意选择为har: 根据实际情况修改全局变量信息,如bizBaseFolder、serverName、userFile等 使用go run gentest.go运行脚本即可 目录说明 然后我们一起来了解一下我们的目录结构定义。 ∮./business 业务封装,封装具体的请求及测试数据 ∮./conf 配置信息及接口请求参数初始化封装 ∮./utils 公共函数封装 ∮./testcase 接口测试用例目录 testcase 用例目录结构规则 基本原则: 根据项目、模块、接口功能逐级区分,建议最多3层目录层级 ¶示例 软件测试论坛项目组/论坛项目/帖子模块/创建帖子接口: CN_TestBBS/bbs/post/post_test.go 基础账号项目/首页项目/白名单接口: CN_account/homepage/whitelist_test.go 实现思路 按照har文件的JSON结构定义对应的结构体,然后解析数据,生成请求数据,生成断言数据,初始化测试套suite,格式化代码,初始化包引用信息。 解析Har数据 定义结构体 1 2 3 4 5 6 7 8 Log struct { version string creator string Entries []struct { startedDateTime string time string Request struct { ... 解析到json 1 2 3 4 5 6 7 func UnpackHar(har []byte) (logs *Har) { err := json.Unmarshal(har, &logs) if err != nil { fmt.Println(err) } return } 转换请求数据 转换请求 转换请求参数 GET 1 2 3 4 5 6 7 8 9 10 11 12 13 // 格式化请求参数为标准请求string getReqParam := make(map[string]interface{}, 1) if len(v.Request.QueryString) > 0 { for _, query := range v.Request.QueryString { getReqParam[query.Name] = query.Value } } // 获取postReq数据 postReqParamStr := v.Request.PostData.Text if v.Request.Method == "GET" { paramstr = genGetParam(InterfaceName, getReqParam) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 func genGetParam(interfaceName string, param map[string]interface{}) (formatParam string) { // 对于请求参数的value值为 数组 if len(param) > 0 { for k, v := range param { switch vv := v.(type) { case []interface{}: fmt.Sprintf(k, "is an array:", vv) temp, _ := json.Marshal(param) formatParam = fmt.Sprintf("%sParam = `%s`", interfaceName, fmt.Sprintf("%v", string(temp))) return default: // fmt.Println(k, "is of a type didn't handle") } } } temp, _ := json.Marshal(param) formatParam = fmt.Sprintf(`%sParam = map[string]interface{} %s`, interfaceName, fmt.Sprintf("%v", string(temp))) return } POST 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

发言:排序

   Bingo我是一只潇潇 🐦 2021-05-26 昵称消息累计累计比例 房子3131 8.01% 惠风和畅3162 16.02% 做梦3092 23.77% 进哥哥22114 29.46% Shine21135 34.88% 主席19154 39.79% 蓝色16170 43.93% 十七16186 48.06% 林夕相心13199 51.42% 天空之城12211 54.52% Steven10221 57.11% 开胶哥10231 59.69% 大海9240 62.02% 海若8248 64.08% 了了7255 65.89% 地瓜7262 67.70% Dizze7269 69.51% 力敏6275 71.06% 锋哥6281 72.61% 三三6287 74.16% 宸宸6293 75.71% 小乔6299 77.26% 梦想5304 78.55% 山海5309 79.84% 心念5314 81.14% 麦迪5319 82.43% 陶子5324 83.72% Isaac4328 84.75% 文迪4332 85.79% 歆乔3335 86.56% 守幸3338 87.34% 小凡3341 88.11% Nan3344 88.89% 摩羯蜜语3347 89.66% 花仙子2349 90.18% 石榴2351 90.70% 蝴蝶2353 91.21% 亮仔2355 91.73% 摆渡人2357 92.25% 羚羊早早2359 92.76% 银河2361 93.28% 偶然2363 93.80% 人淡如菊2365 94.32% Irene2367 94.83% 肚皮2369 95.35% 扬帆2371 95.87% 琦凯2373 96.38% 果子1374 96.64% Cathy1375 96.90% 林么么1376 97.16% CAT小燕1377 97.42% 女眉1378 97.67% 炎年1379 97.93% 未来1380 98.19% 君儿1381 98.45% 琳达1382 98.71% Omo1383 98.97% 知更鸟1384 99.22% 飞麦1385 99.48% 想飞的鱼1386 99.74% Tracychi1387100.00% 1 2 3 4 5 6 7 8 9 10 print([i ** 7 for i in range(1, 9)]) [1, 128, 2187, 16384, 78125, 279936, 823543, 2097152] print([i ** 1 for i in range(1, 9)]) [1, 2, 3, 4, 5, 6, 7, 8] print([i ** 3 for i in range(1, 9)]) [1, 8, 27, 64, 125, 216, 343, 512] print([i ** 5 for i in range(1, 9)]) [1, 32, 243, 1024, 3125, 7776, 16807, 32768] print([i ** 9 for i in range(1, 9)]) [1, 512, 19683, 262144, 1953125, 10077696, 40353607, 134217728]

【locust】使用locust + boomer实现对接口的压测

背景 很早之前,考虑单机执行能力,使用locust做过公司短信网关的压测工作,后来发现了一个golang版本的locust,性能是python版本的5到10倍以上,但是一直没有机会使用。 最近公司想做一个性能测试平台,技术选型要求和开发的语言一致,即golang,所以我想到了boomer,本文为boomer的使用记录。 环境安装 开发环境 安装 Python 3.7 略 locust 0.11.0 pip install locustio golang 略 boomer go get github.com/myzhan/boomer 注:最新版本的boomer兼容了goczmq,需要将locust升级到较高版本才能完成兼容。 脚本编写 master 这部分的代码不重要,只要能启动就行。 1 2 3 4 5 6 7 8 9 10 11 from locust import Locust, TaskSet, task class MyTaskSet(TaskSet): @task(20) def hello(self): pass class Dummy(Locust): task_set = MyTaskSet slave节点(golang/boomer) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 package main import ( "bytes" "encoding/json" "fmt" "io/ioutil" "log" "net/http" "time" "github.com/myzhan/boomer" ) func getDemo() { start := time.Now() resp, err := http.Get("http://httpbin.org/get?name=Detector") if err != nil { log.Println(err) return } defer resp.Body.Close() fmt.Println(resp.Status) elapsed := time.Since(start) if resp.Status == "200 OK" { boomer.RecordSuccess("http", "sostreq", elapsed.Nanoseconds()/int64(time.Millisecond), int64(10)) } else { boomer.RecordFailure("http", "sostreq", elapsed.Nanoseconds()/int64(time.Millisecond), "sostreq not equal") } } func postDemo() { start := time.Now() info := make(map[string]interface{}) info["name"] = "Detector" info["age"] = 15 info["loc"] = "深圳" // 将map解析未[]byte类型 bytesData, _ := json.Marshal(info) // 将解析之后的数据转为*Reader类型 reader := bytes.NewReader(bytesData) resp, _ := http.Post("http://httpbin.org/post", "application/json", reader) body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) elapsed := time.Since(start) if resp.Status == "200 OK" { boomer.RecordSuccess("http", "sostreq", elapsed.Nanoseconds()/int64(time.Millisecond), int64(10)) } else { boomer.RecordFailure("http", "sostreq", elapsed.Nanoseconds()/int64(time.Millisecond), "sostreq not equal") } } func main() { task1 := &boomer.Task{ Name: "sostreq", // The weight is used to distribute goroutines over multiple tasks. Weight: 20, Fn: getDemo, } task2 := &boomer.Task{ Name: "sostreq", // The weight is used to distribute goroutines over multiple tasks. Weight: 10, Fn: postDemo, } boomer.Run(task1, task2) } 实际效果如下: 问题 Failed to execute dot. Is Graphviz installed? Error: exec: “dot”: executable file not found in $PATH