Go test test & Benchmark

Source: Internet
Author: User
Tags benchmark how to write test cases
This is a creation in Article, where the information may have evolved or changed.

The important point of the development program is the test, how we guarantee the quality of the code, how to ensure that each function is operational, the result is correct, and how to ensure that the written code performance is good, we know that the focus of unit testing is to find the design or implementation of logic errors, so that the problem early exposure, Easy to solve the problem, and the focus of performance testing is to find some programming problems, so that the online program can be high concurrency in the case can remain stable. This section will take this series of questions to explain how to implement unit and performance testing in the Go language.

The go language comes with a lightweight test framework testing and comes with go test commands to implement unit testing and performance testing, testing and frameworks are similar to test frameworks in other languages, where you can write test cases for corresponding functions based on the framework, or you can write the appropriate stress test cases based on the framework. Then let's hit to see how to write.

How to write test cases

Since the go test command can only execute all the files in one of the corresponding directories, we will create a new project directory so that gotest all of our code and test code are in this directory.

Next we create two files under this directory: Gotest.go and Gotest_test.go

  1. Gotest.go: In this file we create a package with a function that divides the operation:

    Package Gotestimport (    "errors") Func division (A, B float64) (float64, error) {    if b = = 0 {        return 0, errors. New ("Divisor cannot be 0")    }    return a/b, nil}
  2. Gotest_test.go: This is our unit test file, but keep in mind the following principles:

      • The file name must be _test.go at the end so that it executes go test to the appropriate code at execution time
      • You have to import testing this bag.
      • All test case functions must be at the Test beginning
      • The tests are executed in the order in which they were written in the source code.
      • The parameter of the test function TestXxx() is testing.T that we can use that type to log an error or test state
      • Test format: func TestXxx (t *testing.T) , Xxx part can be any combination of alphanumeric, but the first letter can not be lowercase letters [a-z], such as the Testintdiv wrong function name.
      • The function in the call,,, testing.T Error Errorf FailNow Fatal FatalIf method, means that the test does not pass, and the calling Log method is used to record the test information.

    Here is the code for our test case:

    Package Gotestimport (    "testing") Func test_division_1 (t *testing. T) {    If I, E: = Division (6, 2); I! = 3 | | E! = NIL {//try A unit test on function        t.error ("Division function test Failed")//if not as expected Error    } else {        t.Log ("first Test Passed")//record some information you expect to record    }}func test_division_2 (t *testing. T) {    t.error ("Just Don't Pass")}

    When we execute under the project directory go test , the following information is displayed:

    ---fail:test_division_2 (0.00 seconds)    Gotest_test.go:16: is not through Failexit status 1FAIL    gotest  0.013s

    From this the result shows that the test did not pass, because in the second Test function we wrote dead The test does not pass the code t.Error , then our first function to execute the situation? By default, execution go test does not show the information passed by the test, and we need to bring the parameters so that the go test -v following information is displayed:

    = = = Run test_division_1---pass:test_division_1 (0.00 seconds)    Gotest_test.go:11: The first Test passed the = = = Run Test_division_2 ---fail:test_division_2 (0.00 seconds)    Gotest_test.go:16: is not through Failexit status 1FAIL    gotest  0.012s

    The above output shows the process of the test in detail, we see the test function 1 Test_Division_1 test pass, and the test function 2 Test_Division_2 test failed, and finally concluded that the test does not pass. Next we change the test function 2 to the following code:

    Func test_division_2 (t *testing. T) {    If _, E: = Division (6, 0), E = = Nil {//try A unit test on function        t.error ("Division do not work as Expecte D. ") If not as expected then error    } else {        t.Log ("one Test passed.", e)//record some information you wish to record    }}   

    Then we execute go test -v , the following information is displayed, the test passed:

    = = = Run test_division_1---pass:test_division_1 (0.00 seconds)    Gotest_test.go:11: The first Test passed the = = = Run test_division_2- --Pass:test_division_2 (0.00 seconds)    Gotest_test.go:20:one Test passed. Divisor cannot be 0PASSok      gotest  0.013s

How to write a stress test

Stress tests are used to detect the performance of functions (methods), similar to the method of writing unit functional tests, which are not mentioned here, but note the following points:

    • The stress test case must follow the following format, where xxx can be a combination of any alphanumeric, but the first letter cannot be a lowercase letter

      Func benchmarkxxx (b *testing. B) {...}
    • go testThe function of the stress test will not be performed by default, if the stress test is to be performed with parameters -test.bench , syntax: -test.bench="test_name_regex" For example, to go test -test.bench=".*" test all of the stress test functions

    • In the stress test case, remember to use in the loop body so that the testing.B.N test can run normally
    • The file name must also _test.go end With

Here we create a new stress test file, Webbench_test.go, as shown below:

Package Gotestimport (    "testing") func benchmark_division (b *testing. B) {    for I: = 0; i < B.N; i++ {//use B.N for looping         Division (4, 5)    }}func Benchmark_timeconsumingfunctio N (b *testing. B) {    b.stoptimer ()//Call this function to stop the time count of the stress test    //Do some initialization work, such as reading file data, database connection and    so on,//so that these times do not affect the performance    of our test function itself B.starttimer ()//Restart time for    I: = 0; i < B.N; i++ {        Division (4, 5)}    }

We execute go test -test.bench=".*" the command and see the following results:

Passbenchmark_division  500000000            7.76 ns/opbenchmark_timeconsumingfunction 500000000            7.80 Ns/opok      gotest  9.364s  

The above results show that we did not perform any TestXXX unit test functions, the results show only the pressure test function, the first shows the Benchmark_Division execution of 500 million times, the average time of execution is 7.76 nanoseconds, the second shows that the Benchmark_TimeConsumingFunction execution of 500000000, The average execution time per time is 7.80 nanoseconds. The last bar shows the total execution time.

As we execute go test -test.bench=".*" -count=5 the command, we can see the following result: (use-count to specify how many times to execute)

passbenchmark_division-2                 300000000             4.60ns/opbenchmark_division-2                 300000000             4.57ns/opbenchmark_division-2                 300000000             4.63ns/opbenchmark_division-2                 300000000             4.60ns/opbenchmark_division-2                 300000000             4.63ns/opbenchmark_timeconsumingfunction-2    300000000             4.64ns/opbenchmark_timeconsumingfunction-2    300000000             4.61ns/opbenchmark_timeconsumingfunction-2    300000000             4.60ns/opbenchmark_timeconsumingfunction-2    300000000             4.59ns/opbenchmark_timeconsumingfunction-2    300000000             4.60ns/Opok _/home/diego/gowork/src/app/testing -.546s

go test -run=文件名字 -bench=bench名字 -cpuprofile=生产的cprofile文件名称 文件夹

Example:

There is a popcnt folder under Testbenchmark, and there are files in popcnt popcunt_test.go

➜  Testbenchmark lspopcnt

Popcunt_test.go's Asking price content:

ackage Popcntimport ("Testing")ConstM1 =0x5555555555555555ConstM2 =0x3333333333333333ConstM4 =0x0f0f0f0f0f0f0f0fConstH01 =0x0101010101010101func popcnt (x UInt64) UInt64 {x-= (x >>1) &M1 x= (x & m2) + ((x >>2) &m2) x= (x + (x >>4)) &M4return(x * h01) >> About}func benchmarkpopcnt (b*testing. B) { forI: =0; i < B.N; i++{x:=I x-= (x >>1) &M1 x= (x & m2) + ((x >>2) &m2) x= (x + (x >>4)) &M4 _= (x * h01) >> About    }}

Then run go test-bench= ". *"-cpuprofile=cpu.profile./popcnt

➜testbenchmark Go test-bench=".*"-cpuprofile=cpu.profile./popcnttesting:warning:no tests to runpassbenchmarkpopcnt-8    1000000000             2.01ns/Opok App/testbenchmark/popcnt2. 219s➜testbenchmark lltotal6704drwxr-xr-x5Diego Staff the  5  6  -: $. DRWXR-xr-x3Diego Staff102  5  6  One: A ..-rw-r--r--1Diego Staff5200  5  6  -: $CPU.PROFILEDRWXR-xr-x4Diego Staff136  5  6  One: -popcnt-rwxr-xr-x1Diego Staff3424176  5  6  -: $Popcnt.test➜testbenchmark

Production Cpu.profile asking price and Popcnt.test file

➜testbenchmark lltotal6704drwxr-xr-x5Diego Staff the  5  6  -: $. DRWXR-xr-x3Diego Staff102  5  6  One: A ..-rw-r--r--1Diego Staff5200  5  6  -: $CPU.PROFILEDRWXR-xr-x3Diego Staff102  5  6  -: onpopcnt-rwxr-xr-x1Diego Staff3424176  5  6  -: $Popcnt.test➜testbenchmark
Go tool pprof popcnt.test cpu.profile Enter interactive mode
➜testbenchmark Go tool pprof popcnt.test cpu.profileentering interactive mode (type" Help"  forcommands) (pprof) Top1880ms of 1880ms Total ( -%) Flat Flat% sum% cum cum%1790ms95.21%95.21% 1790ms95.21% app/testbenchmark/popcnt. benchmarkpopcnt 90ms4.79% -% 90ms4.79%Runtime.usleep0     0% -% 1790ms95.21%Runtime.goexit0     0% -% 90ms4.79%Runtime.mstart0     0% -% 90ms4.79%Runtime.mstart10     0% -% 90ms4.79%Runtime.sysmon0     0% -% 1790ms95.21% testing. (*B). Launch0     0% -% 1790ms95.21% testing. (*B). Runn (pprof)

Go tool pprof--web popcnt.test cpu.profile into Web mode

$ go tool pprof --text mybin http://myserver:6060:/debug/pprof/profile

There are several output types available, the most useful being the following:--text,--web and--list. Run go tool pprof to get the most complete list.

Summary

By learning about unit tests and stress tests, we can see that the testing package is lightweight, that writing unit tests and stress test cases is very simple, and that it is easy to test with the built-in go test commands so that every time we modify the code, we execute the Go Test can simply complete the regression test.

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.