测试go test

这篇具有很好参考价值的文章主要介绍了测试go test。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Go 语言从开发初期就注意了测试用例的编写。特别是静态语言,由于调试没有动态语言那么方便,所以能最快最方便地编写一个测试用例就显得非常重要了。

  1. testing 方便进行 Go 包的自动化单元测试、基准测试
  2. net/http/httptest 提供测试 HTTP 的工具

go test工具

Go语言中的测试依赖go test命令。编写测试代码和编写普通的Go代码过程是类似的,并不需要学习新的语法、规则或工具。

go test命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录内,所有以_test.go为后缀名的源代码文件都是go test测试的一部分,不会被go build编译到最终的可执行文件中。

在*_test.go文件中有三种类型的函数,单元测试函数、基准测试函数和示例函数。

类型 格式 作用
测试函数 函数名前缀为Test 测试程序的一些逻辑行为是否正确
基准函数 函数名前缀为Benchmark 测试函数的性能
示例函数 函数名前缀为Example 为文档提供示例文档

go test命令会遍历所有的*_test.go文件中符合上述命名规则的函数,然后生成一个临时的main包用于调用相应的测试函数,然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。

单元测试

格式:Xxx 可以是任何字母数字字符串,但是第一个字母不能是小写字母。

func TestXxxx(t *testing.T){
    // ...
}

t参数拥有以下方法:

func (c *T) Cleanup(func())
func (c *T) Error(args ...interface{})
func (c *T) Errorf(format string, args ...interface{})
func (c *T) Fail()
func (c *T) FailNow()
func (c *T) Failed() bool
func (c *T) Fatal(args ...interface{})
func (c *T) Fatalf(format string, args ...interface{})
func (c *T) Helper()
func (c *T) Log(args ...interface{})
func (c *T) Logf(format string, args ...interface{})
func (c *T) Name() string
func (c *T) Skip(args ...interface{})
func (c *T) SkipNow()
func (c *T) Skipf(format string, args ...interface{})
func (c *T) Skipped() bool
func (c *T) TempDir() string

gotest 的变量有这些:
test.short : 一个快速测试的标记,在测试用例中可以使用 testing.Short() 来绕开一些测试
test.outputdir : 输出目录
test.coverprofile : 测试覆盖率参数,指定输出文件
test.run : 指定正则来运行某个 / 某些测试用例
test.memprofile : 内存分析参数,指定输出文件
test.memprofilerate : 内存分析参数,内存分析的抽样率
test.cpuprofile : cpu 分析输出参数,为空则不做 cpu 分析
test.blockprofile : 阻塞事件的分析参数,指定输出文件
test.blockprofilerate : 阻塞事件的分析参数,指定抽样频率
test.timeout : 超时时间
test.cpu : 指定 cpu 数量
test.parallel : 指定运行测试用例的并行数

测试代码

// main.go
func Fib(n int) int {
        if n < 2 {
                return n
        }
        return Fib(n-1) + Fib(n-2)
}

// fib_test.go
func TestFib(t *testing.T) {
    var (
        in       = 7
        expected = 13
    )
    actual := Fib(in)
    if actual != expected {
        t.Errorf("Fib(%d) = %d; expected %d", in, actual, expected)
    }
}

执行 go test .,(可以为go test命令添加-v参数,让它输出完整的测试结果。)输出:
go test 指定文件,GO,golang,单元测试,测试用例
go test 指定文件,GO,golang,单元测试,测试用例

go test -run

  1. 在执行go test命令的时候可以添加-run参数,它对应一个正则表达式,只有函数名匹配上的测试函数才会被go test命令执行。

  2. 例如通过给go test添加-run=Sep参数来告诉它本次测试只运行TestFuckingSep这个测试用例。

跳过某些测试用例

为了节省时间支持在单元测试时跳过某些耗时的测试用例。

