首頁 > 軟體

GOLang單元測試用法詳解

2022-12-17 14:00:46

概念

單元測試 UT測試,針對程式來進行正確檢測測試工作,一個優秀強壯程式碼 需要有完美的 UT測試用例

go test基本用法

  • go test 測試用例放在 *_test.go 檔案中,與被測函數放到同一個目錄下面go build 時候不會構建成包一部分
  • 被測試用例函數命名 TestXXX. 第一個字母必須大寫
  • 測試函數: 檢測邏輯是否正確
  • 基準函數以BenChmark 為函數名稱字首, 衡量函數效能
  • 範例函數: 以Example 函數名稱為字首函數 提供編譯器正確性的範例檔案

go test 基礎用例

首先 GoLand 中go Test 不成熟,如果直接執行 會丟擲 Undefined 的指令

藉助GoLand 對於指定方式 使用Generate 對需要函數產生對應的XX_test.go 檔案

只能 Teiminal 下:

如果想 直接執行當前目錄下所有測試用例: run go test,在當前目錄下面右鍵即可
如果指向單純執行某個函數 需要 到該目錄下面:

go test -v -run TestXXX 即可

goLand 給我們產生的單元測試使用用例 值需要我們位元組填寫對應 name(測試用例名稱),args(陣列,輸入引數) want(返回引數)

type args struct {
		s string
	}
	tests := []struct {
		name string
		args args
		want bool
	}{
		// TODO: Add test cases.
		{
			"test1",
			args{
				"kafka",
			},
			true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := IsPalindrome(tt.args.s); got != tt.want {
				t.Errorf("IsPalindrome() = %v, want %v", got, tt.want)
			}
		})
	}

使用 Go mod 解決此問題

在 GoPATH目錄下 手動視窗 bin, pkg, src 三個目錄

設定 Go Moudle 路徑

直接執行GOLand 即可

go test -v : 測試函數名字和執行時間
go test -v -run 對應正規表示式,測試函數與正確表示式匹配才會過濾 指定某個特定函數

測試可執行程式

用來測試一個可執行程式一個包的名字是main, 範例: 將程式拆分兩個函數, echo 函數完成真正的工作 main 函數用於處理命令列引數和 echo可能返回錯誤

import (
    "flag"
    "fmt"
    "io"
    "os"
    "strings"
)
var (
    n = flag.Bool("n", false, "omit trailing newline")
    s = flag.String("s", " ", "separator")
)
var out io.Writer = os.Stdout // modified during testing
func main() {
    flag.Parse()
    if err := echo(!*n, *s, flag.Args()); err != nil {
        fmt.Fprintf(os.Stderr, "echo: %vn", err)
        os.Exit(1)
    }
}
func echo(newline bool, sep string, args []string) error {
    fmt.Fprint(out, strings.Join(args, sep))
    if newline {
        fmt.Fprintln(out)
    }
    return nil
}
import (
    "bytes"
    "fmt"
    "testing"
)
func TestEcho(t *testing.T) {
    var tests = []struct {
        newline bool
        sep     string
        args    []string
        want    string
    }{
        {true, "", []string{}, "n"},
        {false, "", []string{}, ""},
        {true, "t", []string{"one", "two", "three"}, "onettwotthreen"},
        {true, ",", []string{"a", "b", "c"}, "a,b,cn"},
        {false, ":", []string{"1", "2", "3"}, "1:2:3"},
    }
    for _, test := range tests {
        descr := fmt.Sprintf("echo(%v, %q, %q)",
            test.newline, test.sep, test.args)
        out = new(bytes.Buffer) // captured output
        if err := echo(test.newline, test.sep, test.args); err != nil {
            t.Errorf("%s failed: %v", descr, err)
            continue
        }
        got := out.(*bytes.Buffer).String()
        if got != test.want {
            t.Errorf("%s = %q, want %q", descr, got, test.want)
        }
    }
}

外部測試包解決迴圈依賴

外部測試主要用來 解決 測試過程中迴圈依賴問題, GO語言中禁止包進行迴圈依賴,解決一個下層包的測試程式碼匯入上層包的這種行為解決方案:z在net.url 包所在目錄宣告一個獨立url_test 測試包,其中包名_test 字尾告訴go test 工具建立一個額外包進行允許測試

測試覆蓋比例

go test -run=Coverage -coverprofile=c.out gopl.io/ch7/eval

go tool cover -html=c.out

測試基準函數

在固定的工作負載下的效能,一Benchmark 字首

go test -bench=IsPalindrome , . 表示匹配所有基準測試函數

func BenchmarkIsPalindrome(b *testing.B) {
	for i := 0; i < b.N; i++ {
		IsPalindrome("A man, a plan, a canal: Panama")
	}
}
goos: windows
goarch: amd64
pkg: goprograme/src
cpu: Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
BenchmarkIsPalindrome
BenchmarkIsPalindrome-4          2308773               502.9 ns/op

1. 基準函數數位字尾 -4 表示執行時候對應 GOMAXPROCS 值, 與並行相關的基準測試重要資訊
2. 每個呼叫函數 花費時間 502.9 微妙
3. 明顯 上面 函數 判斷是 第二個函數 使用 

1.n := len(letters) /2 z只比較一般方式優化 測試後只是改進 提升 4%

2. 在每個字元預先分配一個足夠大的陣列,這樣避免在append 函數時候可能導致記憶體多次重新分配
-- 通過效能工具的測試 從而優化我們的程式

func IsPalindrome(s string) bool {
    letters := make([]rune, 0, len(s))
    for _, r := range s {
        if unicode.IsLetter(r) {
            letters = append(letters, unicode.ToLower(r))
        }
    }
    n := len(letters) / 2
    for i := 0; i < n; i++ {
        if letters[i] != letters[len(letters)-1-i] {
            return false
        }
    }
    return true
}

到此這篇關於GOLang單元測試用法詳解的文章就介紹到這了,更多相關GO單元測試內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com