0%

Go语言开发的小技巧

前言

最近学到了一些Go语言开发时的小技巧,做下记录。

提高下载速度

方法一:科学上网

方法二:配置代理,详情参考《Golang包管理工具》

1
2
3
4
# export GOPROXY=https://goproxy.cn
export GOPROXY=https://goproxy.io
export GO111MODULE=on
go get -v golang.org/x/tools/cmd/goimports

方法三:使用gopm

1
2
go get -v github.com/gpmgo/gopm
gopm get -v golang.org/x/tools/cmd/goimports

编译安装软件

1
2
go build golang.org/x/tools/cmd/goimports
go install golang.org/x/tools/cmd/goimports

自动格式化

Golang希望统一代码风格,因此推出了gofmt工具。gofmt可以格式化单个文件,也可以格式化整个目录下的所有go文件。
除了gofmt工具,go语言中还有一个go fmt命令,该命令是gofmt的简单封装。

在IDEA中,怎样使用gofmt呢?
1、菜单栏,IntelliJ IDEA,Preferences…。
2、Plugins,搜索File,找到File Watchers插件并安装。
3、Tools,File Watchers,添加或修改gofmt模版。

1
2
3
4
5
File type:Go
Scope:Project files
Program:/usr/local/go/bin/gofmt
Arguments:-l -w -s $FilePath$
Output paths to refresh:$FilePath$

4、勾选Enabled。

保存源码时,就会执行代码格式化了。

自动引入依赖包

参考上一节自动格式化,配置 goimports ,自动引入依赖包。

查看文档

如果对一个包或者函数不熟悉,可以使用go doc命令查看文档。比如:

1
go doc http.ListenAndServe

如果想要看一个项目的帮助文档,可以使用godoc工具启动一个文档服务器。

1
2
go get -v golang.org/x/tools/cmd/godoc
godoc -http :6060

测试

Debugging Sucks! Testing Rocks!
Go语言支持三种测试:单元测试、性能测试和http测试,下面分别来看一下。

单元测试

Go语言单元测试函数以Test为前缀,详情参考测试函数

实际开发中推荐使用表格驱动测试,就是把测试数据和测试逻辑分开。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func TestShortFilename(t *testing.T) {
tests := []struct {
in string
expected string
}{
{"???", "???"},
{"filename.go", "filename.go"},
{"hello/filename.go", "filename.go"},
{"main/hello/filename.go", "filename.go"},
}

for _, tt := range tests {
actual := getShortFilename(tt.in)
if strings.Compare(actual, tt.expected) != 0 {
t.Fail()
}
}
}

在IDEA中查看代码覆盖率:
在单元测试函数左边,会出现一个三角箭头,点击它,选择 Run ‘Testxxx’ with Coverage,即可看到代码覆盖率。绿线代表覆盖到了,红线代表没有覆盖到。

也可以使用命令查看代码覆盖率:

1
2
3
go test -coverprofile=c.out
go tool cover
go tool cover html=c.out

性能测试

1、编写性能测试函数,以Benchmark为前缀,详情参考基准测试

2、运行基准测试

1
go test -bench .

3、详细分析(文本)

1
2
go test bench . -cpuprofile cpu.out
go tool pprof -text -nodecount=10 ./cpu.test cpu.out

4、详细分析(图表)

1
2
go tool pprof cpu.out
web

PS:需要安装graphviz,以便生成图表。

http测试

Go语言的http测试使用 net/http/httptest 包,测试方法可以分为两种:一种是使用假的Request/Response,速度快,测试粒度小,适用于测试函数和方法;另外一种是启动http服务器,速度慢,代码覆盖量更大,适用于测试和模拟后端接口。

先说第一种,使用假的Request/Response:
1、已知函数

1
2
3
func HelloHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world"))
}

2、测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import (
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)

func TestHelloHandler(t *testing.T) {
req := httptest.NewRequest("GET", "http://www.voidking.com/", nil)
w := httptest.NewRecorder()
HelloHandler(w, req)
bytes, _ := ioutil.ReadAll(w.Result().Body)

if string(bytes) != "hello world" {
t.Fatal("expected hello world, but got", string(bytes))
}
}

3、运行测试
go test -v .

再说第二种,启动http服务器。
1、已知函数

1
2
3
func HelloHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world"))
}

2、测试代码

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
import (
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)

func TestHelloHandler(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(HelloHandler))
defer ts.Close()

res, err := http.Get(ts.URL)
if err != nil {
t.Fatal(err)
}
bytes, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
t.Fatal(err)
}

if string(bytes) != "hello world" {
t.Fatal("expected hello world, but got", string(bytes))
}
}

3、运行测试
go test -v .

  • 本文作者: 好好学习的郝
  • 本文链接: https://www.voidking.com/dev-golang-skills/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!源站会及时更新知识点及修正错误,阅读体验也更好。欢迎分享,欢迎收藏~