• 20 go单元测试


    单元测试

    Go本身提供了一套轻量级的测试框架。符合规则的测试代码会在运行测试时被自动识别并执行。单元测试源文件的命名规则如下:

    1. 必须是以_test.go结尾的文件,比如manager_test.go

    Go的单元测试函数分为两类:功能测试函数和性能测试函数,分别以Test和Benchmark为函数名前缀并以*testing.T为单一参数的函数。下面是测试函数声明的例子:

    1. func TestAdd1(t *testing.T)
    2. func BenchamarkAdd1(t *testing.T)

    下面我们看下例子

    功能性单元测试代码

    这里我有2个代码文件,一个是代码文件,一个测试代码文件,共放在lib目录下。

    -----   lib目录
      |____ manager.go
      |____ manager_test.go
    

    我们看下测试文件代码,走功能测试的代码,必须是以Test开头的方法,因为我们传入的是*testing.T的参数,所以函数名必须是Test开头的

    // manager_test
    package library
    
    import (
    	"testing"  // 测试包
    )
    
    func TestOps(t *testing.T) {
    	mm := NewMusicManager()
    	if mm == nil {
    		t.Error("NewMusicManager failed")
    	}
    	if mm.Len() != 0 {
    		t.Error("NewMusicManager failed,not empty")
    	}
    	m0 := &MusicEntry{
    		"1", "My Heart Will GO On", "Celion Dion", "http://qbox.me/210394", "mp3",
    	}
    	mm.Add(m0)
    	if mm.Len() != 1 {
    		t.Error("MusicManager.Add() failed")
    	}
    
    	m := mm.Find(m0.Name)
    	if m == nil {
    		t.Error("MusicManager.Find() failed!")
    	}
    	if m.Id != m0.Id || m.Artist != m0.Artist || m.Name != m0.Name || m.Source != m0.Source || m.Type != m0.Type {
    		t.Error("MusicManager.Find() failed. Found item mismatch.")
    	}
    
    	m, err := mm.Get(0)
    	if m == nil {
    		t.Error("MusicManager.Get() Failed.", err)
    	}
    
    	m = mm.Remove(0)
    	if m == nil || mm.Len() != 0 {
    		t.Error("MusicManager.Remove() failed", err)
    	}
    }
    
    

    编写完成后,我们直接切换到这个lib目录下,执行go test 即可

    D:LeoLearnGoLearnsrcgo_devmusicPlayerlib>go test
    PASS    ---> 执行成功
    ok      go_dev/musicPlayer/lib  0.469s
    

    出现PASS和ok,那么就说明我们编写的测试代码ok没有问题,manager这个程序也OK,通过了测试代码。

    性能性单元测试

    我们可以使用go自带的test模块来做性能测试,由于传入的是testing.B参数,所以这里我们的函数必须以Benchmark。 如下所示

    func Add(a, b int) int {
    	return a + b
    }
    
    func BenchmarkHowFast(b *testing.B) {
    	b.StopTimer()
    	time.Sleep(time.Second)
    	b.StartTimer()
    	for i := 0; i < b.N; i++ {
    		Add(i, i+1)
    	}
    }
    

    full example :

    // manager_test
    package library
    
    import (
    	"testing"
    	"time"
    )
    
    func TestOps(t *testing.T) {
    	mm := NewMusicManager()
    	if mm == nil {
    		t.Error("NewMusicManager failed")
    	}
    	if mm.Len() != 0 {
    		t.Error("NewMusicManager failed,not empty")
    	}
    	m0 := &MusicEntry{
    		"1", "My Heart Will GO On", "Celion Dion", "http://qbox.me/210394", "mp3",
    	}
    	mm.Add(m0)
    	if mm.Len() != 1 {
    		t.Error("MusicManager.Add() failed")
    	}
    
    	m := mm.Find(m0.Name)
    	if m == nil {
    		t.Error("MusicManager.Find() failed!")
    	}
    	if m.Id != m0.Id || m.Artist != m0.Artist || m.Name != m0.Name || m.Source != m0.Source || m.Type != m0.Type {
    		t.Error("MusicManager.Find() failed. Found item mismatch.")
    	}
    
    	m, err := mm.Get(0)
    	if m == nil {
    		t.Error("MusicManager.Get() Failed.", err)
    	}
    
    	m = mm.Remove(0)
    	if m == nil || mm.Len() != 0 {
    		t.Error("MusicManager.Remove() failed", err)
    	}
    }
    
    func Add(a, b int) int {
    	return a + b
    }
    
    func BenchmarkHowFast(b *testing.B) {
    	b.StopTimer()
    	time.Sleep(time.Second)
    	b.StartTimer()
    	for i := 0; i < b.N; i++ {
    		Add(i, i+1)
    	}
    }
    
    

    然后我们执行下测试代码,由于加入了性能测试代码,我们需要加入 -bench 参数

    D:LeoLearnGoLearnsrcgo_devmusicPlayerlib>go test -bench="."
    // Benchmark名字-cpu     循环次数                 平均每次执行时间(纳秒)
    BenchmarkHowFast-4      2000000000               0.39 ns/op
    PASS
    ok      go_dev/musicPlayer/lib  7.249s
    
  • 相关阅读:
    JAVA 一个接口多个实现类
    关于Web服务器
    美团买菜IOS版设备风控浅析与算法还原
    阿里App防Bot新版AliTigerTally方案浅析与算法还原1
    使用php的openssl_encrypt和python的pycrypt进行跨语言的对称加密和解密问题
    一个把人民币小写转换为大写中文的方法
    《重构》代码坏味道
    git 合并分支
    java中SPI机制 代码改变世界
    echo print print_r的区别
  • 原文地址:https://www.cnblogs.com/liaojiafa/p/9274135.html
Copyright © 2020-2023  润新知