strikingly建站怎么样,如何对网站做镜像,织梦做的网站如何放在网上,做视频链接的网站文章目录 单元测试基准测试 单元测试
以一个加法函数为例#xff0c;对其进行单元测试。
首先编写add.go文件#xff1a;
//add.go
package mainfunc add(a, b int) int {return a b
}其次编写add_test.go文件#xff0c;在go语言中#xff0c;测试文件均已_test结尾对其进行单元测试。
首先编写add.go文件
//add.go
package mainfunc add(a, b int) int {return a b
}其次编写add_test.go文件在go语言中测试文件均已_test结尾这里只需要在被测试的文件后加上_test即可。并且测试文件与要被测试的文件需要放在同一个包中并不像Java那样需要将所有的测试文件放在一个专门的测试文件夹里面例如我将这两个文件都放在main包下
package mainimport (fmttesting
)//测试函数需要以Test开头
func TestAdd(t *testing.T) {fmt.Println(Running short test)res : add(1, 2)if res ! 3 {t.Errorf(add(1,2) should be 3, got %d, res)}
}cd到测试文件的目录执行测试命令go test
以下是运行结果
(base) PS F:\GolandProjects\GoProject1\main go test
Running short test
PASS
ok GoProject1/main 0.489s如果想在测试中跳过那些需要耗时比较长的测试可以做以下处理
package mainimport (fmttesting
)func TestAdd(t *testing.T) {fmt.Println(Running short test)res : add(1, 2)if res ! 3 {t.Errorf(add(1,2) should be 3, got %d, res)}
}func TestAdd2(t *testing.T) {if testing.Short() {fmt.Println(Skipping long test)//短测试模式就跳过该测试t.Skip(Skipping long test)}fmt.Println(Running long test)res : add(5, 6)if res ! 11 {t.Errorf(add(5,6) should be 11, got %d, res)}
}在运行时指执行短测试只需要执行go test -short
(base) PS F:\GolandProjects\GoProject1\main go test -short
Running short test
Skipping long test
PASS
ok GoProject1/main 0.448s我们发现跳过了第二个测试也就是测试函数TestAdd2。
当然如果还是执行go test命令则两个测试都将会运行
(base) PS F:\GolandProjects\GoProject1\main go test
Running short test
Running long test
PASS
ok GoProject1/main 0.417s如果想要同时测试很多条数据可以按如下的方式处理而不需要写很多的函数
func TestAdd3(t *testing.T) {var dataset []struct {a, b, expected int}{{1, 2, 3},{5, 6, 11},{10, 20, 30},{100, 200, 300},}for _, d : range dataset {res : add(d.a, d.b)if res ! d.expected {t.Errorf(add(%d,%d) should be %d, got %d, d.a, d.b, d.expected, res)}}
}这里我们用go test -v测试一下
(base) PS F:\GolandProjects\GoProject1\main go test -vRUN TestAdd
Running short test
--- PASS: TestAdd (0.00s)RUN TestAdd2
Running long test
--- PASS: TestAdd2 (0.00s)RUN TestAdd3
--- PASS: TestAdd3 (0.00s)
PASS
ok GoProject1/main 0.408sgo test 用于运行测试并显示简洁的结果而 go test -v 用于以详细模式运行测试并提供更多的输出信息有助于更深入地了解测试的运行情况。通常在开发和调试过程中使用 -v 标志是很有帮助的但在持续集成和自动化测试中可能更倾向于使用简洁的 go test以便更容易解释测试结果。
基准测试
性能表现需要实际数据衡量Go语言提供了支持基准性能测试的benchmark工具。基准测试用于确定一段代码的执行速度和性能并可以用来优化和改进代码。
以编写斐波那契函数为例
//fib.go
package mainfunc Fib(n int) int {if n 2 {return n}return Fib(n-1) Fib(n-2)
}//fib_test.go
package mainimport (testing
)func BenchmarkFib10(b *testing.B) {for i : 0; i b.N; i {Fib(10)}
}benchmark 和普通的单元测试用例一样都位于 _test.go 文件中。 函数名以 Benchmark 开头参数是 b *testing.B。和普通的单元测试用例很像单元测试函数名以 Test 开头参数是t *testing.T。使用 b.N 控制循环次数b.N 是基准测试的循环次数它会根据不同的运行情况自动调整以保证结果的可比性。
运行当前 package 内的用例go test .运行子 package 内的用例 go test ./package name如果想递归测试当前目录下的所有的 packagego test ./...
go test 命令默认不运行 benchmark 用例的如果我们想运行 benchmark 用例需要加上 -bench 参数。例如
$ go test -bench .
goos: windows
goarch: amd64
pkg: GoProject1
cpu: 11th Gen Intel(R) Core(TM) i7-11800H 2.30GHz
BenchmarkFib10-16 5496252 212.5 ns/op
PASS
ok GoProject1 1.454sgoos: windows这行显示运行基准测试的操作系统此处为 Windows。goarch: amd64这行显示运行基准测试的机器架构此处为 64 位 AMD 架构。pkg: GoProject1这行显示包含基准测试代码的包名此处为 “GoProject1”。cpu: 11th Gen Intel(R) Core(TM) i7-11800H 2.30GHz这行显示运行基准测试的机器 CPU 信息包括 CPU 型号和时钟频率。PASS这行表示所有的测试包括基准测试都已成功通过。ok GoProject1 1.454s这行显示所有测试包括基准测试的整体执行时间。在这种情况下整个测试套件执行时间大约为 1.454 秒。BenchmarkFib10-16 是测试函数名-16表示GOMAXPROCS的值为16GOMAXPROCS 1.5版本后默认值为CPU核数 。5496252 表示一共执行5496252 次即b.N的值。212.5 ns/op表示每次执行花费212.5ns。
再举一个比较详细的例子比较不同字符串处理方式的性能
func Plus(n int, str string) string {s : for i : 0; i n; i {s str}return s
}func StrBuilder(n int, str string) string {var builder strings.Builderfor i : 0; i n; i {builder.WriteString(str)}return builder.String()
}func ByteBuffer(n int, str string) string {buf : new(bytes.Buffer)for i : 0; i n; i {buf.WriteString(str)}return buf.String()
}func PreStrBuilder(n int, str string) string {var builder strings.Builderbuilder.Grow(n * len(str))for i : 0; i n; i {builder.WriteString(str)}return builder.String()
}
func PreStrByteBuffer(n int, str string) string {buf : new(bytes.Buffer)buf.Grow(n * len(str))for i : 0; i n; i {buf.WriteString(str)}return buf.String()
}基准测试函数
func BenchmarkPlus(b *testing.B) {for i : 0; i b.N; i {Plus(100000, wxy)}
}func BenchmarkStrBuilder(b *testing.B) {for i : 0; i b.N; i {StrBuilder(100000, wxy)}
}func BenchmarkByteBuffer(b *testing.B) {for i : 0; i b.N; i {ByteBuffer(100000, wxy)}
}func BenchmarkPreStrBuilder(b *testing.B) {for i : 0; i b.N; i {PreStrBuilder(100000, wxy)}
}func BenchmarkPreByteBuffer(b *testing.B) {for i : 0; i b.N; i {PreStrByteBuffer(100000, wxy)}
}以下是运行结果
$ go test -bench .
goos: windows
goarch: amd64
pkg: GoProject1
cpu: 11th Gen Intel(R) Core(TM) i7-11800H 2.30GHz
BenchmarkPlus-16 1 1126084200 ns/op
BenchmarkStrBuilder-16 3982 284773 ns/op
BenchmarkByteBuffer-16 2947 485091 ns/op
BenchmarkPreStrBuilder-16 4771 278961 ns/op
BenchmarkPreByteBuffer-16 3310 364676 ns/op
PASS
ok GoProject1 6.457s使用拼接性能最差strings.Builderbytes.Buffer相近strings.Builder更快字符串在Go语言中是不可变类型占用内存大小是固定的使用每次都会重新分配内存strings.Builder bytes.Buffer底层都是[]byte数组。内存扩容策略不需要每次拼接重新分配内存预分配内存后strings.Builder bytes.Buffer性能都有所提升