一般而言,我们通过包中的函数调用来做一些测试,比如正常的调用代码,如果错误然后追寻代码位置和行数来判断,如下:
7.单元测试
- 示例
假设现在创建一个目录codetest,而后放一段代码,如,add函数,做一个加法运算,如下
[root@linuxea.com /opt/Golang/inTest]# cat codetest/calc.go
package codetest
func Add(a,b int) int {
return a + b
}
而后在main函数中调用
[root@linuxea.com /opt/Golang/inTest]# cat main.go
package main
import (
"testmod/info"
"testmod/codetest"
"fmt"
)
func main(){
fmt.Println(info.Name)
a := codetest.Add(1,2)
fmt.Println(a)
}
运行
[root@linuxea.com /opt/Golang/inTest]# go run main.go
mark
3
但是这种方式并不可靠。我们可以使用go的单元测试。
当我们对代码进行重新修改后,我们有必要对一些模块进行单元测试以确保代码运行正常。我们做一个简单的示例。测试上面Add的函数
7.1单元测试
还是如上所示,我们仍然测试ADD函数,加入go的测试风格。测试函数需要导入testing
包,我们在calc
的目录下创建一个go文件,文件中函数名称都是以Test开头,传入一个参数t,是*testing.T
指针类型,在测试函数中调用函数进行返回值测试,当测试失败可通过testing.T
结构体的Error*函数抛出错误
func TestAdd(t *testing.T){}
而后直接调用Add函数,如下:
func TestAdd(t *testing.T){
if 4 != Add(1,2){
t.Errorf("1加2不等于3")
}
}
如上所示,调用Add(1,2)的结果如果不等于4,就抛出错误
代码块
[root@linuxea.com /opt/Golang/inTest/codetest]# cat calc_test.go
package codetest
import "testing"
func TestAdd(t *testing.T){
if 4 != Add(1,2){
t.Errorf("1加2不等于3")
}
}
而后我们运行go test testmod/codetest
go test testmod/codetest
中的testmod是modules中init时候的名字,codetest是当前目录下的包名
[root@linuxea.com /opt/Golang/inTest/codetest]# go test testmod/codetest
--- FAIL: TestAdd (0.00s)
calc_test.go:7: 1加2不等于3
FAIL
FAIL testmod/codetest 0.003s
我们修改成正确的看看。
把条件判断改成3。很明显,1+2,是等于3的
package codetest
import "testing"
func TestAdd(t *testing.T){
if 3 != Add(1,2){
t.Errorf("1加2不等于3")
}
}
运行
[root@linuxea.com /opt/Golang/inTest/codetest]# go test testmod/codetest
ok testmod/codetest (cached)
7.2测试覆盖率
-coverprofile
我们在添加一个函数在calc.go
中
# cat calc.go
package codetest
func Add(x,y int) int {
if x > 0{
return x + y
}else {
return x
}
}
func Multi(x,y int) int {
return x * y
}
测试文件calc_test.go
package codetest
import "testing"
func TestAdd(t *testing.T){
if 3 != Add(1,2){
t.Errorf("1加2不等于3")
}
}
运行
[root@linuxea.com /opt/Golang/inTest/codetest]# go test testmod/codetest -coverprofile=calc.out
ok testmod/codetest 0.002s coverage: 50.0% of statements
这时候会产生一个calc.out
文件列表:
[root@linuxea.com /opt/Golang/inTest/codetest]# ll total 12 -rw-r--r-- 1 root root 137 Oct 2 10:04 calc.go -rw-r--r-- 1 root root 164 Oct 2 10:04 calc.out -rw-r--r-- 1 root root 119 Oct 2 10:04 calc_test.go
7.3查看cover文件
使用go tool cover -html calc.out
[root@linuxea.com /opt/Golang/inTest/codetest]# go tool cover -html calc.out
HTML output written to /tmp/cover001206950/coverage.html
这时候生成了一个html的文件存放在/tmp/cover001206950/coverage.html
红色是未覆盖的测试
7.4多条件测试覆盖率
上述中,只覆盖率判断了x大于0的代码,在覆盖测试else这块,如下:
func TestAdd2(t *testing.T){
if -1 != Add(-1,3){
t.Errorf("-1")
}
}
代码块
package codetest
import "testing"
func TestAdd(t *testing.T){
if 3 != Add(1,2){
t.Errorf("1加2不等于3")
}
}
func TestAdd2(t *testing.T){
if -1 != Add(-1,3){
t.Errorf("-1")
}
}
运行
[root@linuxea.com /opt/Golang/inTest/codetest]# go test testmod/codetest -coverprofile=calc.out
ok testmod/codetest 0.002s coverage: 75.0% of statements
转换html文件
[root@linuxea.com /opt/Golang/inTest/codetest]# go tool cover -html calc.out
HTML output written to /tmp/cover693930635/coverage.html
如下:
两个if分支都被测试到,所以变成了绿色。
8.基准测试
基准测试通常用来测试性能,函数使用Beanchmark
开头,参数也是*testing.B
- 示例
创建一个函数名称为Fact的阶层函数
func Fact(n int) int {
if n == 0 {
return 1
}
return n * Fact(n-1)
}
代码块
package codetest
func Add(x,y int) int {
if x > 0{
return x + y
}else {
return x
}
}
func Multi(x,y int) int {
return x * y
}
func Fact(n int) int {
if n == 0 {
return 1
}
return n * Fact(n-1)
}
在calc_test.go
中基准测试写法如下:
func BeanchmarkFact(b *testing.B) {
for i :=0;i <=20000;i++{
Fact(i)
}
}
代码块
package codetest
import "testing"
func TestAdd(t *testing.T){
if 3 != Add(1,2){
t.Errorf("1加2不等于3")
}
}
func TestAdd2(t *testing.T){
if -1 != Add(-1,3){
t.Errorf("-1")
}
}
func BeanchmarkFact(b *testing.B) {
for i :=0;i <=20000 ;i++{
Fact(i)
}
}
- bench
在执行go test的时候 要加-bench
参数
[root@linuxea.com /opt/Golang/inTest/codetest]# go test testmod/codetest -bench .
goos: linux
goarch: amd64
pkg: testmod/codetest
BenchmarkFact-2 1 1376384478 ns/op
PASS
ok testmod/codetest 1.381s
benchmem
可以加benchmem
查看内存使用
[root@linuxea.com /opt/Golang/inTest/codetest]# go test testmod/codetest -bench . -benchmem
goos: linux
goarch: amd64
pkg: testmod/codetest
BenchmarkFact-2 1 1399430216 ns/op 0 B/op 0 allocs/op
PASS
ok testmod/codetest 1.403s