不得不说,学这个之前我只会APIfox点一点……
- 回归测试:质量保证人员手动测试项目可用性(刷抖音、看评论)top1
 
- 集成测试:对系统功能的测试(对暴露的接口自动化测试)top2
 
- 单元测试:开发者对单独的函数模块测试 top3
 
单元测试
规则
- 所有测试文件都以 
_test.go 结尾 
- 测试函数写成 
func TextXxx(t *testing.T) 
- 初始化逻辑放到 
TestMain 中(准备测试的数据->跑测试->释放资源) 
1 2 3
   | └─test         print.go         print_test.go
   | 
 
如果要测试print.go中的函数输出是否正确
1 2 3 4 5 6
   |  package test
  func HelloTom() string { 	return "John" }
 
  | 
 
然后建立print_test.go,其实这个时候会发现这个吉祥物就有点不一样,而且整个goland文件有入口可以运行了,而不是只能从main.go进入,下面就填写Testxxxx(T &testint.T){}
最后三角形点一点,记得撰写一下测试逻辑
1 2 3 4 5 6 7 8 9 10
   | package test
  import "testing"
  func TestHelloTom(t *testing.T) { 	want := "Tom" 	if got := HelloTom(); got != want { 		t.Errorf("HelloTom() = %q, want %q", got, want) 	} }
   | 
 
测试结果:
1 2 3 4 5 6 7 8
   | === RUN   TestHelloTom     print_test.go:8: HelloTom() = "John", want "Tom" --- FAIL: TestHelloTom (0.00s)
  FAIL
 
  Process finished with the exit code 1
   | 
 
覆盖率
这是一个标准,来判断你的测试是否够格
按照刚才的东西重新写一个案例
1 2 3 4 5 6 7 8 9
   |  package test
  func JudgePassLine(score int) bool { 	if score >= 60 { 		return true 	} 	return false }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | package test
  import "testing"
  func TestJudgePassLineTrue2(t *testing.T) { 	if !JudgePassLine(80) { 		t.Error("The score is less than 60, but it is judged as pass") 	} }
  func TestJudgePassLineFalse2(t *testing.T) { 	if JudgePassLine(50) { 		t.Error("The score is greater than 60, but it is judged as fail") 	} }
   | 
 
绿色三角形中有几个选项,有一个选项是RUN "XXX" WITH COVERAGE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   |  package test
  import "testing"
  func TestJudgePassLineTrue2(t *testing.T) { 	if !JudgePassLine(80) { 		t.Error("The score is less than 60, but it is judged as pass") 	} }
  func TestJudgePassLineFalse2(t *testing.T) { 	if JudgePassLine(50) { 		t.Error("The score is greater than 60, but it is judged as fail") 	} }
 
  | 
 
1 2 3 4 5 6 7 8 9 10
   |  === RUN   TestJudgePassLineTrue2 --- PASS: TestJudgePassLineTrue2 (0.00s) === RUN   TestJudgePassLineFalse2 --- PASS: TestJudgePassLineFalse2 (0.00s) PASS
  coverage: 100.0% of statements in ../../today/...
  Process finished with the exit code 0
 
  | 
 
单元测试 Tips:
- 一般覆盖率:50%~60%,较高覆盖率:80%+
 
- 测试分支相互独立、全面覆盖
 
- 测试单元粒度足够小,函数单一职责
 
文件处理
1 2 3 4 5 6 7 8 9 10
   |  line11 line22 line33 line44 line55
 
 
 
 
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
   |  package test
  import ( 	"bufio" 	"os" 	"strings" )
  func ReadFirstLine() string { 	open, err := os.Open("./file") 	if err != nil { 		return "" 	} 	defer open.Close() 	scanner := bufio.NewScanner(open) 	for scanner.Scan() { 		return scanner.Text() 	} 	return "" }
  func ProcessFirstLine() string { 	line := ReadFirstLine() 	destLine := strings.ReplaceAll(line, "11", "00") 	return destLine }
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11
   |  package test
  import "testing"
  func TestReadFirstLine(t *testing.T) { 	got := ProcessFirstLine() 	if got != "line00" { 		t.Errorf("ReadFirstLine() = %q; want 11", got) 	} }
 
  | 
 
这个测试依赖于log.txt,但是实际中log无法访问又怎么办?
Mock测试
Mock 就是打桩,在测试时使用一个函数或方法替换另一个函数或方法(在运行时替换函数的指针)
例如在上面使用 ReadFirstLine() 来读取数据,而我们可以用一个函数生成数据,然后替换掉那个函数
常见的用于实现 Mock 的包是 monkey
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | package test
  import "testing" import "bou.ke/monkey"
  func TestReadFirstLine(t *testing.T) { 	got := ProcessFirstLine() 	if got != "line00" { 		t.Errorf("ReadFirstLine() = %q; want 11", got) 	} }
 
 
  func TestProcessFirstLineWithMock(t *testing.T) { 	monkey.Patch(ReadFirstLine, func() string { 		return "line110" 	}) 	defer monkey.Unpatch(ReadFirstLine) 	got := ProcessFirstLine() 	if got != "line000" { 		t.Errorf("ProcessFirstLine() = %q; want 11", got) 	} }
   | 
 
基准测试
Benchmark……..