Google资深工程师深度讲解Go语言-测试与性能调优(八)

Google资深工程师深度讲解Go语言-测试与性能调优(八)

大家好,又见面了,我是全栈君。

一.传统测试 vs 表格驱动测试

传统测试

  • 测试数据与测试逻辑混在一起
  • 出错信息不明确
  • 一旦一个数据出错测试全部结束

表格驱动测试

  • 分离的测试数据与测试逻辑
  • 明确的出错信息
  • 可以部分失败
  • go语言的语法使得我们更易实践表格驱动测试

nonerepeating_test.go

package main

import "testing"

func TestSubstr(t *testing.T) {
	tests := []struct {
		s   string
		ans int
	}{
		//normal case
		{"abcabcbb", 3},
		{"pwwkew", 3},

		//edge case
		{"", 0},
		{"bbbb", 1},
		{"abcabcabcd", 4},

		//chainese case
		{"这里是中国", 5},
		{"黑化肥发灰会挥发灰化肥发挥会发黑", 7},
	}
	for _, tt := range tests {
		actual := lenthOfNonRepeatingSubstr(tt.s)
		if actual != tt.ans {
			t.Errorf("got %d for input %s ,expexted %d", actual, tt.s, tt.ans)
		}
	}
}

nonrepeating.go

package main

import "fmt"
//最长不含有重复字符的子串
func lenthOfNonRepeatingSubstr(s string) int {
	lastOccurred := make(map[rune]int)
	start := 0
	maxLength := 0
	for i, ch := range []rune(s) {
		if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
			start = lastI + 1
		}
		if i-start+1 > maxLength {
			maxLength = i - start + 1
		}
		lastOccurred[ch] = i
	}
	return maxLength
}

func main() {
	fmt.Println(lenthOfNonRepeatingSubstr("abcabcbb")) //3
	fmt.Println(lenthOfNonRepeatingSubstr("bbbbb"))    //1
	fmt.Println(lenthOfNonRepeatingSubstr("pwwkew"))   //3
	fmt.Println(lenthOfNonRepeatingSubstr(""))//0
	fmt.Println(lenthOfNonRepeatingSubstr("b"))//1
	fmt.Println(lenthOfNonRepeatingSubstr("abcdef"))//6
	fmt.Println(lenthOfNonRepeatingSubstr("这里是中国"))//5
	fmt.Println(lenthOfNonRepeatingSubstr("一二三二一"))//3
	fmt.Println(lenthOfNonRepeatingSubstr("黑化肥发灰会挥发灰化肥发挥会发黑"))//7
}

运行

TestSubstr报错,??

但是,在命令行可以执行

cd 进入nonrepeating.go和nonerepeating_test.go 所在目录下,输入命令,可以正常执行

go test .

Google资深工程师深度讲解Go语言-测试与性能调优(八)

二.代码覆盖率

执行命令行,52.6%覆盖率

go test -coverprofile=c.out

Google资深工程师深度讲解Go语言-测试与性能调优(八)

Open a web browser displaying annotated source code:打开显示带注释源代码的web浏览器:

 go tool cover -html=c.out

Google资深工程师深度讲解Go语言-测试与性能调优(八)

性能测试,执行命令行,每个操作725纳秒

go test -bench .

Google资深工程师深度讲解Go语言-测试与性能调优(八)

 

参考: 关于golang性能调试及pprof可视化

 go test -bench . -cpuprofile cpu.out  //输出生成out后缀的文件
 go tool pprof cpu.out //查看文件内容,多种方式,

Google资深工程师深度讲解Go语言-测试与性能调优(八)Google资深工程师深度讲解Go语言-测试与性能调优(八)

Google资深工程师深度讲解Go语言-测试与性能调优(八)输入”web”报错:failed to execute dot. Is Graphviz installed? Error: exec: “dot”: executable file not found in $PATH

解决方法:

mac环境:

此时可用如下命令安装Graphviz

sudo apt install graphviz

其中web命令用以图形展示接口之间的调用关系以及性能情况,但是需要安装Graphviz图形化工具,以我目前的系统为Ubuntu为例,直接执行sudo apt-get install graphviz命令即可安装完成图形化工具,随后再次使用web命令,最终生成以下图表:

然后再次输入web,那么会在web页面看到Google资深工程师深度讲解Go语言-测试与性能调优(八)

