Go中如何进行单元测试(testing功能测试及benchmark性能测试)

时间:2024-10-14 11:01:58

Go语言中提供了实现单元测试的testing库和go test指令

本文测试讲解目录如下:

本文使用一个求和函数进行单元测试,包含测试函数的类代码如下:

  1. package main
  2. func sumOfTwo(a int,b int) int {
  3. return a+b
  4. }

因为单纯的go test指令并不能保证测试函数按照一定顺序执行,下边列举了单个测试函数的执行、多个测试函数的顺序执行、初始化测试环境后执行测试函数以及性能测试的方法

1.单个测试函数的定义与执行

对该函数进行测试类代码如下(注意:测试类需导入相同的包):

  1. package main
  2. import (
  3. "fmt"
  4. "testing"
  5. )
  6. //测试函数名必须是TestXxx,测试函数功能必须传入*
  7. func TestPrint(t *) {
  8. res := sumOfTwo(1,2)
  9. ("hey")
  10. if res != 3 {
  11. ("wrong result of sumOfTwo") //打印错误信息,并终止case
  12. }
  13. }

打开命令行在当前目录下使用输入命令:go test,测试结果如下:

2.多个测试函数的顺序执行

  1. package main
  2. import (
  3. "fmt"
  4. "testing"
  5. )
  6. func testPrint(t *) {//注意名称不要命名成定义测试类的名称,即TestXxx,本函数名第一个字母改成了小写
  7. res := sumOfTwo(1, 2)
  8. ("hey")
  9. if res != 3 {
  10. ("wrong result of sumOfTwo") //打印错误信息,并终止case
  11. }
  12. }
  13. func testPrint1(t *) {//注意名称不要命名成定义测试类的名称,即TestXxx,本函数名第一个字母改成了小写
  14. // () 跳过当前test,直接按照pass处理
  15. res := sumOfTwo(2,3)
  16. ("hey")
  17. if res != 5 {
  18. ("wrong result of sumOfTwo") //打印错误信息,并终止case
  19. }
  20. }
  21. func TestPrintAll(t *) {//go test指令会执行的测试类
  22. ("TestPrint", testPrint)//定义测试名称,传入测试类
  23. ("TestPrint", testPrint1)
  24. }

执行go test指令,结果如下:

3.初始化测试环境

定义TestMain函数,在执行测试类的时候若存在该函数会优先执行,可在此函数中完成初始化,如数据库链接等功能。编写测试类如下(注:TestMain中若不执行(),其他测试函数也不会进行):

  1. package main
  2. import (
  3. "fmt"
  4. "testing"
  5. )
  6. func testPrint(t *) {//注意名称不要命名成定义测试类的名称,即TestXxx,本函数名第一个字母改成了小写
  7. // () 跳过当前test,直接按照pass处理
  8. res := sumOfTwo(1, 2)
  9. ("hey")
  10. if res != 3 {
  11. ("wrong result of Print1to20") //打印错误信息,并终止case
  12. }
  13. }
  14. func testPrint1(t *) {//注意名称不要命名成定义测试类的名称,即TestXxx,本函数名第一个字母改成了小写
  15. res := sumOfTwo(2,3)
  16. res++
  17. ("hey")
  18. if res != 5 {
  19. ("wrong result of Print1to20") //打印错误信息,并终止case
  20. }
  21. }
  22. func TestPrintAll(t *) {
  23. ("TestPrint", testPrint)
  24. ("TestPrint", testPrint1)
  25. }
  26. func TestMain(m *) {//TestMain传入M
  27. ("test run...")
  28. () //保证其他testcase被执行,在()之前要做一些初始化的东西,比如数据库连接等。若不执行此函数别的testcase不会执行
  29. }

测试函数运行结果如下:

4.benchmark进行性能测试

Benchmar函数一般以Benchmark开头

Benchmark的case一般会跑次,而且每次执行都会如此,在执行过程中会根据实际case的平均执行时间是否稳定来调整的次数以达到稳态,也是因为如此,如果测试函数的执行时间最终不是趋近于稳态的话,会一直运行该测试,下文会进行演示。

测试函数:

  1. package main
  2. import (
  3. "fmt"
  4. "testing"
  5. )
  6. func BenchmarkAll(b *) {
  7. for i := 0; i < ; i++ {
  8. sumOfTwo(1, 2)
  9. }
  10. }

执行测试(使用-bench=.是只执行benchmark测试,注意若写了Testmain()函数,是会先执行TestMain()的):

该函数执行了200000000次,平均每次执行时间是0.25ns

*************************************************************************************************************************************

测试函数的执行时间最终不是稳态的用例:

  1. package main
  2. import (
  3. "fmt"
  4. "testing"
  5. )
  6. func a(n int) {
  7. for n > 0 {
  8. n--
  9. }
  10. }
  11. func BenchmarkAll(b *) {
  12. for i := 0; i < ; i++ {
  13. a(i)
  14. }
  15. }

 执行结果:

一直卡在这里运行