当前位置: 代码网 > it编程>前端脚本>Golang > 使用Go语言开发自动化API测试工具详解

使用Go语言开发自动化API测试工具详解

2024年05月18日 Golang 我要评论
前言上一篇文章说到我还开发了一个独立的自动测试工具,可以根据 openapi 的文档来测试,并且在测试完成后输出测试报告,报告内容包括每个接口是否测试通过和响应时间等。这个工具我使用了 go 语言开发

前言

上一篇文章说到我还开发了一个独立的自动测试工具,可以根据 openapi 的文档来测试,并且在测试完成后输出测试报告,报告内容包括每个接口是否测试通过和响应时间等。

这个工具我使用了 go 语言开发,主要是考虑到了 go 语言可以傻瓜式的实现交叉编译,生成的可执行文件直接上传到服务器就可以执行,非常方便。

ps: go 语言写起来是真的折磨!感觉语法有很多别扭的地方,不过 build 的时候实在太爽了,根本无法拒绝

为了避免篇幅太长,本文先介绍用到的组件,详细实现以及解析 openapi 文档生成测试配置的部分后续的文章再介绍。

网络请求

标准库中的 net/http 包提供了发送 http 请求的功能,拿到数据之后,使用 json.unmarshal 函数解析 json 数据。这个包相对比较低级,对于简单的网络请求,够用,不过我还是想选择更好用的组件。

resty 是一个简单而强大的 go http 客户端,具有链式 api,可以轻松地发送 http 请求并处理 json 数据。它提供了丰富的功能,包括自动重试、超时设置、请求和响应日志等。您可以使用 resty 来发送 get、post、put、delete 等各种类型的请求,并且它能够自动将响应的 json 数据解析为 go 结构体。

现在出了 v2 版本,支持 http/2、websocket、cookie 操作,并提供了更加简洁和易用的 api 。

项目地址: https://github.com/go-resty/resty

使用起来还行

get 方法

import 	"github.com/go-resty/resty/v2"

req := c.restyclient.r().setheader("authorization", "token "+c.authtoken)

req.setqueryparams(map[string]string{
  "year":  "2024",
})
resp, err = req.get("path")

post 方法

req.setbody(map[string]string{
  "year":  "2024",
})
resp, err = req.get("path")

setbody 的参数是 interface{} 类型,可以传入的类型比较丰富,我这里还是跟 get 一样传了字典,实际上应该传 struct 比较多一些吧。

日志组件

我之前用的是 go 语言内置的 log ,但似乎功能很少,也没有日志等级啥的,这能叫日志库吗……

接着我找到了在 github 上 star 很多的 logrus 库,不过感觉这是一个比较古老的库了,不太好用,formatter 也没找到好用的,看项目主页的介绍发现这个库已经进入退休状态…

它让我 check out, for example, zerologzap, and apex.

logrus is in maintenance-mode. we will not be introducing new features. it's simply too hard to do in a way that won't break many people's projects, which is the last thing you want from your logging library (again...).

项目地址: https://github.com/sirupsen/logrus

所以,最终还是用了 uber 的日志库 go.uber.org/zap

logrus 使用 & 配置

虽然后面换了 zap ,还是记录一下关于 logrus 的使用。

项目主页上列举的几个第三方 formatter 我基本都试用了,就这个 nested-logrus-formatter 比较好用。

以下配置实现了同时输出日志到控制台和文件。

import (
  nested "github.com/antonfisher/nested-logrus-formatter"
  "github.com/sirupsen/logrus"
  "os"
)

func initlogger() *os.file {
  logger.setlevel(logrus.debuglevel)
  logger.setreportcaller(true)
  logger.setformatter(&nested.formatter{})

  // 创建一个文件作为日志输出
  file, err := os.openfile("logfile.log", os.o_create|os.o_wronly|os.o_append, 0666)
  if err != nil {
    logger.fatalf("无法打开日志文件: %v", err)
  }

  // 创建一个多写入器,将日志同时输出到控制台和文件
  mw := io.multiwriter(os.stdout, file)

  // 添加 hook 到 logger 中
  logger.out = mw

  return file
}

func main() {
  file := initlogger()
  defer func(file *os.file) {
    err := file.close()
    if err != nil {
      fmt.println(err)
    }
  }(file)
}

zap 使用 & 配置

zap 比起 logrus 好用多了,开箱即用,搭配 zapcore 可以配置多个输出,也可以设置按日志大小分割文件,还可以对接其他日志收集平台啥的,基本做到了现代日志组件的水平了…

一样是实现了同时输出日志到控制台和文件。

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"os"
)