func TestTimeConsuming(t *testing.T) {
    if testing.Short() {
        t.Skip("short模式下会跳过该测试用例")
    }
    ...
}

当执行go test -short时就不会执行上面的TestTimeConsuming测试用例。

子测试

Go1.7+中新增了子测试,支持在测试函数中使用t.Run执行一组测试用例,这样就不需要为不同的测试数据定义多个测试函数了。

func TestXXX(t *testing.T){
  t.Run("case1", func(t *testing.T){...})
  t.Run("case2", func(t *testing.T){...})
  t.Run("case3", func(t *testing.T){...})
}
// 循环实现
func TestSplit(t *testing.T) {
	type test struct { // 定义test结构体
		input string
		sep   string
		want  []string
	}
	tests := map[string]test{ // 测试用例使用map存储
		"simple":      {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}},
		"wrong sep":   {input: "a:b:c", sep: ",", want: []string{"a:b:c"}},
		"more sep":    {input: "abcd", sep: "bc", want: []string{"a", "d"}},
		"leading sep": {input: "沙河有沙又有河", sep: "沙", want: []string{"河有", "又有河"}},
	}
	for name, tc := range tests {
		got := Split(tc.input, tc.sep)
		if !reflect.DeepEqual(got, tc.want) {
			t.Errorf("name:%s expected:%#v, got:%#v", name, tc.want, got) // 将测试用例的name格式化输出
		}
	}
}

// 用自测试方法实现
func TestSplit(t *testing.T) {
	type test struct { // 定义test结构体
		input string
		sep   string
		want  []string
	}
	tests := map[string]test{ // 测试用例使用map存储
		"simple":      {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}},
		"wrong sep":   {input: "a:b:c", sep: ",", want: []string{"a:b:c"}},
		"more sep":    {input: "abcd", sep: "bc", want: []string{"a", "d"}},
		"leading sep": {input: "沙河有沙又有河", sep: "沙", want: []string{"河有", "又有河"}},
	}
	for name, tc := range tests {
		t.Run(name, func(t *testing.T) { // 使用t.Run()执行子测试
			got := Split(tc.input, tc.sep)
			if !reflect.DeepEqual(got, tc.want) {
				t.Errorf("expected:%#v, got:%#v", tc.want, got)
			}
		})
	}
}

表格驱动测试

测试讲究 case 覆盖,按上面的方式,要覆盖更多 case 时,显然通过修改代码的方式很笨拙。这时可以采用 Table-Driven 的方式写测试,标准库中有很多测试是使用这种方式写的。

表格驱动测试的步骤通常是定义一个测试用例表格,然后遍历表格,并使用t.Run对每个条目执行必要的测试。

func TestFib(t *testing.T) {
    var fibTests = []struct {
        in       int // input
        expected int // expected result
    }{
        {1, 1},
        {2, 1},
        {3, 2},
        {4, 3},
        {5, 5},
        {6, 8},
        {7, 13},
    }

    for _, tt := range fibTests {
        actual := Fib(tt.in)
        if actual != tt.expected {
            t.Errorf("Fib(%d) = %d; expected %d", tt.in, actual, tt.expected)
        }
    }
}

并行测试

表格驱动测试中通常会定义比较多的测试用例,而Go语言又天生支持并发,所以很容易发挥自身并发优势将表格驱动测试并行化。 想要在单元测试过程中使用并行测试,可以像下面的代码示例中那样通过添加t.Parallel()来实现。

