测试
测试Model层
-
user_test.go
- 测试代码所在文件的名称以
_test结尾 - 对于生产编译,不会包含以
_test结尾的文件 - 对于测试编译,会包含以
_test结尾的文件
- 测试代码所在文件的名称以
-
func TestUpdatesModifiedTime(t *testing.T) {...}- 测试函数名应以
Test开头(需要导出) - 函数名需要表达出被验证的特性
- 测试函数的参数类型是
*testing.T,它会提供测试相关的一些工具
example
// 被测文件 package model import "strings" // Company .. tyep Company struct { ID int `json:"id"` Name string `json:"name"` Country string `json:"country"` } // GetCompanyType .. func (c *Company) GetCompanyType() (result string) { if strings.HasSuffix(c.Name, ".LTD"){ result = "Limited Liability Company" } else { result = "Others" } return }// 测试文件 package model import "testing" func TestCompanyTypeCorrect(t *testing.T) { c := Company { ID: 12345, Name: "ABCD .LTD", Country: "China", } companyType := c.GetCompanyType() if companyType != "Limited Liability Company" { t.Errorf("Company's GetCompanyType Method failed to get correct company type") } } - 测试函数名应以
测试Controller层
-
为了尽量保证单元测试的隔离性,测试不要使用例如数据库、外部
API、文件系统等外部资源 -
模拟请求和响应
-
需要使用
net/http/httptest提供的功能-
NewRequest函数:func NewRequest(method, url string, body io.Reader) (*Request, error)method:HTTP Methodurl:请求的URLbody:请求的Body- 返回的
*Request可以传递给handler函数
-
ResponseRecordertype ResponseRecorder { Code int // 状态码 200、500... HeaderMap http.Header // 响应的header Body *bytes.Buffer // 响应的body Flushed bool //缓存是否被flush了 }- 用来捕获从
handler返回的响应,只是做记录 - 可以用于测试断言
example:
// 被测文件部分 func RegisterRoutes() { http.HandleFunc("/companies", handleCompany) } func handleCompany(w http.ResponseWriter, r *http.Request) { c := model.Company { ID: 123, Name: "Google", Country: "USA", } enc := json.NewEncoder(w) enc.Encode(c) }// 测试文件 func TestHandleCompanyCorrect(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/companies", nil) w := httptest.NewRecoder() handleCompany(w, r) result, _ := ioutil.ReadAll(w.Result().Body) c := model.Company{} json.Unmarshal(result, &c) fi c.ID != 123 { t.Errorf("Failed to handle company correctly!") } } - 用来捕获从
-
性能分析
- 内存消耗
- CPU使用
- 阻塞的goroutine
- 执行追踪
- 还有一个
Web界面:应用的实时数据
import _ "net/http/pprof"
-
设置一些监听的
URL,它们会提供各类诊断信息 -
go tool pprof http://localhost:8000/debug/pprof/heap// 内存- 从应用获取内存
dump:应用在使用哪些内存,它们会去哪
- 从应用获取内存
-
go tool pprof http://localhost:8000/debug/pprof/profile// CPU- CPU的快照,可以看到谁在用CPU
-
go tool pprof http://localhost:8000/debug/pprof/block// goroutine- 看到阻塞的
goroutine
- 看到阻塞的
-
go tool pprof http://localhost:8000/debug/pprof/tarce?seconds=5// trace- 监控这段时间内,什么在执行,什么在调用什么...
部署
go build .
nohup ./it &
或者通过守护进程
sudo vim /etc/systemd/system/go-web.service # (go-web是属于自己起的名)
# go-web.service
[Unit]
Description=GO WEB App running on Ubuntu
[Service]
ExecStart=/home/solenovex/it/it # 启动文件的命令
Restart=always # 设置挂了会自动重启
RestartSec=10 # 重启服务间隔为10秒
killSignal=SIGINT
SyslogIdentifier=go-web-example
User=solenovex # 执行用户
[Install]
WantedBy=multi-user.target