func buildlogger() *zap.sugaredlogger {
  config := zap.newproductionencoderconfig()
  config.encodetime = zapcore.iso8601timeencoder
  consoleencoder := zapcore.newconsoleencoder(config)
  fileencoder := zapcore.newjsonencoder(config)
  logfile, _ := os.openfile("./log-test-zap.log", os.o_wronly|os.o_create|os.o_append, 06666)

  tee := zapcore.newtee(
    zapcore.newcore(fileencoder, zapcore.addsync(logfile), zap.debuglevel),
    zapcore.newcore(consoleencoder, zapcore.addsync(os.stdout), zap.debuglevel),
  )
  var zaplogging = zap.new(
    tee,
    zap.addcaller(),
    zap.addstacktrace(zapcore.errorlevel),
  )

  var logger = zaplogging.sugar()
  return logger
}

func main() {
  logger := buildlogger()
  defer logger.sync()
}

swagger 组件

这里我试着用了一下 go swagger

项目地址: https://github.com/go-swagger/go-swagger

这个可以使用 scoop 安装

scoop install go-swagger

用着一般,没有 swagger code generator 好用。

就没继续探索下去了。

ps: jetbrains 系的 ide 里有几成 swagger code generator 工具,功能非常强大,可以生成各种代码。

不过我还是自己实现了openapi 文档解析(比较灵活),所以暂时还没用上这个强大的工具。

excel 导出

excel 操作我用的是这个 github.com/xuri/excelize/v2

一开始没注意,后面发现这个居然是奇安信开源的…… 然后看了 qax-os 这个 group ,发现开源的几个项目都是跟安全无关的,不务正业啊老哥!

没有对比其他的,看着 star 挺多,上手就直接用了

感觉还行。

func exporttestreportstoexcel(testreports []*tester.report, filename string) error {
  // 创建一个新的 excel 文件
  f := excelize.newfile()

  // 创建一个名为 "测试报告" 的工作表
  index, err := f.newsheet("测试报告")
  if err != nil {
    return err
  }

  // 设置工作表列名
  f.setcellvalue("测试报告", "a1", "接口名称")
  f.setcellvalue("测试报告", "b1", "接口路径")
  f.setcellvalue("测试报告", "c1", "测试是否通过")
  f.setcellvalue("测试报告", "d1", "耗时(秒)")

  // 遍历测试报告并在工作表中写入数据
  for i, report := range testreports {
    row := i + 2
    f.setcellvalue("测试报告", fmt.sprintf("a%d", row), report.apiname)
    f.setcellvalue("测试报告", fmt.sprintf("b%d", row), report.apipath)
    f.setcellvalue("测试报告", fmt.sprintf("c%d", row), func() string {
      if report.ispassed {
        return "是"
      }
      return "否"
    }())
    f.setcellvalue("测试报告", fmt.sprintf("d%d", row), report.elapsed.seconds())
  }

  // 设置活动工作表
  f.setactivesheet(index)

  // 将 excel 文件保存到磁盘
  err = f.saveas(filename)
  if err != nil {
    return err
  }

  return nil
}

吐槽

三元表达式

我很想吐槽 go 为啥没有三元表达式,用匿名函数真的好繁琐啊!!

据说是因为觉得三元表达式可以写出很多让人看不懂的骚代码,所以 go 不打算支持,因噎废食啊

不过这难不倒我,可以写个函数来模拟,而且现在 go 似乎更新了泛型的功能,不用再拿 interface 来模拟

func if[t any](condition bool, trueval, falseval t) t {
  if condition {
    return trueval
  }
  return falseval
}

使用的时候就

result := if[string](report.ispassed, "成功", "没通过")

支持类型推导,所以 [string] 也可以省略了。

这样前面导出 excel 的代码里的匿名函数就可以改成这样,简洁多了!

f.setcellvalue("测试报告", fmt.sprintf("c%d", row), if(report.ispassed, "是", "否"))

数组排序

本来也不算什么吐槽,属于是挑刺了,go 的排序没那么好用,但也不难用。

用匿名函数可以实现按字段排序,这倒是和 c 语言里用函数指针大同小异,不愧是带 gc 的 c 语言

测试报告的数据结构是这样

// report 测试报告
type report struct {
  apiname  string
  apipath  string
  ispassed bool
  elapsed  time.duration
  response *apiresponse
}

我想对 []*report 数组排序,可以用 sort.slice 方法

// 按照 elapsed 属性排序,从大到小
sort.slice(testreports, func(i, j int) bool {
  return testreports[i].elapsed > testreports[j].elapsed
})

相比之下还是 cs 的 linq 舒服啊

testreports.sort((a, b) => a - b);

小结

就这样吧,很简单的一个小工具,因为还处在 go 的小白阶段,每用一个新的库都会记录一下。

参考资料

uber的go日志库zap使用详解 -golang日志操作库zap的使用详解

以上就是使用go语言开发自动化api测试工具详解的详细内容,更多关于go自动化api测试工具的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com