func TestSplitAll(t *testing.T) {
	// 将 TLog 标记为能够与其他测试并行运行
	t.Parallel()  

	// 定义测试表格
	// 为每个测试用例设置了一个名称
	tests := []struct {
		name  string
		input string
		sep   string
		want  []string
	}{
		{"base case", "a:b:c", ":", []string{"a", "b", "c"}},
		{"wrong sep", "a:b:c", ",", []string{"a:b:c"}},
		{"more sep", "abcd", "bc", []string{"a", "d"}},
		{"leading sep", "沙河有沙又有河", "沙", []string{"", "河有", "又有河"}},
	}
	// 遍历测试用例
	for _, tt := range tests {
		tt := tt  // 注意这里重新声明tt变量(避免多个goroutine中使用了相同的变量)
		t.Run(tt.name, func(t *testing.T) { // 使用t.Run()执行子测试
			t.Parallel()  // 将每个测试用例标记为能够彼此并行运行
			got := Split(tt.input, tt.sep)
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("expected:%#v, got:%#v", tt.want, got)
			}
		})
	}
}

报告方法

  1. 遇到一个断言错误的时候,标识这个测试失败:

    Fail() : 测试失败,测试继续
    FailNow() : 测试失败,测试中断
    
  2. 遇到一个断言错误,只希望跳过这个错误,但是不希望标识测试失败:

    SkipNow() : 跳过测试,测试中断
    
  3. 只希望打印信息

    Log : 输出信息
    Logf : 输出格式化的信息
    
  4. 希望跳过这个测试,并且打印出信息

    Skip : 相当于 Log + SkipNow
    Skipf : 相当于 Logf + SkipNow
    
  5. 希望断言失败的时候,标识测试失败,并打印出必要的信息,但是测试继续

    Error : 相当于 Log + Fail
    Errorf : 相当于 Logf + Fail
    
  6. 希望断言失败的时候,标识测试失败,打印出必要的信息,但中断测试

    Fatal : 相当于 Log + FailNow
    Fatalf : 相当于 Logf + FailNow
    

测试覆盖率

测试覆盖率是指代码被测试套件覆盖的百分比,也就是在测试中至少被运行一次的代码占总代码的比例。在公司内部一般会要求测试覆盖率达到80%左右。

使用go test -cover来查看测试覆盖率。

go test -cover
PASS
coverage: 100.0% of statements
ok      golang-unit-test-demo/base_demo 0.009s

Go还提供了一个额外的-coverprofile参数,用来将覆盖率相关的记录信息输出到一个文件:

go test -cover -coverprofile=c.out
PASS
coverage: 100.0% of statements
ok      golang-unit-test-demo/base_demo 0.009s

然后执行go tool cover -html=c.out,使用cover工具来处理生成的记录信息,该命令会打开本地的浏览器窗口生成一个HTML报告。
go test 指定文件,GO,golang,单元测试,测试用例

基准测试

基准测试就是在一定的工作负载之下检测程序性能的一种方法。

func BenchmarkName(b *testing.B){
    // ...
}

基准测试以Benchmark为前缀,需要一个*testing.B类型的参数b,基准测试必须要执行b.N次,这样的测试才有对照性,b.N的值是系统根据实际情况去调整的,从而保证测试的稳定性。 testing.B拥有的方法如下:

func (c *B) Error(args ...interface{})
func (c *B) Errorf(format string, args ...interface{})
func (c *B) Fail()
func (c *B) FailNow()
func (c *B) Failed() bool
func (c *B) Fatal(args ...interface{})
func (c *B) Fatalf(format string, args ...interface{})
func (c *B) Log(args ...interface{})
func (c *B) Logf(format string, args ...interface{})
func (c *B) Name() string
func (b *B) ReportAllocs()
func (b *B) ResetTimer()
func (b *B) Run(name string, f func(b *B)) bool
func (b *B) RunParallel(body func(*PB))
func (b *B) SetBytes(n int64)
func (b *B) SetParallelism(p int)
func (c *B) Skip(args ...interface{})
func (c *B) SkipNow()
func (c *B) Skipf(format string, args ...interface{})
func (c *B) Skipped() bool
func (b *B) StartTimer()
func (b *B) StopTimer()

demo

func BenchmarkHello(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fmt.Sprintf("hello")
    }
}

通过 go test 命令,加上 -bench 标志来执行。

