Dive into go language-12 Tests, performance tests, and code sample writing

Source: Internet
Author: User
Tags benchmark sprintf
This is a creation in Article, where the information may have evolved or changed.

Catalogue [−]

    1. Test
    2. Test comparison Tool
    3. TDT (Table driven Tests)
    4. Test coverage
    5. Performance testing
    6. 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 .

packagescan 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 packageswill give a detailed introduction.

build flagContains 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 -vIt 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
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.