In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)06/03 Report--
The first part: how to write Go language unit test
The Go language has a built-in Unit Test framework. This is to standardize the way UT is written at the language level.
The naming convention of the Go language treats go files that end in _ test.go as unit test code.
When we build executables with go build, these _ test.go files are excluded from the build scope.
When we use go test for unit testing, these _ test.go files participate in the build and provide a default TestMain function as the starting entry for UT.
Next, let's look at how to write unit tests for the Go language through an example.
An example
First, let's look at a piece of code like this:
The package db//db package implements a DB structure to encapsulate the access to a database import ("someDB" / / someDB provides functions such as / / insert/get/delete to the actual database). The internal details of the type DB struct {/ / DB structure ignore.} / / DB structure provides Put/Get/Delete// three methods, the specific implementation of slightly func (d * DB) Put (key, value string) error {. SomeDB.insert (...)} func (d * DB) Get (key string) (string, error) {. Return someDB.get (...)} func (d * DB) Delete (key string) error {... SomeDB.delete (...).}
You can see from the above code that we have implemented a DB structure in db.go to abstract access to a database.
Now, to write UT for DB, we usually put the test code in db_test.go.
Although the Go language itself does not require one-to-one correspondence of file names, this established naming convention can give us better readability.
The use case of package db//UT must be in the same package as the code import ("testing" / / testing package provides test functions / / data structures that must be used.) / / We will write a test function for each / / method of the DB structure / / first list the signatures of each test function / / the specific implementation will be followed by func TestPut (t * testing.T) {...} func TestGet (t * testing.T) {.} func TestDelete (t * testing.T) {.}
In order for the Go language testing framework to automatically discover all our test cases
The signature of the test function should also follow its specific rules:
The function name must start with Test, usually followed by the function name of the method to be tested
The parameter must be * testing.T, which provides methods such as Error,Fatal to report an error and terminate the test.
These test cases are executed concurrently within the test framework, and the degree of concurrency is specified by the-parallel parameter at go test.
Specific UT implementation
TestPut
Func TestPut (t * testing.T) {/ / in order to test, we first need to create / / an instance of the DB structure with a few parameters d: = NewDB (...) / / We call the method to be tested Put / / write some data to the database err: = d.Put ("testputkey", "value") / / We must check the returned error Be sure to return nil if err! = nil {/ / use Error to print the error message t.Error (err)} / / next we use someDB's get interface / / to get the data Here, try to / / avoid using the DB.Get method to be tested / / see value below, _: = someDB.get (...) / / check the data if value! = "value" {t.Error ("some msg")}}
It is not recommended to use Get, another method to be tested, when obtaining data, so as to avoid test contamination.
The so-called test contamination refers to the failure caused by the non-test function, for example, the function to be tested in TestPut is DB.Put, if we use the DB.Get method to obtain data, then the test case will fail if DB.Get goes wrong, and we need additional information to determine whether there is something wrong with Put or Get. The someDB.get method has been tested in the someDB package and is generally considered credible.
We will see similar processing in later test cases.
TestGet
Func TestGet (t * testing.T) {d: = NewDB (...) / / first test the key that does not exist in Get / / let the parameter name explain itself as much as possible, err: = d.Get ("testgetnonexist") if err! = ErrNotFound {t.Error ("some msg")} / / use someDB's insert interface / / to write some test data err = someDB.insert (...) If err! = nil {t.Fatal ("some msg")} / / then call the test method Get to read the data value, err: = d.Get ("testgetkey") if err! = nil {t.Error ("some msg")} / / verify the data if value! = "value" {t.Error ("some msg")}}
The difference between Fatal and Error is that Fatal terminates the current use case and continues to run immediately after reporting an error, and if insert fails, the subsequent Get is meaningless, so terminate with Fatal.
TestDelete
Func TestDelete (t * testing.T) {d: = NewDB (...) / / first use someDB's insert interface / / to write some test data err: = someDB.insert (...) If err! = nil {t.Fatal ("some msg")} / / then call the test method Delete / / to delete the data err = d.Delete ("testdeletekey") if err! = nil {t.Error ("some msg")} / / use someDB's Get interface / / to verify the deletion of the data _, err: = someDB.get (...) If err! = ErrNotFound {t.Error ("some msg")}} Common commands for running tests
Run the go test command to compile and execute all test cases in the current directory
If you need to execute test cases in the current directory and all subdirectories, run the command go test. /.
Run go test-run TestGet if you need to execute a test case, such as a TestGet use case alone
Run go test-help to view a detailed list of parameters, such as the-parallel parameter mentioned earlier
Part two: how to write a good GO language unit test
We have seen the basic unit test framework in the first part and can write your own unit tests.
However, it is not that easy to write a good unit test, and there are many elements to pay attention to.
Replace the original error reporting function with assertions
Let's look at an example like this:
If XXX {t.Error ("msg")} if AAA! = BBB {t.Error ("msg2")}
The err provided by the Go language is so unfriendly that the judged if needs to be written first.
For us GE language programmers who write more lines of UT than functional code, the increased amount of code is very scary.
Using assertions allows us to omit the if statement of this judgment and enhance the readability of the code.
The Go language itself does not provide an assert package, but there are many open source options. Such as using https://github.com/stretchr/testify
The above example can be simplified as follows:
Assert.True (t, XXX, "msg") assert.Equal (t, AAA, BBB, "msg2")
There are, of course, many other assertions besides True and Equal, which we need to find out by looking at the code or documentation.
Avoid random results
Let's look at an example like this:
A: = rand.Intn (100b): = rand.Intn (10) result: = div (a, b) assert.Equal (t, a Band b, result)
The results of UT should be decisive, and when we use random input values for UT, we make our test cases uncontrollable.
We don't realize the disadvantages when everything is all right, but when something bad happens, random results make it difficult for us to debug.
For example, the above example works most of the time, but only when b is random to 0 will crash. In the above example, the more correct approach is:
Result: = div (6,3) assert.Equal (t, 2, result)
Avoid meaningless repetition
Let's look at an example like this:
N: = 10000for iRU 0; I
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.