结果输出:
go test 指定文件,GO,golang,单元测试,测试用例

  1. 意味着函数执行了 30542277 次,每次循环花费 33.73 纳秒 (ns)。
  2. 数字16表示GOMAXPROCS的值,这个对于并发基准测试很重要.

还可以为基准测试添加-benchmem参数,来获得内存分配的统计数据。

go test 指定文件,GO,golang,单元测试,测试用例
5 B/op表示每次操作内存分配了5字节,1 allocs/op则表示每次操作进行了1次内存分配

性能比较函数

通常需要对两个不同算法的实现使用相同的输入来进行基准比较测试。

func benchmarkFib(b *testing.B, n int) {
	for i := 0; i < b.N; i++ {
		Fib(n)
	}
}

func BenchmarkFib1(b *testing.B)  { benchmarkFib(b, 1) }
func BenchmarkFib2(b *testing.B)  { benchmarkFib(b, 2) }
func BenchmarkFib3(b *testing.B)  { benchmarkFib(b, 3) }
func BenchmarkFib10(b *testing.B) { benchmarkFib(b, 10) }
func BenchmarkFib20(b *testing.B) { benchmarkFib(b, 20) }
func BenchmarkFib40(b *testing.B) { benchmarkFib(b, 40) }

默认情况下,每个基准测试至少运行1秒。如果在Benchmark函数返回时没有到1秒,则b.N的值会按1,2,5,10,20,50,…增加,并且函数再次运行。

可以使用-benchtime标志增加最小基准时间,以产生更准确的结果:
go test -bench=Fib40 -benchtime=20s

计时方法

有三个方法用于计时:

  1. StartTimer:开始对测试进行计时。该方法会在基准测试开始时自动被调用,也可以在调用 StopTimer 之后恢复计时;
  2. StopTimer:停止对测试进行计时。当需要执行一些复杂的初始化操作,并且不想对这些操作进行测量时,就可以使用这个方法来暂时地停止计时;
    3/ ResetTimer:对已经逝去的基准测试时间以及内存分配计数器进行清零。对于正在运行中的计时器,这个方法不会产生任何效果。
func BenchmarkSplit(b *testing.B) {
	time.Sleep(5 * time.Second) // 假设需要做一些耗时的无关操作
	b.ResetTimer()              // 重置计时器
	for i := 0; i < b.N; i++ {
		Split("xx.xx.xx.xx", ".")
	}
}

并行测试

func (b *B) RunParallel(body func(*PB))会以并行的方式执行给定的基准测试。

通过 RunParallel 方法能够并行地执行给定的基准测试。RunParallel会创建出多个 goroutine,并将 b.N 分配给这些 goroutine 执行,其中 goroutine 数量的默认值为 GOMAXPROCS。用户如果想要增加非 CPU 受限(non-CPU-bound)基准测试的并行性,那么可以在 RunParallel 之前调用 SetParallelism(如 SetParallelism(2),则 goroutine 数量为 2*GOMAXPROCS)。RunParallel 通常会与 -cpu 标志一同使用。

body 函数将在每个 goroutine 中执行,这个函数需要设置所有 goroutine 本地的状态,并迭代直到 pb.Next 返回 false 值为止。因为 StartTimer、StopTime 和 ResetTimer 这三个方法都带有全局作用,所以 body 函数不应该调用这些方法; 除此之外,body 函数也不应该调用 Run 方法。

func BenchmarkSplitParallel(b *testing.B) {
	// b.SetParallelism(1) // 设置使用的CPU数
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			Split("xx.xx.xx.xx", ".")
		}
	})
}

还可以通过在测试命令后添加-cpu参数如go test -bench=. -cpu 1来指定使用的CPU数量。

TestMain

通过在*_test.go文件中定义TestMain函数来可以在测试之前进行额外的设置(setup)或在测试之后进行拆卸(teardown)操作。