file:///private/var/folders/w9/l38fmd696n95tmrt4pf980vm0000gn/T/pprof001.svg

Google资深工程师深度讲解Go语言-测试与性能调优(八)

同样输入:pdf,png,也会生成对应的文件

Google资深工程师深度讲解Go语言-测试与性能调优(八)

 

总结:

  • testing.T的使用
  • 运行测试
  • 使用ide查看代码覆盖
  • 使用go test获取代码覆盖报告
  • 使用go tool cover查看代码覆盖报告
  • 使用test.B的使用
  • 使用pprof优化性能

三.测试HTTP服务器

go test -coverprofile=c.out 生成覆盖文件

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"strings"
	"testing"
)

func errPanic(writer http.ResponseWriter, request *http.Request) error {
	panic(123)
}

type testingUserError string

func (e testingUserError) Error() string {
	return e.Message()
}
func (e testingUserError) Message() string {
	return string(e)
}

func errUserErrot(writer http.ResponseWriter, request *http.Request) error {
	return testingUserError("user error")
}

func errNotFound(writer http.ResponseWriter, request *http.Request) error {
	return os.ErrNotExist
}

func errNoPermission(writer http.ResponseWriter, request *http.Request) error {
	return os.ErrPermission
}

func errUnknown(writer http.ResponseWriter, request *http.Request) error {
	return errors.New("unknown error")
}

func noError(writer http.ResponseWriter, request *http.Request) error {
	fmt.Println(writer, "no error")
	return nil
}
var tests = []struct {
	h       appHandler
	code    int
	message string
}{
	{errPanic, 500, "Internal server Error"},
	{errUserErrot, 400, "user Error"},
	{errNotFound, 404, "Not found"},
	{errNoPermission, 403, "Forbidden"},
	{errUnknown, 500, "Internal server Error"},
	{noError, 200, "NO Error"},
}

func TestErrWrapper(t *testing.T) {
	for _, tt := range tests {
		f := errWrapper(tt.h)
		response := httptest.NewRecorder()
		request := httptest.NewRequest(http.MethodGet, "http://www.imooc.com", nil)
		f(response, request)

		verfyResponse(response.Result(),tt.code,tt.message,t)

	}
}

func TestErrWrapperInServer(t *testing.T){
	for _, tt:=range tests {
		f:=errWrapper(tt.h)
		server:=httptest.NewServer(http.HandlerFunc(f))
		resp,_:=http.Get(server.URL)

		verfyResponse(resp,tt.code,tt.message,t)

	}
}

func verfyResponse(resp *http.Response,expectedCode int,expectedMsg string,t *testing.T)  {
	b, _ := ioutil.ReadAll(resp.Body)
	body := strings.Trim(string(b), "\n")
	if resp.StatusCode != expectedCode || body != expectedMsg {
		t.Errorf("expect (%d,%s);got(%d,%s)", expectedCode, expectedMsg, resp.StatusCode, body)
	}
}

go tool cover -html=c.out 在web浏览器显示具体的覆盖率和具体覆盖部分

Google资深工程师深度讲解Go语言-测试与性能调优(八)

http测试

  • 通过使用假的request/response(在httptest库中,速度快,密度细,像单元测试)
  • 通过起服务器(集成度高,代码覆盖量大)

四.查看文档

go doc
go help doc //帮助文档

Google资深工程师深度讲解Go语言-测试与性能调优(八)

 

连起来的godoc,比较有用

输入godoc 报错,bash: godoc: command not found,

原因:没有安装godoc

解决方法:

关于godoc 不是内部命令问题解决

首先,该命令无效的原因是go 1.13 版本后 移除了godoc相关的一些命令,因此需手动安装
下面是安装使用该命令的方法:

第一步

进入命令行
输入下面两行代码

go env -w GO111MODULE=on
go env -w GOPROXY="https://goproxy.io,direct"
Go Modules
简介
Go 在 1.11 版本引入了新的依赖管理模式 Go Modules,旨在解决一直广为诟病的依赖管理问题。

使用下列命令启用 Go Modules

go env -w GO111MODULE=on # 不建议设为 auto ;on 打开 off 关闭 auto自动 
这是持久性设定,环境变量 GOENV 指示配置文件位置。

Go Modules 采用语义化版本,详见 https://semver.org/lang/zh-CN/ 。

第二步

命令行输入,安装godoc

