Question:
I'm unit testing 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 methods that you want to run as tests must be declared like this:
func TestAlgo(t *testing.T) {
...
}
Why? it's simply a contract between you, the programmer, and the language, so that when you run the command go test
Go runs the unit tests unitarily. To recognize what they are, they must be implemented in methods of the form
func TestXxx(*testing.T)
where each method starts with the word Test and Xxx is any alphanumeric string starting with an uppercase. In addition to this, the method must receive a variable of type *testing.T
as an argument. 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 it should print the logs 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 the second method won't actually run as an automatic unit test, because it doesn't honor the contract that Go requires because it receives a pointer to a structure of type B
inside the testing
package. This B
structure refers to a data type that is used to run any benchmark, or performance, tests that you want to include. However, the correct declaration for 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 package testing
) is that there is really no difference. In Go, the variable name in 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'll need to use the variable name to call the methods available in T to print errors, so you do need to declare the variable name as well, which is usually named t
by the reference:
func TestAlgo(t *testing.T) {
a = 1
if a != 2 {
t.Error("1 no es igual a 2)
}
}
There is more information about this in the Go documentation .