如果测试文件包含函数:func TestMain(m *testing.M)那么生成的测试会先调用 TestMain(m),然后再运行具体测试。TestMain运行在主goroutine中, 可以在调用 m.Run前后做任何设置(setup)和拆卸(teardown)。退出测试的时候应该使用m.Run的返回值作为参数调用os.Exit。

func TestMain(m *testing.M) {
	fmt.Println("write setup code here...") // 测试之前的做一些设置
	// 如果 TestMain 使用了 flags,这里应该加上flag.Parse()
	retCode := m.Run()                         // 执行测试
	fmt.Println("write teardown code here...") // 测试之后做一些拆卸工作
	os.Exit(retCode)                           // 退出测试
}

Setup与Teardown

有时候可能需要为每个测试集设置Setup与Teardown,也有可能需要为每个子测试设置Setup与Teardown。

// 测试集的Setup与Teardown
func setupTestCase(t *testing.T) func(t *testing.T) {
	t.Log("如有需要在此执行:测试之前的setup")
	// 返回Teardown
	return func(t *testing.T) {
		t.Log("如有需要在此执行:测试之后的teardown")
	}
}

// 子测试的Setup与Teardown
func setupSubTest(t *testing.T) func(t *testing.T) {
	t.Log("如有需要在此执行:子测试之前的setup")
	// 返回Teardown
	return func(t *testing.T) {
		t.Log("如有需要在此执行:子测试之后的teardown")
	}
}
func TestSplit(t *testing.T) {
	type test struct { // 定义test结构体
		input string
		sep   string
		want  []string
	}
	tests := map[string]test{ // 测试用例使用map存储
		"simple":      {input: "a:b:c", sep: ":", want: []string{"a", "b", "c"}},
		"wrong sep":   {input: "a:b:c", sep: ",", want: []string{"a:b:c"}},
		"more sep":    {input: "abcd", sep: "bc", want: []string{"a", "d"}},
		"leading sep": {input: "沙河有沙又有河", sep: "沙", want: []string{"", "河有", "又有河"}},
	}
	teardownTestCase := setupTestCase(t) // 测试之前执行setup操作
	defer teardownTestCase(t)            // 测试之后执行testdoen操作

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) { // 使用t.Run()执行子测试
			teardownSubTest := setupSubTest(t) // 子测试之前执行setup操作
			defer teardownSubTest(t)           // 测试之后执行testdoen操作
			got := Split(tc.input, tc.sep)
			if !reflect.DeepEqual(got, tc.want) {
				t.Errorf("expected:%#v, got:%#v", tc.want, got)
			}
		})
	}
}

httptest

由于 Go 标准库的强大支持,Go 可以很容易的进行 Web 开发。为此,Go 标准库专门提供了 net/http/httptest 包专门用于进行 http Web 开发测试。

简单的 Web 应用

// 保存 Topic,没有考虑并发问题
var TopicCache = make([]*Topic, 0, 16)

type Topic struct {
    Id        int       `json:"id"`
    Title     string    `json:"title"`
    Content   string    `json:"content"`
    CreatedAt time.Time `json:"created_at"`
}

func main() {
    http.HandleFunc("/topic/", handleRequest)
    http.ListenAndServe(":2017", nil)
}
/topic/ 开头的请求都交由 handleRequest 处理,它根据不同的 Method 执行相应的增删改查
...

测试

func TestHandlePost(t *testing.T) {
    mux := http.NewServeMux()
    mux.HandleFunc("/topic/", handleRequest)

    reader := strings.NewReader(`{"title":"The Go Standard Library","content":"It contains many packages."}`)
    r, _ := http.NewRequest(http.MethodPost, "/topic/", reader)
	
	// httptest.NewRecorder() 可以获得 httptest.ResponseRecorder 结构,而此结构实现了http.ResponseWriter 接口。
    w := httptest.NewRecorder()

    mux.ServeHTTP(w, r)

    resp := w.Result()
    if resp.StatusCode != http.StatusOK {
        t.Errorf("Response code is %v", resp.StatusCode)
    }
}

