Question:
I am unit testing in Go
and based on some examples a test function is defined like this:
func TestAlgo(t *testing.T) {
...
}
What I want to know is what exactly does the parameter of that function mean?
I've also seen them do something like:
func TestAlgo(*testing.B) {
...
}
What is the difference with the previous parameter?
Answer:
As you mentioned, all the methods you want to run as tests must be declared like this:
func TestAlgo(t *testing.T) {
...
}
Why? it is simply a contract between you, the programmer, and the language, so that when you run the go test
Go command, you run the unit tests in a unit way. To recognize what they are, they must be implemented in methods of the form
func TestXxx(*testing.T)
where each method begins with the word Test and Xxx is any alphanumeric string that begins with uppercase. In addition to this, the method must receive as an argument a variable of type *testing.T
. Now what does this parameter mean? To this method you are passing a pointer to a structure called T
that is inside the testing
package. This parameter is passed to all the methods that execute unit tests since the structure stores information about the state of the tests and the format in which the logs should be printed if desired during the execution of the test. Here you can see the source code in which this structure is declared.
The difference between
func TestAlgo(t *testing.T) {
...
}
Y
func TestAlgo(*testing.B) {
...
}
is that in reality the second method will not be executed as an automatic unit test, because it does not fulfill the contract that Go requires because it receives a pointer to a structure of type B
within the testing
package. This B
structure refers to a data type that is used to run benchmark or performance tests that you want to include. However, the correct declaration of the methods that want to be executed like this is:
func BenchmarkXxx(*testing.B) {
...
}
Now if you actually refer to the difference between
func TestAlgo(t *testing.T) {
...
}
Y
func TestAlgo(*testing.T) {
...
}
(both with parameter pointer to a structure of type T
in the testing
package) is that there really is no difference. In Go, the variable name in the function arguments is not strictly necessary, just the type. However, if you want to do something like:
func TestAlgo(*testing.T) {
//Método de ejecución de la prueba
//Si ocurre un error, imprima un mensaje ó marque la prueba como fallida.
}
you will need to use the variable name to call the methods available in T to print errors, therefore you will need to declare the variable name as well, which the reference normally calls t
:
func TestAlgo(t *testing.T) {
a = 1
if a != 2 {
t.Error("1 no es igual a 2)
}
}
See the Go documentation for more information on this.