This is a creation in Article, where the information may have evolved or changed.
"Nanpi County Chi, the song of the Terroir": "The horses do not move, fodder first". In combat, the soldiers have not been dispatched, the transport of military fodder to advance one step. Before developing a new feature, write the test code, and then write only the function code that makes the test pass, a test-driven development model that I highly recommend.
The contribution of the DIT requires a unit test, and any module that writes the DIT needs to be written in conjunction with the test case. This article first describes the go to the test support, follow-up will continue to provide the Dit test plan and test report.
Go to test support
Go comes with a test framework testing support for unit testing and performance testing. Go prescribes the test file as _test.go
a suffix and go test
runs the test case automatically using command commands.
Unit Test
Take Test
the first method as a test case and have a parameter with the *testing.T
following syntax:
func TestXxx(*testing.T)
Xxx
The part is any combination of alphanumeric characters, and the first letter cannot be a lowercase letter. *testing.T
you can log errors or flag error states. You can skip a part of the test by short and speed up the test time. As follows:
func TestTimeConsuming(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } ...}
Performance testing
The performance test case Benchmark
begins with the parameter as *testing.B
follows:
func BenchmarkXxx(*testing.B)
go test
When you use Run performance test cases, you need to add parameters -bench
.
When writing performance test cases, keep in mind that you use them in the loop body testing.B.N
to make the tests work properly:
func BenchmarkHello(b *testing.B) { for i := 0; i < b.N; i++ { fmt.Sprintf("hello") }}
For time-consuming initialization operations, you can reset the timer inside the test case ResetTimer
to ensure that unnecessary errors are introduced:
func BenchmarkBigLen(b *testing.B) { big := NewBig() b.ResetTimer() for i := 0; i < b.N; i++ { big.Len() }}
Using RunParallel
the test parallel module, the runtime needs to add parameters -cpu
:
func BenchmarkTemplateParallel(b *testing.B) { templ := template.Must(template.New("test").Parse("Hello, {{.}}!")) b.RunParallel(func(pb *testing.PB) { var buf bytes.Buffer for pb.Next() { buf.Reset() templ.Execute(&buf, "World") } })}
Standard output Test
The testing package provides a test of the standard terminal output, the test case to begin with, and the Example
result is written in the form of a comment Output:
:
func ExampleHello() { fmt.Println("hello") // Output: hello}
Example naming conventions for use cases:
func Example() { ... }func ExampleF() { ... } // F - functionfunc ExampleT() { ... } // T - typefunc ExampleT_M() { ... } // T_M - method M on type T// 多个 example 可用后缀区分,The suffix must start with a lower-case letter.func Example_suffix() { ... }func ExampleF_suffix() { ... }func ExampleT_suffix() { ... }func ExampleT_M_suffix() { ... }
Main Test
When you need a batch setup or teardown test environment, you can use:
func TestMain(m *testing.M)
Testmain simple implementation is as follows:
func TestMain(m *testing.M) { flag.Parse() os.Exit(m.Run())}
Demo
Write a simple example to Demo the use of the testing test framework.
Div.gopackage testimport ("errors") func div (A, b int) (int, error) {if b = = 0 {return 0, errors. New ("B must not being 0")} return a/b, nil}//div_test.gopackage testimport ("Errors" "Flag" "FMT" "OS" "Testing" "Time") func Testdivnormal (t *testing. T) {ret, err: = div (6, 2) if err! = Nil | | Ret! = 3 {t.error ("6/2=3")}}func Testdivzero (t *testing. T) {_, Err: = div (6, 0) if Err. Error ()! = errors. New ("B must not being 0"). Error () {t.error ("zero div Error")}}func Benchmarkdiv (b *testing. B) {B.Log ("Run Times:", B.N) for I: = 0; i < B.N; i++ {div (6, 2)}}func Benchmarkdiv_sleep (b *testing. B) {B.Log ("Run Times:", B.N) time. Sleep (3000)//analog time-consuming operation B.resettimer () for I: = 0; i < B.N; i++ {div (6, 2)}}func Exampleoutput () {ret, _: = div (6, 2) fmt. Println ("6/2 =", ret)//Output://6/2 = 3}func testmain (M *testing. M) {flag. Parse () fmt. Println ("Setup ... Done ") RET: = M.run () fmt. Println ("Teardown ... Done ") OS. Exit (ret)}
Run go test -v
with the following results:
localhost:test zdd$ go test -vSetup ... Done=== RUN TestDivNormal--- PASS: TestDivNormal (0.00s)=== RUN TestDivZero--- PASS: TestDivZero (0.00s)=== RUN: ExampleOutput--- PASS: ExampleOutput (0.00s)PASSTeardown ... Doneok github.com/zddhub/hellogo/test 0.005s
By default, performance test cases are not performed, using go test -v -bench .
execution:
localhost:test zdd$ go test -v -bench .Setup ... Done=== RUN TestDivNormal--- PASS: TestDivNormal (0.00s)=== RUN TestDivZero--- PASS: TestDivZero (0.00s)=== RUN: ExampleOutput--- PASS: ExampleOutput (0.00s)PASSBenchmarkDiv 100000000 16.2 ns/op--- BENCH: BenchmarkDiv div_test.go:27: run times: 1 div_test.go:27: run times: 100 div_test.go:27: run times: 10000 div_test.go:27: run times: 1000000 div_test.go:27: run times: 100000000BenchmarkDiv_Sleep 100000000 16.4 ns/op--- BENCH: BenchmarkDiv_Sleep div_test.go:34: run times: 1 div_test.go:34: run times: 100 div_test.go:34: run times: 10000 div_test.go:34: run times: 1000000 div_test.go:34: run times: 100000000Teardown ... Doneok github.com/zddhub/hellogo/test 3.305s
Zddhub produced by Wood B-word
Number: Zddnotes
Just for fun!
Article only write to yourself, if you also like, Welcome to scan the following two-dimensional code attention OH ~