go get golang.org/x/tools/cmd/godoc
  • 安装完成后即可使用godoc命令,生成文档
sudo apt-get install golang-doc //方法一
sudo apt-get install golang-go.tools //方法二
go get -v  golang.org/x/tools/cmd/godoc //方法三

godoc -http= :6060   //在浏览器 访问 http://localhost:6060

Google资深工程师深度讲解Go语言-测试与性能调优(八)

sudo vi ~/.profile  //编辑用户的配置文件
source ~/.profile  //加载配置信息,使生效

Google资深工程师深度讲解Go语言-测试与性能调优(八)

在命令行执行godoc -http=localhost:6060后, 直接在浏览器,访问 http://localhost:6060/pkg/

Google资深工程师深度讲解Go语言-测试与性能调优(八)

  • 用注释写文档
  • 在测试中加入example
  • 使用go doc/godoc 来查看/生成文档

自己文件文档: http://localhost:6060/pkg/study/queue/

Google资深工程师深度讲解Go语言-测试与性能调优(八)

示例函数,以Example开头,没有参数也没有结果。

1.作为文档

2.可以通过go test运行的可执行测试

3.提供手动实验代码

参考:testing – 运行并验证示例

示例,一方面是文档的效果,是关于某个功能的使用例子;另一方面,可以被当做测试运行。

package queue

import "fmt"

func ExampleQueues_Pop() {
	q := Queue{1}
	q.Push(2)
	q.Push(3)
	fmt.Println(q.Pop())
	fmt.Println(q.Pop())
	fmt.Println(q.IsEmpty())

	fmt.Println(q.Pop())
	fmt.Println(q.IsEmpty())

	//Output:
	//1
	//2
	//false
	//3
	//true

}

通过: go test  执行该示例, 注意 Output 首字母大写

输出:与结果不一致

Google资深工程师深度讲解Go语言-测试与性能调优(八)

输出:与结果一致

Google资深工程师深度讲解Go语言-测试与性能调优(八)

五.测试总结

  • 表格驱动测试:
  • 代码覆盖:go test -coverprofile=c.out  go tool cover -html=c.out
  • 性能优化工具: go test -bench .
  • http测试
  • 文档以及示例代码
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/111709.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • awk基本语法

    awk基本语法

  • OpenCV 的颜色空间转换

    OpenCV 的颜色空间转换

    2021年11月21日
  • 2012服务器系统密钥,WINDOWS SERVER 2012标准版密钥[通俗易懂]

    2012服务器系统密钥,WINDOWS SERVER 2012标准版密钥[通俗易懂]js获取浏览器内核、类型、版本以及系统类型正则表达式:varrsys=/\b(windows|win32|macintosh|macosx|adobeair|linux|unix)\b/;varrkn=/\b(opera|…docker组件(c/s)Docker组件1.dockerclient:docker…

  • Stimulsoft Reports.Web.JS 2022.2.5

    Stimulsoft Reports.Web.JS 2022.2.5Stimulsoft2022.2.5Publishedon13May2022Reports.WebReports.NetReports.WpfReports.JSReports.PHPReports.JavaReports.BlazorReports.AngularDashboards.WEBDashboards.WINDashboards.JSDashboards.PHPBIDesignerBICloudBIServerN..

  • Ogre1.7.2 + CEGUI0.7.5配置[通俗易懂]

    Ogre1.7.2 + CEGUI0.7.5配置[通俗易懂]转载请说明出处!http://blog.csdn.net/zhanghua1816/article/details/6650509鉴于现在很多朋友开始学习研究Ogre或者CEGUI,不过很多朋友对如何配置这两个环境有很多问题,所以我把配置方法在此简单介绍一下,希望对大家有用,分享是一种快乐,大家共同进步嘛~~~。我这里的这种方法可能不是最简单的配置方法,但是我相信这种配置方法或许对

  • MySQL读写分离的原理

    MySQL读写分离的原理1.为什么要实现MySQL的读写分离?因为实际上大多是互联网公司,一些网站或者是app,其实都是读多写少,所以针对这个情况,就是写请求是一个主库,但是主库挂多个从库,然后从多个从库来读,这样可以提高MySQL的并发。2.如何实现MySQL的读写分离?就是基于主从复制架构,简单就是之搞一个主库,然后主库挂多个从库,我们单单只是写主库,然后主库会自动把数据给同步到从库上去。…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号