Go語言程式測試

來源:互聯網
上載者:User
   最近一直在搞各種測試,然後今天周末翻翻書,發現特價蘿蔔的書上在測試方面寫得挺全的。 
這書是之前 CU(chinaunix.net)論壇。搞活動得到獎品(還有作者親筆簽名),拿回來都沒看完.
因為寫得太太太細了,又厚。
    參考他的書及官網的文檔,再把測試方面的東西過一下還是有點意思的.

這篇主要講這幾點:

一.Testing的幾種不同形式
功能測試:
TestXxxx(t *testing.T) 

基準測試:
BenchmarkXxxx(b *testing.B)

樣本測試:
Example_Xxx() 

用於測試的Main函數:
TestMain(m *testing.M)
//
// func TestMain(m *testing.M) {
// flag.Parse()
// os.Exit(m.Run())
// }

二. 測試中的資源收集

三. 測試覆蓋率


一.Testing的幾種不同形式
功能測試:

TestXxxx(t *testing.T) 
   偏向於測試某個源碼檔案中的具體源碼功能實現。
   基本是在同一個包位置。
   go test 來運行.
   //運行包下的所有測試
   go test -v prj/pkg
   //只測試這個包下名稱與之匹配的功能測試函數
   go test -v -run=xxfunc prj/pkg


控制測試回合時間:
 -timeout : 逾時控制
   go test -timeout 100ms prj/pkg  //可以用1h20s之類表示時間
   (時間單位: h小時/m分鐘/s秒/ms毫秒/us微秒/ns納秒)   
  
 -short : 是否縮短測試時間   
   可以在測試代碼中加上這個if
   if testing.Short() {
   }else{
   }
   然後在運行命令中加上 -short參數,如:
   go test -short prj/pkg

並發控制:
  測試函數預設是不並發執行的.如要並發執行.除了設定GOMAXPROCS外,
   runtime.GOMAXPROCS( runtime.NumCPU())
   還要在要測試的函數中開始,加上
  t.Parallel()   

  func TestParallel(t *testing.T){
  t.Parallel()
  //......
  }
  go test -parallel 8 

基準測試:

BenchmarkXxxx(b *testing.B)

 運行:    
  go test benxxx_test.go -bench="." 
  go test -bench=xxfunc
  go test -bench=xxfunc prj/pkg

 Go的Benchmark預設是在1s的時間內,儘可能多的執行這個函數. 可以通過 -benchtime 這個參數擴大時間長度.
 go test benxxx_test.go -benchtime=2s

 標準包中的相關源碼:

 var benchTime = flag.Duration("test.benchtime", 1*time.Second, "approximate run time for each benchmark")   // Run the benchmark for at least the specified amount of time.d := *benchTimefor !b.failed && b.duration < d && n < 1e9 {

測試函數模板例子:  

