单元测试

引入

我们写了一段函数或者一个模块,我们该怎么确认他的运行结果是正确的呢?

当然我们有最简单粗暴的方法,就是直接调用该函数,看实际输出结果和预期结果是否一致,但是这样很不方便,我们在main函数里面调用,如果项目正在运行,需要停止项目,同时我们要测试多模块的时候需要调用很多函数,非常麻烦。

我们为了优化传统的测试方式,Go引入了testing框架和go test命令来进行单元测试和性能测试,testing框架和其他语言的测试框架类似,可以基于这个框架写针对相应函数的测试用例,也可以基于该框架写相应的压力测试用例,单元测试可以解决如下问题:

  1. 确保函数可运行,结果正确
  2. 代码性能良好
  3. 单元测试便于定位问题,性能测试可以使程序在高并发状态下能够保持稳定。

快速入门

我们就直接来一个案例,来体验一下。

特别说明:测试时要退出360(?别问为啥是360,ttdr电脑里没有360),因为360可能认为测试用例程序是木马

cal1.go

 package main
 ​
 func addUpper(n int) int {
  res := 0
  for i := 1; i <= n-1; i++ {
  res += i
  }
  return res
 }
 ​

cal_test.go

testing框架会直接将xxx_test.go文件引入,同时调用TestXxx函数

 package main
 ​
 import (
  "testing"
 )
 ​
 // 测试用例
 func TestAddUpper(t *testing.T) {
  res := addUpper(10)
  if res != 55 {
  t.Fatalf("执行错误实际值为%v", res)
  }
  t.Logf("执行正确")
 }
 ​
image-20260102074332295

总结

  1. 测试用例文件名必须是)_test.go结尾,测试用例函数必须是Test开头。
  2. Test开头的测试用例函数二点形参类型必须是*testing.T*
  3. 一个测试用例文件中可以有多个测试用例函数
  4. 运行测试用例指令go testgo test -v
  5. 出现错误时可以用t.Fatalf来格式化输出错误信息,并退出程序
  6. t.Logf可以输出相应日志
  7. 测试用例函数并没有放在main函数中,但是也执行了,这就是测试用例的方便之处
  8. PASS表示测试用例运行成功,FAIL表示测试用例运行失败

案例

  1. 编写一个Monster结构体,字段 Name, Age, Skill
  2. 给Monster绑定方法Store,可以将一个Monster变量(对象),序列化后保存到文件中
  3. 给Monster绑定方法ReStore,可以将一个序列化的Monster,从文件中读取,并反序列化为Monster对象,检查反序列化,名字正确。
  4. 编程测试用例文件 monster_test.go,编写测试用例函数 TestStore 和 TestRestore 进行测试。

monster.go

 package testing
 ​
 import (
  "encoding/json"
  "fmt"
  "io/ioutil"
 )
 ​
 type Monster struct {
  Name  string
  Age   int
  Skill string
 }
 ​
 func (this *Monster) Store() bool {
  data, err := json.Marshal(this)
  if err != nil {
  fmt.Println("序列化失败", err)
  return false
  }
  filePath := "d:/日志/monster.ser"
  err = ioutil.WriteFile(filePath, data, 0666)
  if err != nil {
  fmt.Println("write file err:", err)
  return false
  }
  return true
 }
 func (this *Monster) UnStore() bool {
  filePath := "d:/日志/monster.ser"
  data, err := ioutil.ReadFile(filePath)
  if err != nil {
  return false
  }
  err = json.Unmarshal([]byte(data), this)
  if err != nil {
  fmt.Println("反序列化失败", err)
  }
  return true
 }
 func main() {
 ​
 }
 ​

monster_test.go

 package testing
 ​
 import "testing"
 ​
 func TestMonster_Store(t *testing.T) {
  monster := Monster{
  Name:  "幻胧",
  Age:   1000,
  Skill: "丰饶",
  }
  res := monster.Store()
  if !res {
  t.Fatalf("store()错误,错误值为%v", res)
  }
  t.Logf("monster.Store()测试成功")
 }
 func TestMonster_UnStore(t *testing.T) {
  var monster Monster
  res := monster.UnStore()
  if !res {
  t.Fatalf("unstore()错误,错误值为%v", res)
  }
  if monster.Name != "幻胧" {
  t.Fatalf("unstore()错误,错误值为%v", res)
  }
  t.Logf("unstore测试成功")
 }
 ​
暂无评论

发送评论 编辑评论


				
上一篇