How to write Unit Test in Go¶
Overview¶
Go | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
- Each
Spcify
block is a test case for one feature. BeforeEach
block is used to reset the state of Datastore and Keystore so that tests do not interfere with each other.
Therefore, we use BeforeEach
to reset and divide different tests which is specified by Specify
block.
Test Syntax¶
We take this block as an example:
Go | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
Test name should be clear and concise, and should be able to describe the tested feature
- The test name is
Default Test: Testing InitUser/GetUser on a single user
. - The test name is usually corresponding to the feature to be tested, here it means "We are going to test
InitUser
andGetUser
".
Use Error Return Value to check if the specific function works correctly
nil
In Go, nil
is a pre-declared identifier representing the zero value of a pointer, channel, func, interface, map, or slice type.
If return value equals to nil
, it means that the function works correctly. (like return 0
in C++)
Let take a deep look into this test body:
userlib.DebugMsg("Initializing user Alice.")
- This is a debug message, which is used to print out the message to the console.
- "Hey buddy, we are going to initialize user Alice."
alice, err = client.InitUser("alice", defaultPassword)
- This is the function we want to test,
client.InitUser(a,b)
. - 2 return values:
alice
anderr
. - If
err
isnil
, it means that the function works correctly.
- This is the function we want to test,
- We expect
err
to benil
, so we useExpect(err).To(BeNil())
to check if it isnil
.
Therefore, in this case, if err == nil
, and Expect(err).To(BeNil())
works well, and it means that function client.InitUser(a,b)
works correctly. Now we go to userlib.DebugMsg("Getting user Alice.")
for a sequent test. We are all good!
But, if err != nil
, and Expect(err).To(BeNil())
fails, it means that function client.InitUser(a,b)
does not work correctly. And the test will fail.
Failure Msg in Go
When a test fails in Go (especially using the Ginkgo testing framework, as seems to be the case here), an error message will typically be printed to the console, making it clear that an issue occurred. Here’s what the user will see:
-
Failure Message: Ginkgo will show a message like "Expected nil, but got
", where <error>
details the specific error returned by the function. This message helps the user quickly identify that theExpect(err).To(BeNil())
check did not pass. -
Test Name: Ginkgo will display the name of the failed test case, such as "Default Test: Testing InitUser/GetUser on a single user.", so the user knows exactly which test encountered the problem.
-
Debug Messages: Any
userlib.DebugMsg
statements that were executed before the failure will also be visible in the output, helping to trace where the failure occurred. -
Additional Context: In some cases, the line number in the code where the failure occurred will be shown. This can guide the user to the exact point of failure.
Like:
Go | |
---|---|
1 2 3 4 |
|
Q & A¶
Q1 Expect a function to return a specific error¶
One more question is that: we expect a function to return a specific error, especially in a function which is responsible for checking in original code (avoid illegal action), how to do that?
Go | |
---|---|
1 2 3 4 |
|
In this case, we don't allow appending to a nonexistent File (Product's feature).
Hence, if we append to a nonexisting file by AppendToFile
, we expect alice.AppendToFile(aliceFile, []byte(contentOne))
to return an error, so we use Expect(err).ToNot(BeNil())
to check if it is not nil
.
Q2 Not only error checking, but also check the return data¶
We can not only check error, but also check the return data.
Go | |
---|---|
1 2 3 4 |
|
Like Except(data).To(Equal([]byte(contentOne + contentTwo + contentThree)))
, we can check the return data of the function.
In this way, we can check verify the function working status not only by checking the error, but also by checking the return data.