func BenchmarkXxxx(b *testing.B){   var (      //初始化    )b.StopTimer() //停止測試計時,因為預設是開啟計時的.////////////////////////////////    // 一些不需要計入測試時間的動作    // ......    ////////////////////////////////    b.StartTimer() //開始測試計時    ////////////////////////////////    // 繼續運行測試    // 如:       for i:=0;i<b.N;i++{    //......    }    ////////////////////////////////    // 如有重設計數時間需求    // RestTimer() 把之前累計的函數執行時間重設成0    // 繼續運行測試    // ........}

Benchmark 與功能測試不同的地方在於,它更多的關注效能之類的指標上.
例子:

package mainimport ("fmt""testing")func BenchmarkXxxx(b *testing.B) {for i := 0; i < b.N; i++ {fmt.Println("i:", i)}}
測試結果:
   30000             50806 ns/op
ok      _/E_/GOtest/testing/bentest   2.179s

30000 :總運行次數
50806 ns/op : 平均已耗用時間,即平均運行一次,要50806納秒

另外還可以加 t.SetBytes(1111111)得到每次能向檔案系統寫入多mb資料

/*Benchmark 例子Author:xclDate:2015-11-22*/package mainimport ("fmt""math/big""testing")func BenchmarkXxxx(b *testing.B) {for i := 0; i < b.N; i++ {fmt.Sprintf("hello %d", i)}}func BenchmarkBigLen(b *testing.B) {big := NewBig()b.ResetTimer()for i := 0; i < b.N; i++ {big.BitLen()}}func NewBig() *big.Int {x := new(big.Int)x.MulRange(1, 10)return x}/*//測試結果:E:\GOtest\testing\bentest>go test b_test.go -bench=.  -benchmem -cpu=1,2,4,8testing: warning: no tests to runPASSBenchmarkXxxx            5000000               341 ns/op              32 B/op          2 allocs/opBenchmarkXxxx-2          5000000               323 ns/op              32 B/op          2 allocs/opBenchmarkXxxx-4          5000000               332 ns/op              32 B/op          2 allocs/opBenchmarkXxxx-8          5000000               330 ns/op              32 B/op          2 allocs/opBenchmarkBigLen         200000000                9.85 ns/op            0 B/op          0 allocs/opBenchmarkBigLen-2       200000000                9.86 ns/op            0 B/op          0 allocs/opBenchmarkBigLen-4       100000000               10.0 ns/op             0 B/op          0 allocs/opBenchmarkBigLen-8       200000000                9.82 ns/op            0 B/op          0 allocs/opok      command-line-arguments  18.085s*/

樣本測試:
Example_Xxx() 
  用來看運行中,輸出的內容是否與預期的一樣
   func ExampleXxxx() 
 例子:  
  func ExampleHello() {
        fmt.Println("hello")
        // Output: hello
}
就是在下面,加一行 "// Output: 預期結果" 用來對比結果.
它的樣本函數命令有些規則:
   被測試對象是函數時:
func Example() { ... } //被測試對象是整個包
func ExampleF() { ... }  //被測試對象是函數
func ExampleT() { ... }   //被測試對象是類型
func ExampleT_M() { ... } //被測試對象是某個類型的一個函數

依前面規則取名後,還可以在後面加尾碼以例區分
func Example_suffix() { ... }
func ExampleF_suffix() { ... }
func ExampleT_suffix() { ... }
func ExampleT_M_suffix() { ... }

二. 測試中的資源收集

 在測試回合時,可以加上一些參數,用來採集監控資源使用方式。然後依Go提供的工具,作分析.

  -cpuprofile cpu.out // 預設每10毫秒採樣一次,cpu的使用方式 
  -memprofile mem.out  //程式運行期間,堆記憶體的分配情況
  -memprofilerate n     //記憶體配置行為,預設每分配512k位元組,採樣一次
  -blockprofile block.out  //記錄Goroutine阻塞事件
  -blockprofilerate n  // 控制記錄Goroutine阻塞時候打點的納秒數。預設不設定
    // 就相當於-test.blockprofilerate=1,每一納秒都打點記錄一下

以cpuprofile為例:

E:\GOtest\testing\bentest>go test b_test.go -bench=. -benchmem -cpu=1,2,4,8  -cpuprofile cpu.outtesting: warning: no tests to runPASSBenchmarkXxxx            5000000               351 ns/op              32 B/op          2 allocs/opBenchmarkXxxx-2          5000000               326 ns/op              32 B/op          2 allocs/opBenchmarkXxxx-4          5000000               326 ns/op              32 B/op          2 allocs/opBenchmarkXxxx-8          5000000               332 ns/op              32 B/op          2 allocs/opBenchmarkBigLen         200000000                9.91 ns/op            0 B/op          0 allocs/opBenchmarkBigLen-2       200000000                9.84 ns/op            0 B/op          0 allocs/opBenchmarkBigLen-4       100000000               10.2 ns/op             0 B/op          0 allocs/opBenchmarkBigLen-8       100000000               10.2 ns/op             0 B/op          0 allocs/opok      command-line-arguments  16.231sE:\GOtest\testing\bentest>dir 磁碟機 E 中的卷是 doc 卷的序號是 0E3D-2A1F E:\GOtest\testing\bentest 的目錄2015/11/22  11:59    <DIR>          .2015/11/22  11:59    <DIR>          ..2015/11/22  11:44             1,423 b_test.go2015/11/22  11:59            63,024 cpu.out2015/11/22  11:59         3,932,160 main.test.exe               3 個檔案      3,996,607 位元組               2 個目錄 15,239,778,304 可用位元組
        注意,產生了一個叫"main.test.exe"的可執行檔及cpu.out的輸出檔案。
可以利用它們來做分析
     go tool pprof main.test.exe cpu.out

//查閱運行中,CPU使用方式E:\GOtest\testing\bentest>go tool pprof main.test.exe cpu.outEntering interactive mode (type "help" for commands)(pprof) top1012230ms of 16500ms total (74.12%)Dropped 62 nodes (cum <= 82.50ms)Showing top 10 nodes out of 55 (cum >= 1890ms)      flat  flat%   sum%        cum   cum%    2910ms 17.64% 17.64%     4330ms 26.24%  math/big.nat.bitLen    2850ms 17.27% 34.91%     7180ms 43.52%  math/big.(*Int).BitLen    1420ms  8.61% 43.52%     1420ms  8.61%  math/big.bitLen    1090ms  6.61% 50.12%     1250ms  7.58%  runtime.mallocgc    1020ms  6.18% 56.30%     3510ms 21.27%  fmt.(*pp).doPrintf     840ms  5.09% 61.39%     8020ms 48.61%  command-line-arguments.BenchmarkBigLen     820ms  4.97% 66.36%     1090ms  6.61%  fmt.(*fmt).integer     550ms  3.33% 69.70%      550ms  3.33%  runtime.memmove     400ms  2.42% 72.12%      400ms  2.42%  runtime.mSpan_Sweep.func1     330ms  2.00% 74.12%     1890ms 11.45%  fmt.(*pp).printArg(pprof)(pprof) help Commands:   cmd [n] [--cum] [focus_regex]* [-ignore_regex]*       Produce a text report with the top n entries.       Include samples matching focus_regex, and exclude ignore_regex.       Add --cum to sort using cumulative data.       Available commands:         callgrind    Outputs a graph in callgrind format         disasm       Output annotated assembly for functions matching regexp or address         dot          Outputs a graph in DOT format         eog          Visualize graph through eog         evince       Visualize graph through evince         gif          Outputs a graph image in GIF format         gv           Visualize graph through gv         list         Output annotated source for functions matching regexp         pdf          Outputs a graph in PDF format         peek         Output callers/callees of functions matching regexp         png          Outputs a graph image in PNG format         proto        Outputs the profile in compressed protobuf format         ps           Outputs a graph in PS format         raw          Outputs a text representation of the raw profile         svg          Outputs a graph in SVG format         tags         Outputs all tags in the profile         text         Outputs top entries in text form         top          Outputs top entries in text form         tree         Outputs a text rendering of call graph         web          Visualize graph through web browser         weblist      Output annotated source in HTML for functions matching regexp or address   peek func_regex       Display callers and callees of functions matching func_regex.   ......... (pprof) weblist  (pprof) webCannot find dot, have you installed Graphviz?  
下載安裝個 Graphviz ,就能出圖了.


用於測試的Main函數:
TestMain(m *testing.M)

  來個例子:   

/*TestMain例子Author:xclDate: 2015-11-22*/package mainimport ("flag""log""os""testing")var wordPtr = flag.String("word", "foo", "a string")func TestMain(m *testing.M) {flag.Parse()log.Println("[TestMain] word:", *wordPtr)log.Println("[TestMain] run()前")exitVal := m.Run()log.Println("[TestMain] run()後")os.Exit(exitVal)}func Test1(t *testing.T) {log.Println("[Test1] running ", *wordPtr)}/*E:\GOtest\testing\t2>go test t2_test.go -v  -trace trace.out -word xcl......2015/11/22 18:11:43 [TestMain] word: xcl......2015/11/22 18:11:43 [TestMain] run()前=== RUN   Test12015/11/22 18:11:43 [Test1] running  xcl......--- PASS: Test1 (0.00s)PASS2015/11/22 18:11:43 [TestMain] run()後ok      command-line-arguments  0.101sE:\GOtest\testing\t2>dir 磁碟機 E 中的卷是 doc 卷的序號是 0E3D-2A1F E:\GOtest\testing\t2 的目錄2015/11/22  18:11    <DIR>          .2015/11/22  18:11    <DIR>          ..2015/11/22  18:11         3,666,944 main.test.exe2015/11/22  18:11             2,234 t2_test.go2015/11/22  18:11               730 trace.out               3 個檔案      3,669,908 位元組               2 個目錄 15,177,601,024 可用位元組E:\GOtest\testing\t2>go tool trace main.test.exe trace.out*/

三.測試覆蓋率:

   覆蓋率是指被測試對象有多少代碼在剛剛的測試中被用到。
   go test -cover prj/pkg
   go test prj/pkg -coverpkg=pkg1,pkg2
   go test prj/pkg -coverpkg=pkg1,pkg2 -coverprofile=cover.out
   go tool cover -html=cover.out

-func=cover.out  //輸出每個函數的測試覆蓋率概要資訊
-html=cover.out //將概要檔案內容轉成html並瀏覽
-mode=cover.out //設計概要檔案編譯模式
-o=cover.out //...
-var=GoCover  // ...


參考資料: https://golang.org/pkg/testing/

 https://golang.org/cmd/go/#hdr-Description_of_testing_flags
 https://github.com/polaris1119/The-Golang-Standard-Library-by-Example/blob/master/chapter09/09.1.md
         郝林的<<Go語言並發編程實戰>>測試篇

      

其實細節,具體查相關資料。 另外,Go源碼包下也有很多詳細的例子.

先整理到這,HTTP/WebSocket之類怎麼測試及效能最佳化方面的再另寫.


BLOG: http://blog.csdn.ent/xcl168



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.