开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:单元测试综合案例】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/626/detail/9744
单元测试综合案例
一,单元测试综合案例要求
(1)编写一个 Monster 结构体,字段 Name, Age, Skill
(2)给 Monster 绑定 方法 Store,可以将-个 Monster 变量(对象),序列化后保存到文件中。
(3)给 Monster 绑定方法 ReStore,可以将一个序列化的 Monster,从文件中试取,并反序列化为 Monster 对象,检查反序列化,名字正确。
(4)编程测试用例文件 store_ test.go ,编写测试用例函数 TestStore 和TestRestore 进行测试。
代码实现:
第一步:创建 testcase02,测试文件monster-test.go monster.go
package monster
import
(
"encoding/
json“
“io/ioutil”
"fmt"
第二步:有名字,有年龄,小写时麻烦要用大写type Monster strupt {
Name string
Age int
skill string
第三步:绑定方法
//给 Monster 绑定方法 store,可以将个 Monster 变量(对象),序列化后保存到文件中func (this *monster) store()
error
{
//先序列化
data, err := json.
m
arshal(this)
if err!= nil {
fmt. Println("marshal err =", err)
return false
}
说明:可将错误信息表明出来
//保存到文件
filePath
:
= "d:/monster. ser"
ioutil.WrsteFile(flePath, data,066)
if err != nil {
fmt.PrintIn("write file err =",err)
return fals
e
}
return ture
说明:直接用 ioutil. 里的方法
//给 Monster 绑定方法 Restore,可以将一 个序列化的 Monster,从文件中读取,
//并反序列化为 Monster 对象检查反序列化,名字正确
func (this *Monster) ReStore() bool {
1.先从文件中,读取序列化的字符串
filePath := "d: /monster .ser"
data, err := lout1l.ReadFile(f1lePath)
if err != nil {
fmt.PrintIn("ReadFile err ="
eturn false
}
2.使用读取到 data []byte ,对反序列化err . Json.UnMarshal(data, th1s)
if err != nil {
fmt.Printn("UnNarshal er s". err)
return false
}
return true
}
package ioutil
import "io/ioutil"
Package ioutil implements some I/O tilly functions.
Index
返回首页
Unmarshal 函数解析 json 编码的数据并将结果存入 v 指向的值。
UnmarshaloMarshal 做相反的操作,必要时申请映射、切片或指针,有如下的附加规则:
要将 json 数据解码写入一个指针,Unmarshal 函数首先处理 json 数据是 json 字面值 null 的情况。此时,函数将指针设为 nil ;否则,函数将 json 数据解码写入指针指向的值;如果指针本身是 nil ,四数会先申请一个值并使指针指向它。
要将 json 数据解码写入一个结构体,函数会匹配输入对象的键和Marshal 使用的键(结构体字段名或者它的标签指定的键名),优先选择精确的匹配 ,但也接受大小写不敏感的匹配。
要将 json 数据解码写入-个接口类型值,函数会将数据解码为如下类型写入接口:
Bool 对应 ISON 布尔类型
float64 对应 OSON 数字类型
string 对应 JSON 字符串类型
[]interface{}对应 JSON 数组
map[string]interface{}对应SON对象 nil 对应 JSON 的 null
如果一个 JSON 值不匹配给出的目标类型,或者如果一个 json 数字写入目标关型时溢出, Unmarshal 函数会跳过该字段并尽量完成其余的解码操作。如果没有出现更加严重的错误,本函数会返回一个描述第一个此类错误的详细信息的 UnmarshalTypeError.
JSONe 的 nul 值解码为 go 的接口、指针、切片时会将它们设为 nil ,因为 nul 在 json 里一股表示 不存在。解码 son 的null值到其他g0类型时,不会造成任何改变,也不会产生错误。
testing提供对GO包的自动化测试的支持。通过 "go test' 命令,能够自动执行如下形式的任何函数:func Testxx("testing.T)
其中Xxx可以是任何字母数字字符串(但第一个字母不能是[a-z]) , 用于识别测试例程。
在这些函数中,使用 Error, Fail 或相关方法来发出失败信号.
要编写-个新的测试套件 ,需要创建- 个名称以_test.go 结尾的文件 ,该文件包含'TestxXxx 函数,如上所述。将该文件放在与被测试的包相同的包中。该文件将被排除在正常的程序包之外,但在运行"go test 命令时将被包含。有关详细信息, 请运行"go help test"和"go help testtlag"了解。
如果有需要,可以调用T和"B的Skip方法,跳过该测试或基准测试:
第一步:创建monster包
package monster
import (
"testing"
)
第二步:测试,首先创建一个monster,输入名字,年龄,必杀技
//测试用例,测试store方法func Teststore(t *testing.T) {
//先创建一个 Monster 实例monster := &Monster{
Name :“红孩儿”。
Age :10,
skill : "吐火.”,
}
第三步:直接用store调res := monster . Store()
第四步:进行测试t. Logf( "monster . store()测试成功!")
}
第五步:通过monster调用restore
func TestRestore(t *testing.T) {
//先创建一个 Monster 实例,不需要指定字段的值var monster = &Monster{}
res := monster. ReStore()
说明:如果结果错误返回真if !res {
t.Fatalf("monster ReStore()错误,希望为=%v实际为=%V", true, res)
}
第六步:最后进一步判断
//进步判断if monster.Name != "红孩儿”{
t. Fatalf( "monster . Restore()错误,希望为=%v 实际为=%v",“红孩儿”,monster.Na
}
t. Logf( "monster. ReStore()测试成功!")
}
cal_test.go对 cal.go 的函数进行测试function TestAUpper(t*testing.T)
testing
框架将 xxx_test.go 的文件引入import…main(){//调用 Testxxx()函数}
意思就是说一种情况去测试一个,比如 up 这个函数,其实它用了很多其他地方的,例如有一个张三写的,这一行张三里面他写了一个文件,叫张三.go,或者李四.go,这个李四和张三里面有很多函数,它有它自己的函数,然后,在测这个函数的时候,这个开始 up 这个函数,这个函数里面他又去调用了李四的,。这个函数一,甚至它有可能用了函数三,甚至还用到了函数二。就是当测试这个地方的时候,可能这个结果他是不正确的,这个结果到底是这个函数带来的,还是张三的函数一,还是函数二的错误,这样就不太好定位。
关于这个问题,他解决方案第一种就是细化,细化就是这个张三写一个函数,这个函数一完成,它一定会有一个准确的结果,这点必须要接受。也就是说一个比较简单方法,虽然不能退,但是可以先测,每一个都刻一个严谨的一个产品,或者是这个产品本身,它这个很重要,那么肯定每个人都应该做一个小测试,他确保他的这个没问题,那么有问题的话再测,如果一旦错了,肯定是他的错误,这是一个方案。
第二个是刚才每个月也是有适当的日志,也因为在调查,他本质仍然是通过调查那里出错了,这个错误日志能够体现出来的也能看到这个日志,看到的信息很详细,什么时间,哪个文件,哪个模块,甚至可以直接的把它打出来的,一般都有这个功能。现在日志都可以自定义的假象,他都会这样说是哪个文件哪个函数可以看到是哪一行也可以定位这两个,方式都可以解决。