Golang - 测试用例示例代码


目录结构

在这里插入图片描述


代码示例

split.go

package split

import "strings"

// 定义一个切割字符串的包

// Split 按照 sep 分割 s, a:b:c --> a b c
func Split(s, sep string) []string {
	// 得到字符串中分隔符的数量
	sepNum := strings.Count(s, sep)
	// 按照分隔符数量申请内存
	r := make([]string, 0, sepNum+1)

	index := strings.Index(s, sep)
	for index >= 0 {
		r = append(r, s[:index])
		s = s[index+len(sep):]
		index = strings.Index(s, sep)
	}

	r = append(r, s)
	return r
}


split_test.go

package split

import (
	"fmt"
	"os"
	"reflect"
	"testing"
)

// 子测试集
func TestNormalSplit(t *testing.T) {
	get := Split("a:b:c", ":")
	want := []string{"a", "b", "c"}

	if ok := reflect.DeepEqual(get, want); !ok {
		t.Fatalf("期望结果: %v, 实际结果: %v\n", want, get)
	}
}

func TestMultiSplit(t *testing.T) {
	// 这里是 setup 和 teardown 的使用实例
	f := setupT(t)
	defer f(t)

	get := Split("a::b::c", "::")
	want := []string{"a", "b", "c"}

	if ok := reflect.DeepEqual(get, want); !ok {
		t.Fatalf("期望结果: %v, 实际结果: %v\n", want, get)
	} else {
		t.Log("pass test...")
	}
}

func TestNumSplit(t *testing.T) {
	get := Split("1231", "1")
	want := []string{"", "23", ""}

	if ok := reflect.DeepEqual(get, want); !ok {
		t.Fatalf("期望结果: %v, 实际结果: %v\n", want, get)
	}
}

// 子测试组
func TestSplitGroup(t *testing.T) {

	// 存放测试的结构体
	type test struct {
		str  string
		sep  string
		want []string
	}

	// 将测试用例都实例化到 map 中
	items := map[string]test{
		"normal": test{
			str:  "a:b:c",
			sep:  ":",
			want: []string{"a", "b", "c"},
		},
		"multi": test{
			str:  "a::b::c",
			sep:  "::",
			want: []string{"a", "b", "c"},
		},
		"num": test{
			str:  "1231",
			sep:  "1",
			want: []string{"", "23", ""},
		},
	}

	for k, i := range items {
		t.Run(k, func(t *testing.T) {
			get := Split(i.str, i.sep)
			if ok := reflect.DeepEqual(i.want, get); !ok {
				t.Fatalf("测试关键字: %v, 期望结果: %v, 实际结果: %v\n", k, i.want, get)
			}
		})
	}
}

// 性能测试 - 基础版
func BenchmarkSplit(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Split("a:b:c", ":")
	}
}

// 性能测试 - 并发版
func BenchmarkParallelSplit(b *testing.B) {
	// 设置 cpu 数量
	// b.SetParallelism(1)

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			Split("1231", "1")
		}
	})
}

// 在全局加前后操作
func TestMain(m *testing.M) {
	fmt.Println("start test...")
	r := m.Run()
	fmt.Println("end test...")
	os.Exit(r)
}

// 给单一测试用例加前后操作, 如果是性能测试, t 改 b 即可
func setupT(t *testing.T) func(t *testing.T) {
	t.Log("start test...")      // 测试前执行
	return func(t *testing.T) { // 返回函数名, 使用时 defer 调用
		t.Log("end test...")
	}
}


fib.go

package fib

// Fib 计算斐波那契数列
func Fib(n int) int {
	if n < 2 {
		return n
	}

	return Fib(n-1) + Fib(n-2)
}


fib_test.go

package fib

import "testing"

// 性能测试 - 性能对比, 根据数据量不同进行分析
func benchmarkFib(b *testing.B, n int) {
	// 清除耗时
	// b.ResetTimer()

	for i := 0; i < b.N; i++ {
		Fib(n)
	}
}

func BenchmarkFib2(b *testing.B) {
	benchmarkFib(b, 2)
}

func BenchmarkFib10(b *testing.B) {
	benchmarkFib(b, 10)
}

func BenchmarkFib20(b *testing.B) {
	benchmarkFib(b, 20)
}


运行结果

split code

xxx@xxx split % go test -v
testMain start test...
=== RUN   TestNormalSplit
--- PASS: TestNormalSplit (0.00s)
=== RUN   TestMultiSplit
--- PASS: TestMultiSplit (0.00s)
    split_test.go:111: setupT start test...
    split_test.go:30: pass test...
    split_test.go:113: setupT end test...
=== RUN   TestNumSplit
--- PASS: TestNumSplit (0.00s)
=== RUN   TestSplitGroup
=== RUN   TestSplitGroup/normal
=== RUN   TestSplitGroup/multi
=== RUN   TestSplitGroup/num
--- PASS: TestSplitGroup (0.00s)
    --- PASS: TestSplitGroup/normal (0.00s)
    --- PASS: TestSplitGroup/multi (0.00s)
    --- PASS: TestSplitGroup/num (0.00s)
PASS
testMain end test...
ok      xxx/split   0.013s


fib code

xxx@xxx Fib % go test -bench=. -v
goos: darwin
goarch: amd64
pkg: code.oldboy.com/Fib
BenchmarkFib2-4         100000000               10.9 ns/op
BenchmarkFib10-4         2000000               695 ns/op
BenchmarkFib20-4           20000             90912 ns/op
PASS
ok      xxx/Fib     5.728s

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值