一、gotests
gotests
是一個針對 Go 語言編寫的代碼自動生成工具。當寫測試代碼時,由於需要測試的函數或方法較多,且每個測試用例需要按照各種不同的場景編寫,使得編寫測試用例變得繁瑣而耗費時間。因此使用 gotests 可以自動生成函數或方法對應的測試用例代碼,提高編寫測試用例的效率。
go get -u github.com/cweill/gotests/...
在使用之前需要先安裝 gotests 工具:
實例:以下是一個簡單的函數 add
和 add
的測試用例, 運行 gotests 可以自動生成測試用例的代碼:
package main
import "fmt"
func add(a, b int) int {
return a + b
}
func main() {
fmt.Println(add(1, 2))
}
go test -v -cover
=== RUN Test_add
--- PASS: Test_add (0.00s)
PASS
coverage: 100.0% of statements
ok command-line-arguments 0.191s
二、gotest 上下文
在進行測試時,有時候需要使用到上下文(Context),然而,在測試中,通過測試上下文進行傳遞的操作比較麻煩。因此,gotest 提供了一種內置的上下文(Context)機制,可以用 gotest.C
對象來實現。
實例:以下是一個函數及測試用例。在測試用例中,可以引用 gotest.C 對象。
package main
import (
"testing"
)
func Test_calc(t *testing.T) {
c := context.Background()
t.Run("test1", func(t *testing.T) {
gotest.CB(t)
calc(c)
})
}
func calc(ctx context.Context) {
gotest.C.Log("the context is " ctx)
}
三、gotest pk
在編寫測試用例時,有時候需要在一個單獨的包內或導入其他包中的函數和變數。使用 go 命令進行測試時,包的名稱不會自動成為測試名稱,這需要手動指定。因此,gotest 提供了 -include
和 -exclude
等選項,切換使用以包名為測試名稱的模式。
實例:以下是包名為 pkg
的測試用例:
package pkg
import "testing"
func Test_add(t *testing.T) {
if add(1, 2) != 3 {
t.Fatal("error")
}
}
func Test_minus(t *testing.T) {
if minus(1, 2) != -1 {
t.Fatal("error")
}
}
運行測試時,可以使用 -p
參數指定包的名稱:
go test -v -p pkg
=== RUN Test_add
--- PASS: Test_add (0.00s)
=== RUN Test_minus
--- FAIL: Test_minus (0.00s)
minus_test.go:9: error
FAIL command-line-arguments 0.011s
FAIL
四、gotestwaf
使用 go 命令進行測試時,我們可以使用 -run
選項指定要運行的測試用例的名稱(pattern)。如果有多個 pattern,需要使用空格分隔。然而,當測試用例較多時,pattern 也可能會很多,使得修改了測試用例名稱或新增了測試用例會帶來很多麻煩。因此,gotest 提供了一個 -waf 選項,啟用自動發現測試用例。
實例:以下是一個帶有多個測試用例和 -waf 選項的例子:
func TestAdd1(t *testing.T) {
if add(1, 2) != 3 {
t.Fatal("error")
}
}
func TestAdd2(t *testing.T) {
if add(2, 3) != 5 {
t.Fatal("error")
}
}
func TestMinus(t *testing.T) {
if minus(1, 2) != -1 {
t.Fatal("error")
}
}
運行測試:
go test -v -waf
=== RUN TestAdd1
--- PASS: TestAdd1 (0.00s)
=== RUN TestAdd2
--- PASS: TestAdd2 (0.00s)
=== RUN TestMinus
--- FAIL: TestMinus (0.00s)
minus_test.go:9: error
FAIL command-line-arguments 0.011s
FAIL
五、gotest圍棋
圍棋是一種超越國界的傳統棋類,在日本、中國、韓國等國家廣為流行。因此,對於圍棋的編程實現和測試也是必要的,而 gotest 也提供了一個圍棋庫。
實例:以下是一個圍棋棋盤的例子:
package main
import (
"github.com/gorilla/mux"
"github.com/sunfmin/gothic"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
gothic.Writer.Write(w, "welcome!")
})
go http.ListenAndServe(":8080", r)
fmt.Println("start server: http://localhost:8080")
}
六、gotest面料
在進行測試時,有時候需要操作面料(fabric),比如 TCP 連接或 HTTP 請求。然而,在測試中進行面料操作比較麻煩,因為可能需要編寫一些網路通訊代碼。因此,gotest 提供了一種內置的面料對象(fabric),可以對 TCP 或 HTTP 進行模擬或代理。
實例:以下是一個通過 HTTP 請求進行判斷的例子:
func TestHttp(t *testing.T) {
var err error
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello, world")
}))
defer ts.Close()
var resp *http.Response
resp, err = http.Get(ts.URL)
if err != nil {
t.Fatal(err)
}
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
t.Fatal(err)
}
if string(body) != "hello, world\n" {
t.Fatalf("expect hello, world, but got %q", body)
}
}
七、gotest功能
除了支持測試用例的編寫和執行,gotest 還提供了一些進階功能。其中包括性能測試、覆蓋度分析、基準測試等。
實例1:以下是一個簡單的基準測試函數:
func BenchmarkMap(b *testing.B) {
b.Run("insert", func(b *testing.B) {
var m map[int]int
for i := 0; i < b.N; i++ {
m = make(map[int]int)
m[i] = i
_ = m[0]
}
})
b.Run("read", func(b *testing.B) {
var m = make(map[int]int, b.N)
for i := 0; i < b.N; i++ {
m[i] = i
}
_ = m[0]
})
}
實例2:以下是一個覆蓋度分析函數:
func Example() {
Cover()
}
func Cover() {
path := "/tmp/test.binary"
file, err := os.Create(path)
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
err = cover.StartCover(file)
if err != nil {
fmt.Println(err)
return
}
defer cover.StopCover()
Main()
cover.WriteCoverageData(file)
}
八、gotest 編譯過程
除了提供測試用例的編寫和執行外,gotest 還涵蓋了測試編譯過程的相關知識。通過了解測試編譯過程的內容,有助於我們在處理有關測試編譯時可能出現的問題時更好地理解和解決。
實例:以下是一個示常式序和編譯過程:
package main
import "testing"
func main() {
t := new(testing.T)
}
go test -c
% ls
command-line-arguments.test
九、gotest ruc edu cn
gotest 還提供了關於 gotest 項目的 API 介面。
實例:以下是 gotest API 的代碼:
package main
import (
"net/http"
"net/url"
)
const baseURL = "http://gotest.ruc.edu.cn/api/v1/"
func main() {
u, err := url.Parse(baseURL)
if err != nil {
panic(err)
}
u.RawQuery = "key=value"
client := &http.Client{}
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}
以上代碼使用了 Go 的 net/http 包,通過 HTTP 請求向 gotest API 進行訪問並獲取數據。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/291261.html