通过 go test -v 运行测试。

pprof 性能分析

  1. benchmark(基准测试) 可以度量某个函数或方法的性能,也就是说,如果我们知道性能的瓶颈点在哪里,benchmark 是一个非常好的方式。
  2. 但是面对一个未知的程序,如何去分析这个程序的性能,并找到瓶颈点呢?

pprof 就是用来解决这个问题的,pprof 包含两部分:
3. 编译到程序中的 runtime/pprof 包
4. 性能剖析工具 go tool pprof

性能分析类型

记录性能数据会对程序的性能产生影响,建议一次只记录一类数据。

CPU

  1. 启动 CPU 分析时,运行时(runtime) 将每隔 10ms 中断一次,记录此时正在运行的协程(goroutines) 的堆栈信息。

  2. 程序运行结束后,可以分析记录的数据找到最热代码路径(hottest code paths)。

  3. 一个函数在性能分析数据中出现的次数越多,说明执行该函数的代码路径(code path)花费的时间占总运行时间的比重越大。

使用
import (
	"math/rand"
	"os"
	"runtime/pprof"
	"time"
)

func main() {
	pprof.StartCPUProfile(os.Stdout)
	defer pprof.StopCPUProfile()
	n := 10
	for i := 0; i < 5; i++ {
		nums := generate(n)
		bubbleSort(nums)
		n *= 10
	}
}

运行该程序,将输出定向到文件 cpu.pprof 中。
$ go run main.go > cpu.pprof

接下来,用 go tool pprof 分析这份数据(展示结果到网页)
$ go tool pprof -http=:9999 cpu.pprof

用控制台输出结果:
go tool pprof cpu.pprof

一般来说,不建议将结果直接输出到标准输出,因为如果程序本身有输出,则会相互干扰,直接记录到一个文件中是最好的方式。

func main() {
	f, _ := os.OpenFile("cpu.pprof", os.O_CREATE|os.O_RDWR, 0644)
	defer f.Close()
	pprof.StartCPUProfile(f)
	defer pprof.StopCPUProfile()
	n := 10
	for i := 0; i < 5; i++ {
		nums := generate(n)
		bubbleSort(nums)
		n *= 10
	}
}

运行go build 编译执行即可。

报错

如果出现报错:
go test 指定文件,GO,golang,单元测试,测试用例
官网下载graphviz即可:地址
go test 指定文件,GO,golang,单元测试,测试用例
此处勾选环境变量:

go test 指定文件,GO,golang,单元测试,测试用例
验证成功:cmd输入dot -version即可
go test 指定文件,GO,golang,单元测试,测试用例

内存

内存性能分析(Memory profiling) 记录堆内存分配时的堆栈信息,忽略栈内存分配信息。

阻塞性能分析

阻塞性能分析(block profiling) 是 Go 特有的。

阻塞性能分析用来记录一个协程等待一个共享资源花费的时间。在判断程序的并发瓶颈时会很有用。阻塞的场景包括:

  1. 在没有缓冲区的信道上发送或接收数据。
  2. 从空的信道上接收数据,或发送数据到满的信道上。
  3. 尝试获得一个已经被其他协程锁住的排它锁。

一般情况下,当所有的 CPU 和内存瓶颈解决后,才会考虑这一类分析。

锁性能分析

锁性能分析(mutex profiling) 与阻塞分析类似,但专注于因为锁竞争导致的等待或延时。文章来源地址https://www.toymoban.com/news/detail-693961.html

