GO语言测试方法| 青训营笔记

99 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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)
	}
}

image.png

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的情况没有被测试到。

image.png

这时需要增加一个测试函数测试所传入的值大于50的情况

func TestJudgeNum1(t *testing.T) {
	testNum := JudgeNum(51)
	expected := true
	if testNum != expected {
		t.Errorf("期望值 ", "%d%d", "不同", expected, testNum)
	}
}

此时覆盖率可达100%

image.png

4.基准测试

基准测试是测量一个程序在固定工作负载下的性能。在Go语言中,基准测试函数和普通测试函数写法类似,但是以Benchmark为前缀名,并且带有一个*testing.B类型的参数

如下段代码所示,循环N次对函数进行测试。

func BenchmarkIsPalindrome(b *testing.B) {
    for i := 0; i < b.N; i++ {
        IsPalindrome("haha")
    }
}

总结

项目代码测试是保证代码质量的一种重要手段。在一般情况下,项目测试覆盖率大约在50%-60%,较高情况下能到80%以上,同时我们应该尽量保证测试分支相互独立,全面覆盖,还有测试单元的粒度足够小,函数单一负责。