在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ GO/ 11.3 Go怎么寫測試用例
7 文本處理
3 Web基礎(chǔ)
14 擴(kuò)展Web框架
10.4 小結(jié)
2.2 Go基礎(chǔ)
2.8 總結(jié)
6.1 session和cookie
5.5 使用beedb庫進(jìn)行ORM開發(fā)
8.3 REST
13.6 小結(jié)
5.4 使用PostgreSQL數(shù)據(jù)庫
14.6 pprof支持
14.1 靜態(tài)文件支持
11.2 使用GDB調(diào)試
7.7 小結(jié)
1 GO環(huán)境配置
14.5 多語言支持
7.1 XML處理
1.5 總結(jié)
13 如何設(shè)計(jì)一個(gè)Web框架
14.3 表單及驗(yàn)證支持
12 部署與維護(hù)
10 國際化和本地化
1.1 Go 安裝
6.2 Go如何使用session
5.6 NOSQL數(shù)據(jù)庫操作
6.5 小結(jié)
9.4 避免SQL注入
12.1 應(yīng)用日志
4.2 驗(yàn)證表單的輸入
10.1 設(shè)置默認(rèn)地區(qū)
1.3 Go 命令
9.6 加密和解密數(shù)據(jù)
4.1 處理表單的輸入
4.4 防止多次遞交表單
11.3 Go怎么寫測試用例
8 Web服務(wù)
12.3 應(yīng)用部署
5.7 小結(jié)
12.5 小結(jié)
11 錯(cuò)誤處理,調(diào)試和測試
9.2 確保輸入過濾
14.2 Session支持
6.4 預(yù)防session劫持
12.4 備份和恢復(fù)
8.1 Socket編程
13.1 項(xiàng)目規(guī)劃
13.4 日志和配置設(shè)計(jì)
7.6 字符串處理
13.2 自定義路由器設(shè)計(jì)
6.3 session存儲(chǔ)
3.4 Go的http包詳解
8.2 WebSocket
10.3 國際化站點(diǎn)
7.5 文件操作
7.4 模板處理
9.1 預(yù)防CSRF攻擊
13.3 controller設(shè)計(jì)
2.6 interface
14.4 用戶認(rèn)證
2.3 流程和函數(shù)
附錄A 參考資料
11.1 錯(cuò)誤處理
9.5 存儲(chǔ)密碼
9.3 避免XSS攻擊
12.2 網(wǎng)站錯(cuò)誤處理
6 session和數(shù)據(jù)存儲(chǔ)
2.4 struct類型
3.3 Go如何使得Web工作
2.5 面向?qū)ο?/span>
3.1 Web工作方式
1.2 GOPATH與工作空間
2.1 你好,Go
9.7 小結(jié)
13.5 實(shí)現(xiàn)博客的增刪改
7.2 JSON處理
10.2 本地化資源
7.3 正則處理
2 Go語言基礎(chǔ)
5.1 database/sql接口
4.5 處理文件上傳
8.5 小結(jié)
4.3 預(yù)防跨站腳本
5.3 使用SQLite數(shù)據(jù)庫
14.7 小結(jié)
3.2 Go搭建一個(gè)Web服務(wù)器
2.7 并發(fā)
5 訪問數(shù)據(jù)庫
4 表單
3.5 小結(jié)
1.4 Go開發(fā)工具
11.4 小結(jié)
9 安全與加密
5.2 使用MySQL數(shù)據(jù)庫
4.6 小結(jié)
8.4 RPC

11.3 Go怎么寫測試用例

開發(fā)程序其中很重要的一點(diǎn)是測試,我們?nèi)绾伪WC代碼的質(zhì)量,如何保證每個(gè)函數(shù)是可運(yùn)行,運(yùn)行結(jié)果是正確的,又如何保證寫出來的代碼性能是好的,我們知道單元測試的重點(diǎn)在于發(fā)現(xiàn)程序設(shè)計(jì)或?qū)崿F(xiàn)的邏輯錯(cuò)誤,使問題及早暴露,便于問題的定位解決,而性能測試的重點(diǎn)在于發(fā)現(xiàn)程序設(shè)計(jì)上的一些問題,讓線上的程序能夠在高并發(fā)的情況下還能保持穩(wěn)定。本小節(jié)將帶著這一連串的問題來講解Go語言中如何來實(shí)現(xiàn)單元測試和性能測試。

