Go测试与性能调优

第四章 测试与性能调优

4.1 传统测试vs表格驱动测试

传统测试

assertEquals()第一个参数是期望结果,第二个参数是实际结果。

image

传统测试的缺点:

  • 测试数据和测试逻辑混在一起
  • 出错信息不明确
  • 一旦一个数据出错测试全部结束

表格驱动测试

测试结构体中a+b=c。

image

表格驱动测试的优点:

  • 分离的测试数据和测试逻辑
  • 明确的出错信息
  • 可以部分失败
  • go语言的语法使得我们更容易实践表格驱动测试

4.1.1 表格驱动测试示例1:triangle_test.go

测试文件一般放在与被测试文件同一目录下,且文件名一般以被测试对象名_test的形式命名,如下:

image

被测试函数:

func calcTriangle(a, b int) int {
   var c int
   c = int(math.Sqrt(float64(a*a + b*b)))
   return c
}

triangle_test.go

package main

import "testing"

func TestTriangle(t *testing.T) {
   tests := []struct{ a, b, c int }{//a和b是测试例,c是预期结果
      {3, 4, 5},
      {5, 12, 13},
      {8, 15, 17},
      {12, 35, 37},
      {30000, 40000, 50000},
   }

   for _, tt := range tests {
      if actual := calcTriangle(tt.a, tt.b); actual != tt.c {
         t.Errorf("calcTriangle(%d, %d); got %d; expected %d", tt.a, tt.b, actual, tt.c)
      }
   }
}

测试成功控制台输出:

=== RUN   TestTriangle
--- PASS: TestTriangle (0.00s)
PASS

测试失败控制台输出:

=== RUN   TestTriangle
    triangle_test.go:16: calcTriangle(3, 4); got 5; expected 0

--- FAIL: TestTriangle (0.00s)

FAIL

利用命令行运行测试文件:

首先进入测试文件目录,再输入go test .或者go test即可运行测试文件得出测试结果:

image

4.1.2 表格驱动测试示例2:最小不重复子串测试

被测试函数:

func lengthOfLongestSubstring(s string) int {
   lastOccurred := make(map[rune]int)
   start := 0
   maxLength := 0

   for i, ch := range []rune(s) {
      lastI, ok := lastOccurred[ch]
      if ok && lastI >= start {
         start = lastI + 1
      }
      if i-start+1 > maxLength {
         maxLength = i - start + 1
      }
      lastOccurred[ch] = i
   }
   return maxLength
}

lengthOfLongestSubstring_test.go

package main

import "testing"

func TestSubstr(t *testing.T) {
   tests := []struct { //s是测试例,ans是预期结果
      s   string
      ans int
   }{
      //Normal cases
      {"abcabcbb", 3},
      {"pwwkew", 3},

      //Edge cases
      {"", 0},
      {"b", 1},
      {"bbbbbbb", 1},
      {"abcabcabcd", 4},

      //Chinese support
      {"这里是慕课网", 6},
      {"一二三二一", 3},
      {"黑化肥挥发会发灰", 6},
   }

   for _, tt := range tests {
      if actual := lengthOfLongestSubstring(tt.s); actual != tt.ans {
         t.Errorf("got %d for input%s; expected %d", actual, tt.s, tt.ans)
      }
   }
}

测试成功控制台输出:

=== RUN   TestSubstr
--- PASS: TestSubstr (0.00s)
PASS

测试失败控制台输出:

=== RUN   TestSubstr
    lengthOfLongestSubstring_test.go:28: got 6 for input黑化肥挥发会发灰; expected 0
--- FAIL: TestSubstr (0.00s)

FAIL

此外还有性能测试,对lengthOfLongestSubstring()进行Benchmark性能测试:

func BenchmarkSubstr(b *testing.B) {
   s := "黑化肥挥发会发灰"
   ans := 6
   for i := 0; i < b.N; i++ {
      actual := lengthOfLongestSubstring(s)
      if actual != ans {
         b.Errorf("got %d for input%s; expected %d", actual, s, ans)
      }
   }
}

控制台输出:

goos: windows
goarch: amd64
pkg: learngo/algorithm/lengthOfLongestSubstring
cpu: AMD Ryzen 7 5800H with Radeon Graphics
BenchmarkSubstr
BenchmarkSubstr-16       5948668//循环次数               196.3 ns/op//每个循环所耗时间
PASS
posted @ 2022-08-12 16:28  雪碧锅仔饭  阅读(115)  评论(0)    收藏  举报