關於go語言的測試相關內容筆記

其實之前對於測試自己一直比較弱,不管是python的還是go的,關於測試這塊並沒有非常注重,這次就好好整理一下關於go的測試

單元測試

Go程序主要包含三類測試: 功能測試(test)、基準測試(benchmark,也稱性能測試)以及示例測試

這裏提一下,示例測試其實也是一種功能測試,只不過它更關注程序打印出來的內容

一般情況下:一個測試賽源碼文件只會針對某個命令源碼文件, 或庫源碼文件做測試,所以我們應該把它們放在同一個代碼包內

測試源碼文件的主名稱應該以被測試源碼文件的主名稱爲前導, 並且必須以“_test”爲後綴,如被測試的源碼文件名是demo.go 那麼測試源碼文件名是demo_test.go

Go 語言對測試函數的名稱和簽名都有哪些規定?

  1. 對於功能測試函數來說,其名稱必須以Test爲前綴,並且參數列表中只有一個*testing.T 類型的參數聲明
  2. 對於性能測試函數來說,其名稱必須以Benchmark爲前綴,並且唯一參數的類型必須是*testing.B類型
  3. 對於實例測試函數來說,其名稱必須以Example爲前綴, 但對函數的參數列表沒有強制規

關於go test 命令的主要流程是:

go test 命令在開始運行時會先做一些準備工作,比如,確定內部需要用到的命令,檢查我們指定的代碼包或源碼文件的有效性,以及判斷我們基於的標記是否合法等等

在準備工作完成後,go test 命令會針對每個測試代碼包依次進行構建,執行包中符合要求的測試函數,清理臨時文件,打印測試結果。

這裏的依次:表示對每個測試代碼包,go test 命令會串行的執行測試流程中的每個步驟。但是爲了加快測試速度,它通常會併發地對多個被測試代碼包進行功能測試。只不過最後打印測試結果的時候

會按照我們給定的順序逐個進行,讓我們感覺是在串行的執行測試

由於併發測試會讓性能測試的結果存在偏差,所以性能測試一般都是串行進行的

go test -v 可以看到測試中更詳細的日誌信息

如果想要某個測試在執行的過程中立即失敗,可以在該函數中調用:t.FailNow方法

怎麼解釋性能測試的測試結果?

這個還是非常重要的,之前並沒有去細緻的瞭解

這裏有一段代碼,併爲之寫了一個性能測試代碼內容如下:

package demo54

import "math"

func GetPrimes(max int) []int {
    if max <= 1 {
        return []int{}
    }
    marks := make([]bool, max)
    var count int
    squareRoot := int(math.Sqrt(float64(max)))
    for i := 2; i <= squareRoot; i++ {
        if marks[i] == false {
            for j := i * i; j < max; j += i {
                if marks[j] == false {
                    marks[j] = true
                    count++
                }
            }
        }
    }
    primes := make([]int, 0, max-count)
    for i := 2; i < max; i++ {
        if marks[i] == false {
            primes = append(primes, i)
        }
    }
    return primes
}

性能測試的代碼爲:

package demo54

import "testing"

func BenchmarkGetPrimes(b *testing.B) {
    for i:=0;i<b.N;i ++ {
        GetPrimes(1000)
    }
}

下面是測試命令和結果

zhaofan@zhaofandeMacBook-Pro  ~/go_project  go test -bench=. -run=^$ 36/demo54
goos: darwin
goarch: amd64
pkg: 36/demo54
BenchmarkGetPrimes-4      500000              2728 ns/op
PASS
ok      36/demo54       1.407s

這裏對這個命令進行解釋:

第一個標記-bench=. 只有有了這個標記命令纔會進行性能測試,該標記. 表明需要執行任意名稱的性能測試函數,當然這裏還是要符合Go程序測試的基本規則的

第二個標記及值是-run=^$ 這個標記用於表明需要執行哪些功能測試函數,這同樣是以函數名稱爲依據的 該標記的值^$ 意味着只執行名稱爲空的功能測試函數,其實就是不執行任何功能測試函數

結果中:BenchmarkGetPrimes-4 被稱爲單個性能測試的名稱,表示命令執行了性能測試函數BenchmarkGetPrimes 並且當時所有最大的P 數量爲4 最大P 數量相當於可以同時運行goroutine的邏輯CPU的最大個數。這裏的CPU可以被稱爲CPU核心,但他並等同於計算機中真正的CPU核心

go test -cpu 可以設置最大P數量的列表

關於測試代碼的解釋:

func BenchmarkGetPrimes(b *testing.B) {
    for i:=0;i<b.N;i ++ {
        GetPrimes(1000)
    }
}

這裏在一個會循環迭代b.N次方的循環中調用了GetPrimes函數,並傳遞的參數爲1000, go test 命令會先嚐試把b.N 設置爲1,

然後執行測試函數

如果測試的函數執行時間沒有超過上限, 此傷心啊默認爲1秒,那麼命令就會改大b.N的值,然後再次執行測試函數,如此往復,知道這個時間大於或等於上限爲止。

當某次執行的時間大於或等於上限時, 我們就說這事命令此次對該測試函數的最後一次執行,這時b.N的值就會包含在測試結果中,也就是上述測試結果中的500000

結果中:2728 ns/op 表明單次執行GetPrimes函數的平均耗時爲2728納秒。 這其實就是最後一次執行測試函數的時間,除以被測函數的執行測試得出的結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章