这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
1.测试类型
1.单元测试
在测试开发阶段,开发者对单独的函数或模块进行测试验证。
2.集成测试
对系统功能维度进行测试验证。
3.回归测试
手动通过终端回归一些固定的主流程场景。
从3到1,测试成本逐步减少,测试覆盖率也逐步提高,因此单元测试覆盖率很大程度上决定了整个项目代码的质量
2.测试规则
所有的测试源文件都需要以_test.go结尾
测试前需要导入testing包,然后写成如下形式。测试函数必须以Test开头,可选后缀名也要以大写字母开头。其中为*testing.T类型的t参数会记录并报告测试错误结果的信息。
func TestName(t *testing.T) {
}
如下图代码,定义一个测试函数测试HelloTom函数的返回值是否正确,在具体逻辑中实现判断,若实际输出值与期望值不同,则使用参数t的Error方法打印出错误信息。
func HelloTom()string{
return "Jerry"
}
func TestHelloTom(t*testing.T){
output:=HelloTom()
expectedOutput:="Tom"
if output !=expectedOutput{
t.Error(output,"is not equal to",expectedOutput)
}
}
3.测试覆盖率
每一个测试场景都有一定覆盖率,在实际项目开发中,测试是不可能找出所有错误的,只能够尽可能的排除bug使程序可以在大多数或重要情况下运行。覆盖率即成功测试出的功能情况在所有功能情况中的占比,是衡量代码是否经过了足够的测试,评价项目水准的一个重要指标。
func JudgeNum(x int) bool {
if x > 50 {
return true
}
return false
}
func TestJudgeNum(t *testing.T) {
testNum := JudgeNum(1)
expected := true
if testNum != expected {
t.Errorf("期望值 ", "%d%d", "不同", expected, testNum)
}
}
上段代码的测试覆盖率仅有66.7%,因为在JudgeNum函数中还有一个return false的情况没有被测试到。
这时需要增加一个测试函数测试所传入的值大于50的情况
func TestJudgeNum1(t *testing.T) {
testNum := JudgeNum(51)
expected := true
if testNum != expected {
t.Errorf("期望值 ", "%d%d", "不同", expected, testNum)
}
}
此时覆盖率可达100%
4.基准测试
基准测试是测量一个程序在固定工作负载下的性能。在Go语言中,基准测试函数和普通测试函数写法类似,但是以Benchmark为前缀名,并且带有一个*testing.B类型的参数
如下段代码所示,循环N次对函数进行测试。
func BenchmarkIsPalindrome(b *testing.B) {
for i := 0; i < b.N; i++ {
IsPalindrome("haha")
}
}
总结
项目代码测试是保证代码质量的一种重要手段。在一般情况下,项目测试覆盖率大约在50%-60%,较高情况下能到80%以上,同时我们应该尽量保证测试分支相互独立,全面覆盖,还有测试单元的粒度足够小,函数单一负责。