基本介绍
go语言自带一个轻量级的测试框架testing 和自带go test命令来实现单元测试和性能测试,通过单元测试可以解决以下问题
- 确保每个函数是可运行的,并且运行是正确的
- 确保写出来的代码性能是最好的
- 单元测试能及时发现程序设计或逻辑的错误,使问题及早暴露
注意事项
1、测试用例文件名必须以_test.go结尾,例如demo_test.go
2、测试用例函数必须以Test开头,一般来说就是Test+被测试的函数名(Test后面的第一个字符不能是小写的[a-z],如Testclac 这种就是错误 TestCalc 正确),例如TestCalc
3、TestCalc函数的形参必须是*testing.T,例如TestCalc(t *testing.T)
4、一个测试文件中,可以包含多个测试函数 如:testClac(t *testing.T),TestToLower(t *testing.T)…
5、运行测试用例指令(打开dos命令窗口,进入到该测试用例文件位置):
a、go test 【运行正确,无日志,错误有日志】
b、go test -v 【正确错误都有日志】
6、当出现错误时,可以用t.Fatalf来格式化输出错误信息,并退出程序
7、t.Logf可以格式化输出相应的日志
8、PASS表示测试用例通过,FAIL表示测试用例未通过
9、测试单个文件时,一定要带上被测试的原文件,如:test go -v clac_test.go calc.go
10、测试单个方法:go test -v -test.run TestCalc
dmeo
1、待测试文件 monster.go
package main
import (
"bufio"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
)
type Monster struct {
Name string `json:"name"`
Age int `json:"age"`
Skill string `json:"skill"`
}
//将结构体序列化后保存在文件中
func (this *Monster) Store() error {
str,err := json.Marshal(this)
if err != nil {
return errors.New(fmt.Sprintf("结构体转json错误,err:%v",err))
}
//将json保存在文件中
return this.PutFile("E:/goWork/src/newStudy/testing/monster/log.txt",string(str))
}
func (this *Monster)PutFile(fileName,content string) error{
if fileName == "" || content == "" {
//文件名或者问价内容不存在
return errors.New("文件名或者问价内容不存在")
}
file,err := os.OpenFile(fileName,os.O_WRONLY|os.O_CREATE|os.O_TRUNC,0666)
if err != nil {
return errors.New(fmt.Sprintf("打开文件句柄错误,err:%v",err))
}
//关闭文件
defer file.Close()
//将文件加入到缓冲区中
write := bufio.NewWriter(file)
//将需要写的内容加入到缓冲区
_,err = write.WriteString(content)
if err != nil {
return errors.New(fmt.Sprintf("文件写入到缓冲区失败,err:%v",err))
}
//落盘
err = write.Flush()
if err != nil {
return errors.New(fmt.Sprintf("文件落盘失败,err:%v",err))
}
return nil
}
func (this *Monster)ReStore(fileName string) (Monster,error) {
var mon Monster
//判断文件是否存在
_,err := os.Stat(fileName)
if err != nil {
return mon,errors.New(fmt.Sprintf("文件不存在,err:%v",err))
}
//获取文件内容
byt,err := ioutil.ReadFile(fileName)
if err != nil {
return mon,errors.New(fmt.Sprintf("文件读取失败,err:%v",err))
}
//将字符切片转换为结构体
err = json.Unmarshal(byt,&mon)
if err != nil {
return mon,errors.New(fmt.Sprintf("序列化失败,err:%v",err))
}
return mon,nil
}
func main() {
monster := Monster{
Name:"gangan",
Age:18,
Skill:"都会",
}
err := monster.Store()
//mon,err := monster.ReStore("testing/monster/log.txt")
if err != nil {
fmt.Println(err)
}
//fmt.Println(mon)
}
2、单元测试文件 monster_test.go(一定要以_test.go结尾,单元测试文件)
package main
import "testing"
func TestMonster(t *testing.T) {
monster := Monster{"gangan",18,"都会"}
err := monster.Store()
if err != nil {
t.Fatalf("用例测试失败,期望是nil,结果是%v",err)
}
t.Log("用例测试成功")
}
func TestReStore(t *testing.T){
var monster Monster
mon,err := monster.ReStore("E:/goWork/src/newStudy/testing/monster/log.txt")
if err != nil {
t.Fatalf("用例测试失败,期望是nil,结果是%v",err)
}
if mon.Name != "gangan" {
t.Fatalf("用例测试失败,期望的name是gangan,结果是%v",mon.Name)
}
t.Log("用例测试成功")
}
3、调用命令测试方法(*一定要进入当前单元测试目录下执行命令)
E:\goWork\src\newStudy\testing\monster>go test -v
=== RUN TestMonster
--- PASS: TestMonster (0.00s)
monster_test.go:12: 用例测试成功
=== RUN TestReStore
--- PASS: TestReStore (0.00s)
monster_test.go:26: 用例测试成功
PASS
ok _/E_/goWork/src/newStudy/testing/monster 0.140s