需求
有一个函数,怎样确认他运行结果是正确的?
func addUpper(n int)int {
res := 0
for i := 1; i <= n; i++ {
res+=1
}
return res
}
传统测试
在main中测试
缺点
- 不方便
- 不利于管理
单元测试
Go语言中自带有一个轻量级的测试框架testing和自带的go test命令来实现单元测试和性能测试,testing框架和其他语言中的测试框架类似,可以基于这个框架写针对相应函数测测试用例,也可以基于该框架写相应的压力测试用例,解决如下问题:
- 确保每个函数可行性
- 确保代码性能是好的
- 及时规避问题
牛刀小试
import (
"testing"
"wiaf.org/zhouhongjie/demo1/util"
)
func TestAddUpper(t *testing.T) {
res := util.AddUpper(3)
if res != 55 {
t.Fatalf("Addupper(3) 执行错误,期望值 %v 实际值 %v ", 55, res)
}
t.Logf("Addupper(3) 运行正确")
}
func TestOk(t *testing.T) {
t.Logf("测试TestOk 运行正确")
}
cd 到一 _test.go
结尾的目录下,执行 go test -v
,其下每一个测试用例方法都会执行
总结
- 测试用例文件必须以 _test.go 结尾
- 测试用例方法 必须是 TestXxx 的格式
- 一个测是用例可以有多个测试用例函数
- go test -v 会输出正确或错误的;go test 只会输出错误的
- 测试某个文件(这里测试两个) go test -v cal_test.go cal.go
- 测试某个方法 go test -v -test.run TestAddUpper
练习
package util
import (
"encoding/json"
"log"
)
type Monster struct {
Name string `json:"name"`
Age string `json:"age"`
Skill string `json:"skill"`
}
func Serialize(monster Monster) string {
marshal, err := json.Marshal(monster)
if err != nil {
log.Fatalf("序列化失败 ", err)
}
return string(marshal)
}
func UnSerialize(strMonster string) (monster *interface{}) {
err := json.Unmarshal([]byte(strMonster), monster)
if err != nil {
log.Fatalf("反序列化失败 ", err)
}
return monster
}
package test
import (
"testing"
"wiaf.org/zhouhongjie/demo1/util"
)
func TestSerialize(t *testing.T) {
monster := util.Monster{
Name: "牛魔王",
Age: "13",
Skill: "牛角功",
}
serialize := util.Serialize(monster)
t.Logf(serialize)
}
func TestUnSerialize(t *testing.T) {
monster := util.UnSerialize("{\"name\":\"牛魔王\",\"age\":\"13\",\"skill\":\"牛角功\"}")
u, ok := (*monster).(util.Monster)
if ok {
t.Log("转换成功 ", u)
} else {
t.Log("转换失败 ", u)
}
}
文件介绍
文件在程序中以流的形式来操作的
输入流:程序 -> 文件
输出流:文件 -> 程序
os.File 封装文件相关操作
打开关闭文件
func TestFileBaseOpr(t *testing.T) {
file, err := os.Open("/Users/mac/Desktop/diagram")
defer func(file *os.File) {
err := file.Close()
if err != nil {
t.Fatal("关闭文件错误", err)
}
}(file)
if err != nil {
t.Fatal("打开文件失败", err)
}
t.Log("文件名称 ", file.Name())
}
读文件
func TestFileBaseOpr(t *testing.T) {
file, err := os.Open("/Users/mac/go/src/wiaf.org/zhouhongjie/demo1/main/main.go")
defer func(file *os.File) {
err := file.Close()
if err != nil {
t.Fatal("关闭文件错误", err)
}
}(file)
if err != nil {
t.Fatal("打开文件失败", err)
}
t.Log("文件名称 ", file.Name())
reader := bufio.NewReader(file)
for {
readString, err := reader.ReadString('\n')
if err == io.EOF {
break
}
t.Log(readString)
}
}
一次性读取文件
func TestFileBaseOpr(t *testing.T) {
// 这个包里边都过期了
file, err := ioutil.ReadFile("/Users/mac/go/src/wiaf.org/zhouhongjie/demo1/test/cal1_test.go")
if err != nil {
t.Fatal("读取文件失败", err)
}
t.Log(string(file))
}
写文件
func TestFileBaseOpr(t *testing.T) {
file, err := os.OpenFile("./text.txt", os.O_CREATE|os.O_APPEND, 0777)
defer func(file *os.File) {
err := file.Close()
if err != nil {
t.Fatal("关闭失败", err)
}
}(file)
if err != nil {
t.Fatal("打开失败", err)
}
writer := bufio.NewWriter(file)
_, err = writer.Write([]byte("hello world"))
if err != nil {
t.Fatal("写入失败", err)
}
err = writer.Flush()
if err != nil {
t.Fatal("刷盘失败", err)
}
}
文件或文件夹是否存在
func PathExists(path string) (bool, error) {
_, err := os.Stat("./text.txt")
if err == nil {
return true,nil
}
if os.IsNotExist(err){
return false,nil
}
return false,err
}
文件拷贝
package test
import (
"bufio"
"fmt"
"io"
"os"
"testing"
)
func CopyFile(dstFileName string, srcFileName string) (written int64, err error) {
srcFile, err := os.Open(srcFileName)
if err != nil {
fmt.Print("open file error", err)
}
reader := bufio.NewReader(srcFile)
dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Printf("open file err = %v", err)
return
}
writer := bufio.NewWriter(dstFile)
defer dstFile.Close()
return io.Copy(writer, reader)
}
func TestFileBaseOpr(t *testing.T) {
CopyFile("./text.mp4", "/Users/mac/Desktop/硬件基础/day01/03_电学基础_电阻.mp4")
}