到了这里,关于测试go test的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Go 单元测试中 testing 包的数据类型M/T/B/PB

    testing.M 对main方法进行的测试 testing.T 对函数/方法进行单元测试 testing. B 对性能进行的测试 testing.PB - 命令 作用 go test 【包名】或 go test . 运行当前package内的所有用例 go test ./… 或 go test 【目录名】/… 递归执行当前目录下所有用例: go test -v [单元测试文件]. // 如 go test -v f

    2024年04月17日
    浏览(32)
  • 7 文件操作、单元测试、goroutine【Go语言教程】

    1.1 介绍 os.File 封装所有文件相关操作,File 是一个结构体 常用方法: 打开文件 关闭文件 1.2 应用实例 ①读文件 常用方法: ①bufio.NewReader(), reader.ReadString【带缓冲】 ②io/ioutil【一次性读取,适用于小文件】 读取文件的内容并显示在终端(带缓冲区的方式),使用 os.Open, file.

    2024年02月04日
    浏览(51)
  • 测试go test

    Go 语言从开发初期就注意了测试用例的编写。特别是静态语言,由于调试没有动态语言那么方便,所以能最快最方便地编写一个测试用例就显得非常重要了。 testing 方便进行 Go 包的自动化单元测试、基准测试 net/http/httptest 提供测试 HTTP 的工具 Go语言中的测试依赖go test命令。

    2024年02月10日
    浏览(39)
  • Go Test测试教程

    go中测试既有类似有 pytest 中的功能测试,也有 benchMark 的基准测试,以及单元测试( Unit Tests , UT ).这里从单元测试UT引入本篇的话题,单元测试的重要性不言而喻,尤其在大型项目中跨团队合作时,无法mr合格的代码,很容易影响整个团队的交付进度和质量。或者会说直接

    2024年02月15日
    浏览(40)
  • Go 工具链详解(三): 代码测试神器 go test

    go test 是 Go 工具链中的一个命令,用于编译和运行按照要求编写的 Golang 测试代码,并生成测试报告。 要求将测试代码所在的文件命名为 *_test.go,如此命名的文件不会被 go build 命令编译,但是会被 go test 进行编译和运行。在 *_test.go 中有几种类型的函数: 单元测试函数:以

    2024年02月16日
    浏览(42)
  • Maven-使用maven mvn命令进行单元测试、指定测试某个类、mvn test

    添加测试插件 运行mvn test命令

    2024年02月05日
    浏览(58)
  • 测试工具 go-stress-testing/fortio/vegeta 使用体验

    go-stress-testing 是一款由go语言实现的压测工具,源码开源、支持二次开发、可以压测http、webSocket请求、私有rpc调用,使用协程模拟单个用户,可以更高效的利用CPU资源 下载地址 注意需要将项目源码 clone 到 $GOPATH 目录下 mac电脑下载如下这个 放到 $GOPATH 目录下 赋权 chmod +x go

    2024年02月08日
    浏览(59)
  • Go单元测试入门

    测试文件以 _test.go 结尾 假如 calc.go 的代码如下: 那么 calc_test.go 中的测试用例可以这么写: 测试用例名称一般 命名为 Test 加上待测试的方法名。 测试用的参数有且只有一个,在这里是 t *testing.T。 基准测试(benchmark)的参数是 *testing.B,TestMain 的参数是 *testing.M 类型。 运行

    2024年02月09日
    浏览(38)
  • Go 单元测试基本介绍

    目录 一、单元测试基本介绍 1.1 什么是单元测试? 1.2 如何写好单元测试 1.3 单元测试的优点 1.4 单元测试的设计原则 二、Go语言测试 2.1 Go单元测试概要 2.2 Go单元测试基本规范 2.3 一个简单例子 2.3.1 使用Goland 生成测试文件 2.3.2 运行单元测试 2.3.3 完善测试用例 2.3.5 回归测试

    2024年04月16日
    浏览(40)
  • Go语言单元测试

    Go语言中的测试依赖 go test 命令,go test 命令是一个按照一定约定和组织的测试代码的驱动程序。在包目录 内,所有以 _test.go 为后缀名的源代码文件都是 go test 测试的一部分,不会被 go build 编译到最终的可执行 文件中。 在 *_test.go 文件中有三种类型的函数, 单元测试函数

    2024年02月11日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包