This is a creation in Article, where the information may have evolved or changed.
Catalogue [−]
- Test
- Test comparison Tool
- TDT (Table driven Tests)
- Test coverage
- Performance testing
- Example
This chapter describes the code tests, performance tests, and examples of the go language.
Test
While there are some third-party test libraries based on some kind of concept development, I think it's best to use the official test library: testing.
Conventionally, we will place the test code file and the official code file in the same folder, but the file containing the test code should end with "_test.go".
The package name of the test file can be the same as the package name of the official file, or it can be different. For example, the formal registration is abc
, the test registration can be abc_test
, but cannot be other, for example xyz
.
Both of these styles are available in the official library. In general and formal package name, we can carry out white box test, can directly call the package under the non-export method, the package name is different, black box test. According to the book "The Go Programming language", this scheme can also avoid the problem of cyclic dependence.
The file name of the test cannot be underlined or .
started, and these files will not be go test
included.
The method name of the test has a special definition, beginning with "Test", and the parameters are *testing.T
:
1 |
func Testxxx (*testing. T |
XXX can be any alphanumeric string, but the first letter x cannot be a [a-z] character, Testxyz
it is not a test function, but it Test123
is.
Many languages, such as JUnit in Java, testng provide assertion
auxiliary functions, can easily determine whether the test results and expected results are consistent, but go official did not provide, and is intentional, that is to avoid the programmer to make lazy. There are local libraries that provide the appropriate functionality, such as Testify/assert.
If the test results are not what you expect, you can call Fail
, and so on, to trigger the Error
failed signal.
The test file is excluded from normal compilation, but is go test
included when the test is called.
The Skip
method can be passed down to test:
123456 |
func Testtimeconsuming (t *testing. T) { if testing. Short () { T.skip ("skipping test in short mode.") } ...} |
The complete test command is as follows:
go test [build/test flags] [packages] [build/test flags & test binary flags]
It compiles and tests all the source files under the package without any parameters.
In addition build flag
, test will handle several additional compiler flags:,,, -args
-c
-exec xprog
-i
, -o file
.
packages
can be an absolute path, relative path (. Or ...) Or just a package name (go will look for dir/src/p in the list of Gopath environment variables, assuming dir is in the list of files defined by the environment variable, P is the package name). ...
you can blur matching strings, such as x/...
subfolders that match x and X. go help packages
will give a detailed introduction.
build flag
Contains a lot of flag, generally we will not add these flag, if you want to understand, you can look at the official documents.
The official document description of testing flags describes all the test flags, and we pick a few common ones to look at.
-bench regexp
: A performance test that supports the filtering of a test function by an expression. -bench .
is for all the benchmark function tests
-benchmem
: Performance test displays statistics of memory allocations for test functions
-count n
: Run tests and performance how much this, default once
-run regexp
: Run only specific test functions, such as test functions -run ABC
with ABC in the function name only
-timeout t
: Test time if more than T, panic, default 10 minutes
-v
: Displays the details of the test and displays the Log
log of the Logf
method.
go test -v -args -x -v
It compiles and executes the program: pkg.test -test.v -x -v
so you can easily understand the meaning of the args parameter.
Go 1.7 begins to support the concept of sub-test.
Reference
- https://golang.org/pkg/testing/
- Https://golang.org/doc/code.html#Testing
- https://golang.org/cmd/go/#hdr-test_packages
- Https://github.com/shageman/gotestit
Test comparison Tool
Performance testing is critical, and you often ask "A faster or B faster" and, of course, to speak on performance data. Of course performance testing is not a simple thing, I also saw this morning Chenhao wrote a critical Dubbo test article: How should the performance test do? Fortunately go provides an easy way to write performance tests, but how do you compare performance among multiple candidates?
One way is to write multiple test functions, each of which tests only one candidate, and then see the results of the test, such as the performance test I wrote for the Go Serialization framework: Gosercomp.
The first tool introduced in this sectionto is benchcmp, which can compare performance improvements or declines between two versions. For example, your code base's performance changes after the go 1.6.2 and go 1.7 compilations:
123 |
Go test-run=none-bench=. ./... > Old.txt # makechangesgo test-run=none-bench=. ./... > New.txt |
Then use this tool to compare:
123456789 |
newtxtbenchmark old ns/op new ns/op deltabenchmarkconcat 523 68.6 -86.88%benchmark old allocs new allocs deltabenchmarkconcat 3 1 -66.67%benchmark old bytes new bytes Deltabenchmarkconcat -40.00 |
The second tool is prettybench, which can beautify the test report of Go own performance, better read:
Passbenchmark iter time/iter---------------- ------benchmarkcssescaper 1000000 2843 ns/opbenchmarkcssescapernospecials 5000000 6 Ns/opbenchmarkdecodecss 1000000 1183 Ns/opbenchmarkdecodecssnospecials 50000000 Ns/opbenchmarkcssvaluefilter 5000000 501 Ns/opbenchmarkcssvaluefilterok 5000000 707 Ns/opbenchmarkescapedexecute 500000 6191 ns/opbenchmarkhtmlnospaceescaper 100000 0 2523 ns/opbenchmarkhtmlnospaceescapernospecials 5000000 596 ns/opbenchmarkstriptags 1000 2351 ns/opbenchmarkstriptagsnospecials 10000000 260 ns/opbenchmarkjsvalescaperwithnum 10 00000 1123 ns/opbenchmarkjsvalescaperwithstr 500000 4882 ns/opbenchmarkjsvalescaperwithstrnospecials 1000000 1461 Ns/opbencHmarkjsvalescaperwithobj 500000 5052 ns/opbenchmarkjsvalescaperwithobjnospecials 1000000 1897 ns/opBe Nchmarkjsstrescapernospecials 5000000 608 ns/opbenchmarkjsstrescaper 1000000 2633 ns/op Benchmarkjsregexpescapernospecials 5000000 661 Ns/opbenchmarkjsregexpescaper 1000000 2510 ns/ Opbenchmarkurlescaper 500000 4424 ns/opbenchmarkurlescapernospecials 5000000 422 n S/opbenchmarkurlnormalizer 500000 3068 ns/opbenchmarkurlnormalizernospecials 5000000 431 Ns/opok html/template 62.874s
The third tool to introduce is Benchviz, which uses the results of BENCHCMP, but can graphically display performance improvements:
Benchstat This tool can summarize the results of multiple tests and generate profile information.
Reference:
- http://dominik.honnef.co/posts/2014/12/an_incomplete_list_of_go_tools/
TDT (Table driven Tests)
The TDT is also called a table-driven method, sometimes classified as a keyword-driven test (Keyword-driven testing, a software testing method for automated testing, which divides the steps of creating a test program into two stages of planning and implementation.
Some tests in the Go official library Use this test method.
Each table item in the TDT is a complete test case that contains the input and expected output, and sometimes adds additional information such as the test name. If you find that your tests are often copy/paste, you can consider transforming them into TDT.
The test code is one piece, but you can test each item in the table.
Here is an example:
123456789101112131415161718192021222324252627 |
varFlagtests = []struct{instringOutstring}{ {"%a","[%a]"}, {"%-a","[%-a]"}, {"%+a","[%+a]"}, {"% #a","[% #a]"}, {"% a","[% a]"}, {"%0a","[%0a]"}, {"%1.2a","[%1.2a]"}, {"%-1.2a","[%-1.2a]"}, {"%+1.2a","[%+1.2a]"}, {"%-+1.2a","[%+-1.2a]"}, {"%-+1.2ABC","[%+-1.2A]BC]}, {"%-1.2ABC","[%-1.2A]BC]},}funcTestflagparser (t *testing. T) {varFlagprinter Flagprinter for_, TT: =Rangeflagtests {s: = Sprintf (tt.in, &flagprinter)ifs! = tt.out {T.errorf ("Sprintf (%q, &flagprinter) =%q, want%q", tt.in, S, Tt.out)}} |
Reference
- Https://github.com/golang/go/wiki/TableDrivenTests
- Http://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go
Test coverage
Starting with Go 1.2, GO provides a tool for generating code coverage cover
.
Code coverage describes how many of the statements in the package are covered by the test.
such as code:
1234567891011121314151617 |
PackageSizefuncSize (Aint)string{Switch{ CaseA <0:return "negative" CaseA = =0:return "Zero" CaseA <Ten:return "Small" CaseA < -:return "Big" CaseA < +:return "huge"}return "enormous"} |
Test code:
12345678910111213141516171819202122 |
package sizeimport "testing" type Test struct {in int
out string }var tests = []test{{-1 , }, {5 , },}func testsize (t *testing. T) {for i, Test: = range tests {size: = Size (test.in ) if size! = test.out {T.errorf ( "#%d:size (%d) =%s; Want%s ", I, test.in, size, Test.out)}}} |
To view Code coverage:
12345 |
42.9% of Statementsok size 0.026s% |
To see detailed coverage, you can generate a coverage profile
file:
12345 |
42.9% of Statementsok size 0.030s% |
To generate an HTML test report:
1 |
$ go Tool cover-html=coverage.out |
Some websites can help you test generated code coverage, and you can also write your project's badge in a readme file, such as Gocover, Coveralls
Reference
- Https://blog.golang.org/cover
Performance testing
The performance test is written in a similar notation to the unit test, but the "Benchmark" instead of "test" is used as the beginning of the function, and the parameter of the function is changed to *testing.B
:
1 |
func Benchmarkxxx (*testing. B |
Test, plus you -bench
can perform performance tests, such as go test -bench .
.
A simple performance test code is as follows:
12345 |
func Benchmarkhello (b *testing. B) {for i: = 0; i < B.N; i++ { fmt. Sprintf ("Hello") }} |
The test code executes b.N
once, but N
adjusts to the performance of your code, the code executes faster, n is larger, the code is slow, and n is smaller.
The test results are as follows, 10 million tests were performed, and each test took 282 nanoseconds:
1 |
Benchmarkhello 10000000 282 Ns/op |
If you need to prepare some long-time work before the test, you can invoke ResetTimer
the time when the specified test begins:
1234567 |
func Benchmarkbiglen (b *testing. B) { big: = Newbig () B.resettimer () for i: = 0; i < B.N; i++ { big. Len () }} |
If you need to perform tests in parallel, you can add parameters to the test, -cpu
and you can execute the RunParallel
helper methods:
12345678910 |
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 () "World") } )} |
Example
A code sample function is like a test function, but it does not use a *testing.T
parameter to report an error or failure, but instead outputs the output to the OS. Stdout and OS. Stderr.
The output is compared to the results in the comments within the function, which is Output:
at the bottom of the function body. If there is no ' Output: Comment, or there is no text behind it, the code compiles only and does not execute.
Godoc can display EXAMPLEXXX implementation code to demonstrate the use of function xxx or constant XXX or variable XXX. If receiver is a T or *t method M, its example code should be named Examplet_m. If a function, constant, or variable can have more than the method name of the sample code suffix _xxx, the first character of XXX cannot be capitalized.
As an example:
1234567891011 |
Package ch11import"FMT"func Exampleadd () {k: = Add(1, 2) fmt. Println (k)//Output://3} |
I believe you have seen a lot of such examples in Godoc, you should also provide a corresponding example for your library, so that others can easily familiarize yourself with your code.
You can use to go help testfunc
view detailed instructions.
The file names of the sample code are generally used example_test.go
because they are also test functions, so the file name ends with "_test.go".
Run the test code: go test -v
You can see that the sample function has also been tested.
If we change the comment in the previous // 3
example // 2
to run, we go test -v
see an error because the execution results are inconsistent with our output.
12345678910111213 |
Smallnestmbp:ch11 smallnest$ go test-v=== run Test123---pass:test123 (0.00s) = = = Run exampleadd--- Fail:exampleadd (0.00s) got:3want:2FAILexit1failgithub.com/ Smallnest/dive-into-go/ch110.005ssmallnestmbp:ch11 smallnest$ |
Sometimes we may want to write an example for a set of functions, and we need one at a time, whole file example
one that whole file example
ends with "_test.go", contains only one example function, no test function or performance test function, at least one other package-level declaration, The following example is a complete file:
123456789101112131415161718 |
BOOL return A[i]. Age < A[j]. Age}func Example () { people: = []person{ {"Bob", +}, {"John", {"Michael", +}, {"Jenny", +}, } FMT. Println (people) sort. Sort (Byage (people)) FMT. Println (People) //Output: //[bob:31 john:42 michael:17 jenny:26] //[ Michael:17 jenny:26 bob:31 john:42]} |
Reference
- https://blog.golang.org/examples