Go語言中自帶有一個(gè)輕量級(jí)的測試框架testing和自帶的go test命令來實(shí)現(xiàn)單元測試和性能測試,testing框架和其他語言中的測試框架類似,你可以基于這個(gè)框架寫針對(duì)相應(yīng)函數(shù)的測試用例,也可以基于該框架寫相應(yīng)的壓力測試用例,那么接下來讓我們一一來看一下怎么寫。

如何編寫測試用例

由于go test命令只能在一個(gè)相應(yīng)的目錄下執(zhí)行所有文件,所以我們接下來新建一個(gè)項(xiàng)目目錄gotest,這樣我們所有的代碼和測試代碼都在這個(gè)目錄下。

接下來我們?cè)谠撃夸浵旅鎰?chuàng)建兩個(gè)文件:gotest.go和gotest_test.go

  1. gotest.go:這個(gè)文件里面我們是創(chuàng)建了一個(gè)包,里面有一個(gè)函數(shù)實(shí)現(xiàn)了除法運(yùn)算:

      package gotest
    
      import (
          "errors"
      )
    
      func Division(a, b float64) (float64, error) {
          if b == 0 {
              return 0, errors.New("除數(shù)不能為0")
          }
    
          return a / b, nil
      }
  2. gotest_test.go:這是我們的單元測試文件,但是記住下面的這些原則:

    • 文件名必須是_test.go結(jié)尾的,這樣在執(zhí)行go test的時(shí)候才會(huì)執(zhí)行到相應(yīng)的代碼
    • 你必須import testing這個(gè)包
    • 所有的測試用例函數(shù)必須是Test開頭
    • 測試用例會(huì)按照源代碼中寫的順序依次執(zhí)行
    • 測試函數(shù)TestXxx()的參數(shù)是testing.T,我們可以使用該類型來記錄錯(cuò)誤或者是測試狀態(tài)
    • 測試格式:func TestXxx (t *testing.T),Xxx部分可以為任意的字母數(shù)字的組合,但是首字母不能是小寫字母[a-z],例如Testintdiv是錯(cuò)誤的函數(shù)名。
    • 函數(shù)中通過調(diào)用testing.TError, Errorf, FailNow, Fatal, FatalIf方法,說明測試不通過,調(diào)用Log方法用來記錄測試的信息。

      下面是我們的測試用例的代碼:

      package gotest
      
      import (
          "testing"
      )
      
      func Test_Division_1(t *testing.T) {
          if i, e := Division(6, 2); i != 3 || e != nil { //try a unit test on function
              t.Error("除法函數(shù)測試沒通過") // 如果不是如預(yù)期的那么就報(bào)錯(cuò)
          } else {
              t.Log("第一個(gè)測試通過了") //記錄一些你期望記錄的信息
          }
      }
      
      func Test_Division_2(t *testing.T) {
          t.Error("就是不通過")
      }

      我們?cè)陧?xiàng)目目錄下面執(zhí)行go test,就會(huì)顯示如下信息:

      --- FAIL: Test_Division_2 (0.00 seconds)
          gotest_test.go:16: 就是不通過
      FAIL
      exit status 1
      FAIL    gotest  0.013s

      從這個(gè)結(jié)果顯示測試沒有通過,因?yàn)樵诘诙€(gè)測試函數(shù)中我們寫死了測試不通過的代碼t.Error,那么我們的第一個(gè)函數(shù)執(zhí)行的情況怎么樣呢?默認(rèn)情況下執(zhí)行go test是不會(huì)顯示測試通過的信息的,我們需要帶上參數(shù)go test -v,這樣就會(huì)顯示如下信息:

      === RUN Test_Division_1
      --- PASS: Test_Division_1 (0.00 seconds)
          gotest_test.go:11: 第一個(gè)測試通過了
      === RUN Test_Division_2
      --- FAIL: Test_Division_2 (0.00 seconds)
          gotest_test.go:16: 就是不通過
      FAIL
      exit status 1
      FAIL    gotest  0.012s

      上面的輸出詳細(xì)的展示了這個(gè)測試的過程,我們看到測試函數(shù)1Test_Division_1測試通過,而測試函數(shù)2Test_Division_2測試失敗了,最后得出結(jié)論測試不通過。接下來我們把測試函數(shù)2修改成如下代碼:

      func Test_Division_2(t *testing.T) {
          if _, e := Division(6, 0); e == nil { //try a unit test on function
              t.Error("Division did not work as expected.") // 如果不是如預(yù)期的那么就報(bào)錯(cuò)
          } else {
              t.Log("one test passed.", e) //記錄一些你期望記錄的信息
          }
      }   

      然后我們執(zhí)行go test -v,就顯示如下信息,測試通過了:

      === RUN Test_Division_1
      --- PASS: Test_Division_1 (0.00 seconds)
          gotest_test.go:11: 第一個(gè)測試通過了
      === RUN Test_Division_2
      --- PASS: Test_Division_2 (0.00 seconds)
          gotest_test.go:20: one test passed. 除數(shù)不能為0
      PASS
      ok      gotest  0.013s

