测试分为三种
- 回归测试
- 集成测试
- 单元测试
从上到下,覆盖率逐层变大,成本却逐层降低
单元测试 规则
所有测试文件以 _test.go 结尾
publish_post.go
publish_post_test.go
函数名命名 func TestXxx(*testing.T)
func TestPublishPost(t *testing.T){
初始化逻辑放到 TestMain 中
func TestMain(m *testing.M){
//测试前:数据装载、配置初始化等前置工作
code := m.Run()
//测试后:释放资源等收尾工作
os.Exit(code)
}
单元测试 运行
func HelloTom() string {
return "Jerry"
}
func TestHelloTom(t *testing.T) {
output := HelloTom()
expectOutput := "Jerry"
if output != expectOutput {
t.Errorf("Expected %s do not match actual %s", expectOutput, output)
}
}
PS E:\Code\go\practice> go test ./A_test.go
ok command-line-arguments 0.612s
PS E:\Code\go\practice>
单元测试 assert
import (
"github.com/stretchr/testify/assert"
"testing"
)
func HelloTom() string {
return "Jerry"
}
func TestHelloTom(t *testing.T) {
output := HelloTom()
expectOutput := "Tom"
assert.Equal(t, expectOutput, output)
}
单元测试 依赖
外部依赖 ⇒ 稳定&幂等
单元测试 文件处理
func ReadFirstLine() string {
open, err := os.Open("log")
defer open.Close()
if err != nil {
return ""
}
scanner := bufio.NewScanner(open)
for scanner.Scan() {
return scanner.Text()
}
return ""
}
func ProcessFirstLine() string {
line := ReadFirstLine()
destLine := strings.ReplaceAll(line, "11", "00")
return destLine
}
func TestProcessFirstLine(t *testing.T) {
firstLine := ProcessFirstLine()
assert.Equal(t, "line00", firstLine)
}
基准测试 运行
var ServerIndex [10]int
func InitServerIndex() {
for i := 0; i < 10; i++ {
ServerIndex[i] = i + 100
}
}
func Select() int {
return ServerIndex[rand.Intn(10)]
}
func BenchmarkSelect(b *testing.B) {
InitServerIndex()
b.ResetTimer()
for i := 0; i < b.N; i++ {
Select()
}
}
func BenchmarkSelectParallel(b *testing.B) {
InitServerIndex()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Select()
}
})
}
这两个代码块是 Go 语言中用于性能测试的基准函数(benchmark)。它们都会运行 Select() 函数并返回其运行时间,但第二个函数使用了 b.RunParallel() 函数来并发运行测试循环,相比于第一个函数,第二个函数可以更好地模拟并发负载的情况。
具体来说,BenchmarkSelectParallel() 函数使用了 b.RunParallel() 函数来创建多个 goroutine 并发运行 Select() 函数。每个 goroutine 都会在不同的 CPU 上运行,以便更好地利用多核处理器的性能。这样可以更好地模拟并发负载下的性能表现,从而更全面地评估程序的性能。
与此相反,BenchmarkSelect() 函数没有使用并发,而只是简单地运行 Select() 函数,因此它不能模拟并发负载下的性能表现,并且可能无法完全展现程序在真实场景下的性能表现。
Testing 方法总结
testing.T:是单元测试中最常用的对象,表示一个测试用例。你可以在该对象上调用各种断言方法,如Error、Fail、FailNow等来判断测试结果是否正确。testing.B:是基准测试中使用的对象,表示一个基准测试用例。你可以在该对象上调用ResetTimer、StartTimer、StopTimer等方法来控制基准测试的计时器。testing.M:表示一个测试main函数中的对象,主要用于协调测试用例的执行。例如,在测试用例执行之前,你可以在测试main函数中添加一些代码来初始化一些共享资源。testing.C:表示一个子测试用例,通常是在testing.T对象上调用Run方法时创建的。它允许你对测试用例进行更细粒度的划分和管理。testing.Short:标记当前测试为短时间测试,用于快速检查某个功能或快速运行测试套件。testing.Verbose:设置测试输出详细信息,包括每个测试用例的名称以及测试结果等。testing.PB:是性能测试中使用的对象,表示一个性能测试用例。你可以在该对象上调用Start、Stop等方法来控制性能测试的计时器。