go 测试和文件
- 需求
- 传统测试
- 单元测试
- 牛刀小试
- 总结
- 练习
- 文件介绍
- 打开关闭文件
- 读文件
- 一次性读取文件
- 写文件
- 文件或文件夹是否存在
- 文件拷贝
需求
有一个函数,怎样确认他运行结果是正确的?
func addUpper(n int)int {res := 0for 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 utilimport ("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 testimport ("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 testimport ("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")
}