如何編寫壓力測試

壓力測試用來檢測函數(shù)(方法)的性能,和編寫單元功能測試的方法類似,此處不再贅述,但需要注意以下幾點(diǎn):

  • 壓力測試用例必須遵循如下格式,其中XXX可以是任意字母數(shù)字的組合,但是首字母不能是小寫字母

      func BenchmarkXXX(b *testing.B) { ... }
  • go test不會(huì)默認(rèn)執(zhí)行壓力測試的函數(shù),如果要執(zhí)行壓力測試需要帶上參數(shù)-test.bench,語法:-test.bench="test_name_regex",例如go test -test.bench=".*"表示測試全部的壓力測試函數(shù)
  • 在壓力測試用例中,請(qǐng)記得在循環(huán)體內(nèi)使用testing.B.N,以使測試可以正常的運(yùn)行
  • 文件名也必須以_test.go結(jié)尾

下面我們新建一個(gè)壓力測試文件webbench_test.go,代碼如下所示:

package gotest

import (
    "testing"
)

func Benchmark_Division(b *testing.B) {
    for i := 0; i < b.N; i++ { //use b.N for looping 
        Division(4, 5)
    }
}

func Benchmark_TimeConsumingFunction(b *testing.B) {
    b.StopTimer() //調(diào)用該函數(shù)停止壓力測試的時(shí)間計(jì)數(shù)

    //做一些初始化的工作,例如讀取文件數(shù)據(jù),數(shù)據(jù)庫連接之類的,
    //這樣這些時(shí)間不影響我們測試函數(shù)本身的性能

    b.StartTimer() //重新開始時(shí)間
    for i := 0; i < b.N; i++ {
        Division(4, 5)
    }
}

我們執(zhí)行命令go test -file webbench_test.go -test.bench=".*",可以看到如下結(jié)果:

PASS
Benchmark_Division  500000000            7.76 ns/op
Benchmark_TimeConsumingFunction 500000000            7.80 ns/op
ok      gotest  9.364s  

上面的結(jié)果顯示我們沒有執(zhí)行任何TestXXX的單元測試函數(shù),顯示的結(jié)果只執(zhí)行了壓力測試函數(shù),第一條顯示了Benchmark_Division執(zhí)行了500000000次,每次的執(zhí)行平均時(shí)間是7.76納秒,第二條顯示了Benchmark_TimeConsumingFunction執(zhí)行了500000000,每次的平均執(zhí)行時(shí)間是7.80納秒。最后一條顯示總共的執(zhí)行時(shí)間。

小結(jié)

通過上面對(duì)單元測試和壓力測試的學(xué)習(xí),我們可以看到testing包很輕量,編寫單元測試和壓力測試用例非常簡單,配合內(nèi)置的go test命令就可以非常方便的進(jìn)行測試,這樣在我們每次修改完代碼,執(zhí)行一下go test就可以簡單的完成回歸測試了。

上一篇:7.2 JSON處理下一篇:3 Web基礎(chǔ)