golang分层测试之http接口测试入门教程
在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《golang分层测试之http接口测试入门教程》,聊聊测试、http接口、分层测试,希望可以帮助到正在努力赚钱的你。
前言
前几话主要讲解关于使用golang进行单元测试,在单元测试的上一层就是接口测试,本节主要讲使用golang进行接口测试,其中主要以http协议的接口测试来讲解
golang中的http请求
golang中拥有一个原生的http依赖库:net/http,http服务器的建立还是http客户端的开发,都会使用到这个依赖库,这里主要讲解时client部分,作为请求发起方应用于日常的接口测试,例示代码如下:
get请求
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
//模拟一个get提交请求
resp, err := http.Get("http://127.0.0.1:12345/checkon")
if err != nil {
panic(err)
}
defer resp.Body.Close() //关闭连接
body, err := ioutil.ReadAll(resp.Body) //读取body的内容
fmt.Println(string(body))
}
返回结果
E:\go_project>go run testget.go
{
"code": 200,
"data": "",
"msg": "online",
"state": "success"
}
post请求:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {
//模拟一个post提交请求
resp, err := http.Post("http://www.baidu.com", "application/x-www-form-urlencoded", strings.NewReader("id=1"))
if err != nil {
panic(err)
}
//关闭连接
defer resp.Body.Close()
//读取报文中所有内容
body, err := ioutil.ReadAll(resp.Body)
//输出内容
fmt.Println(string(body))
}
上面的post请求以form的方式,最后会返回一个页面
这里说明一下以下这行代码
defer resp.Body.Close()
首先是defer, Go的defer语句用来调度一个函数调用(被延期的函数),使其在执行defer的函数即将返回之前才被运行,被延期执行的函数,它的参数(包括接受者)实在defer执行的时候被求值的,而不是在调用执行的时候。也就是说被延期执行的函数的参数是按正常顺序被求值的,简单理解为,无论defer对应的代码行放在代码段的哪个位置,defer是在return前执行的代码行,但defer代码行中的参数是需要先声明再调用的,对应响应中的处理,golang的Response.Body需要被关闭的,body实际上是一个嵌套了多层的net.TCPConn:
- bufio.Reader,这层尝试将多次小的读操作替换为一次大的读操作,减少系统调用的次数,提高性能;
- io.LimitedReader,tcp连接在读取完body后不会关闭,继续读会导致阻塞,所以需要LimitedReader在body读完后发出eof终止读取;
- chunkedReader,解析chunked格式编码(如果不是chunked略过);
- bodyEOFSignal,在读到eof,或者是提前关闭body时会对readLoop发出回收连接的通知;
- gzipReader,解析gzip压缩(如果不是gizp压缩略过);
从上面可以看出如果body既没有被完全读取,也没有被关闭,那么这次http事务就没有完成,除非连接因超时终止了,否则相关资源无法被回收,所以需要我们进行关闭连接的操作,这个是很多golang新手会忽略的一个点,作为client端处理response的时候,body一定要close,否则会造成GC回收不到,继而产生内存泄露
带json的post请求
我们大部分应用到的restful接口都是用json格式的请求体,对应的golang的http请求也会有相关的方式post json请求体
package main
import (
"fmt"
"io/ioutil"
"net/http"
"bytes"
"encoding/json"
)
type HttpData struct {
Flag int `json:"flag"`
Msg string `json:"msg"`
}
func main() {
url := "http://127.0.0.1:12345/postdata"
contentType := "application/json;charset=utf-8"
var httpdata HttpData
httpdata.Flag = 1
httpdata.Msg = "terrychow"
b ,err := json.Marshal(httpdata)
if err != nil {
fmt.Println("json format error:", err)
return
}
body := bytes.NewBuffer(b)
resp, err := http.Post(url, contentType, body)
if err != nil {
fmt.Println("Post failed:", err)
return
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Read failed:", err)
return
}
fmt.Println("header:", resp.Header)
fmt.Println("content:", string(content))
}
执行结果响应
E:\go_project>go run gohttptest.go
header: map[Content-Type:[application/json] Content-Length:[78] Server:[Werkzeug/0.14.1 Python/2.7.15] Date:[Thu, 06 Dec 2018 16:35:11 GMT]]
content: {
"code": 200,
"data": 1,
"msg": "terrychow",
"state": "success"
}
对于常用的get和post请求基本上就以照上面的版本执行,当然我们现在需要做的是http接口的测试,那就需要引入测试框架进行相关的校验,本文先讲解用之前提到的gocheck来进行断言
golang中的http接口测试
引入gocheck之后我们得到了以下的脚本:
package hello_test
import (
"testing"
"fmt"
"strconv"
"io/ioutil"
"net/http"
"bytes"
"encoding/json"
. "gopkg.in/check.v1"
)
var a int =1
// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }
type MySuite struct{}
type HttpData struct {
Flag int `json:"flag"`
Msg string `json:"msg"`
}
var _ = Suite(&MySuite{})
var testurl string ="http://127.0.0.1:12345"
func (s *MySuite) SetUpSuite(c *C) {
str3:="第1次套件开始执行"
fmt.Println(str3)
//c.Skip("Skip TestSutie")
}
func (s *MySuite) TearDownSuite(c *C) {
str4:="第1次套件执行完成"
fmt.Println(str4)
}
func (s *MySuite) SetUpTest(c *C) {
str1:="第"+strconv.Itoa(a)+"条用例开始执行"
fmt.Println(str1)
}
func (s *MySuite) TearDownTest(c *C) {
str2:="第"+strconv.Itoa(a)+"条用例执行完成"
fmt.Println(str2)
a=a+1
}
func (s *MySuite) TestHttpGet(c *C) {
geturl := fmt.Sprintf("%v/checkon", testurl)
respget, err := http.Get(geturl)
if err != nil {
panic(err)
}
defer respget.Body.Close() //关闭连接
body, err := ioutil.ReadAll(respget.Body) //读取body的内容
var gdat map[string]interface{} //定义map用于解析resp.body的内容
if err := json.Unmarshal([]byte(string(body)), &gdat); err == nil {
fmt.Println(gdat)
} else {
fmt.Println(err)
}
var gmsg=gdat["msg"]
c.Assert(gmsg, Equals, "terrychow") //模拟失败的断言
}
func (s *MySuite) TestHttpPost(c *C) {
url := fmt.Sprintf("%v/postdata", testurl)
contentType := "application/json;charset=utf-8"
var httpdata HttpData
httpdata.Flag = 1
httpdata.Msg = "terrychow"
b ,err := json.Marshal(httpdata)
if err != nil {
fmt.Println("json format error:", err)
return
}
body := bytes.NewBuffer(b)
resp, err := http.Post(url, contentType, body)
if err != nil {
fmt.Println("Post failed:", err)
return
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Read failed:", err)
return
}
var dat map[string]interface{} //定义map用于解析resp.body的内容
if err := json.Unmarshal([]byte(string(content)), &dat); err == nil {
fmt.Println(dat)
} else {
fmt.Println(err)
}
var msg=dat["msg"]
c.Assert(msg, Equals, "terrychow") //模拟成功的断言
}
最后的输出内容:
E:\go_project>go test -v gocheckhttp_test.go === RUN Test 第1次套件开始执行 第1条用例开始执行 map[code:200 data: msg:online state:success] 第1条用例执行完成 ---------------------------------------------------------------------- FAIL: gocheckhttp_test.go:56: MySuite.TestHttpGet gocheckhttp_test.go:72: c.Assert(gmsg, Equals, "terrychow") ... obtained string = "online" ... expected string = "terrychow" 第2条用例开始执行 map[msg:terrychow state:success code:200 data:1] 第2条用例执行完成 第1次套件执行完成 OOPS: 1 passed, 1 FAILED --- FAIL: Test (0.02s) FAIL FAIL command-line-arguments 0.613s
输出的结果符合预期,这也是比较基本的http接口测试
小结
就上文来说,我们基本可以通过本文掌握如何做http接口测试,其核心还是使用http依赖库发出请求获取响应,利用gocheck进行断言,当然还可以用testing,下一节继续讲一下http接口测试,但会重点讲专门做http接口测试的测试框架httpexpect以及用于mock的httptest,希望对大家的学习有所帮助,也希望大家多多支持golang学习网。
到这里,我们也就讲完了《golang分层测试之http接口测试入门教程》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于golang的知识点!
Golang学习笔记之延迟函数(defer)的使用小结
- 上一篇
- Golang学习笔记之延迟函数(defer)的使用小结
- 下一篇
- golang如何使用struct的tag属性的详细介绍
-
- Golang · Go教程 | 33分钟前 | 格式化输出 printf fmt库 格式化动词 Stringer接口
- Golangfmt库用法与格式化技巧解析
- 140浏览 收藏
-
- Golang · Go教程 | 34分钟前 |
- Golang配置Protobuf安装教程
- 147浏览 收藏
-
- Golang · Go教程 | 36分钟前 |
- Golang中介者模式实现与通信解耦技巧
- 378浏览 收藏
-
- Golang · Go教程 | 41分钟前 |
- Golang多协程通信技巧分享
- 255浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Golang如何判断变量类型?
- 393浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Golang云原生微服务实战教程
- 310浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Golang迭代器与懒加载结合应用
- 110浏览 收藏
-
- Golang · Go教程 | 2小时前 | 性能优化 并发安全 Golangslicemap 预设容量 指针拷贝
- Golangslicemap优化技巧分享
- 412浏览 收藏
-
- Golang · Go教程 | 2小时前 |
- Golang代理模式与访问控制实现解析
- 423浏览 收藏
-
- Golang · Go教程 | 2小时前 |
- Golang事件管理模块实现教程
- 274浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3162次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3375次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3403次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4506次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3784次使用
-
- 详解Go 语言如何通过测试保证质量
- 2022-12-29 290浏览
-
- Golang 单元测试和基准测试实例详解
- 2022-12-23 275浏览
-
- GoLang基础学习之go test测试
- 2023-01-01 265浏览
-
- Go语言单元测试超详细解析
- 2023-01-07 185浏览
-
- Golang单元测试与覆盖率的实例讲解
- 2022-12-31 156浏览

