He visto varias estrategias de nomenclatura de paquetes de prueba diferentes dentro de Go y quería saber cuáles son las ventajas y desventajas de cada una y cuál debería usar.
Estrategia 1:
Nombre de archivo: github.com/user/myfunc.go
package myfunc
Nombre del archivo de prueba: github.com/user/myfunc_test.go
package myfunc
Consulte bzip2 para ver un ejemplo.
Estrategia 2:
Nombre de archivo: github.com/user/myfunc.go
package myfunc
Nombre del archivo de prueba: github.com/user/myfunc_test.go
package myfunc_test
import (
"github.com/user/myfunc"
)
Ver cable para un ejemplo.
Estrategia 3:
Nombre de archivo: github.com/user/myfunc.go
package myfunc
Nombre del archivo de prueba: github.com/user/myfunc_test.go
package myfunc_test
import (
. "myfunc"
)
Vea cadenas para un ejemplo.
La biblioteca estándar de Go parece utilizar una combinación de la estrategia 1 y 2. ¿Cuál de las tres debería utilizar? Es una molestia agregar package *_test
mis paquetes de prueba, ya que significa que no puedo probar los métodos privados de mi paquete, pero tal vez haya una ventaja oculta que no conozco.
fuente
Respuestas:
La diferencia fundamental entre las tres estrategias que ha enumerado es si el código de prueba está o no en el mismo paquete que el código bajo prueba. La decisión de utilizar
package myfunc
opackage myfunc_test
en el archivo de prueba depende de si desea realizar pruebas de caja blanca o de caja negra .No hay nada de malo en usar ambos métodos en un proyecto. Por ejemplo, podría tener
myfunc_whitebox_test.go
ymyfunx_blackbox_test.go
.Comparación de paquetes de códigos de prueba
package myfunc_test
, lo que garantizará que solo esté usando los identificadores exportados .package myfunc
para tener acceso a los identificadores no exportados. Bueno para pruebas unitarias que requieren acceso a variables, funciones y métodos no exportados.Comparación de las estrategias enumeradas en la pregunta
myfunc_test.go
usapackage myfunc
: en este caso, el código de pruebamyfunc_test.go
estará en el mismo paquete que el código que se está probandomyfunc.go
, que se encuentramyfunc
en este ejemplo.myfunc_test.go
utilizapackage myfunc_test
: en este caso, el código de prueba enmyfunc_test.go
"se compilará como un paquete separado y luego se vinculará y ejecutará con el binario de prueba principal". [Fuente: líneas 58 a 59 en el código fuente de test.go ]myfunc_test.go
usapackage myfunc_test
pero se importamyfunc
usando la notación de puntos: esta es una variante de la Estrategia 2, pero usa la notación de puntos para importarmyfunc
.fuente
_test.go
separados del paquete que se está probando (el mismo comportamiento que la Estrategia 2). Esto no parece estar documentado según github.com/golang/go/issues/15315_test.go
no era de_test
paquete y que contiene unfunc init()
que cambia alguna variable de paquete global para probar. Estaba equivocado..
no resuelve el problema de la bifurcación. No es una importación relativa. Simplemente importa los identificadores "en el paquete actual".Depende del alcance de sus pruebas. Las pruebas de alto nivel (integración, aceptación, etc.) probablemente deberían colocarse en un paquete separado para asegurarse de que está utilizando el paquete a través de la API exportada.
Si tiene un paquete grande con muchos componentes internos que deben someterse a prueba, utilice el mismo paquete para sus pruebas. Pero esa no es una invitación para que sus pruebas accedan a ningún estado privado. Eso haría de la refactorización una pesadilla. Cuando escribo estructuras en go , a menudo estoy implementando interfaces. Son esos métodos de interfaz los que invoco de mis pruebas, no todos los métodos / funciones auxiliares individualmente.
fuente
Debe utilizar la estrategia 1 siempre que sea posible. Puede usar el
foo_test
nombre del paquete especial para evitar ciclos de importación, pero eso es mayormente allí, por lo que la biblioteca estándar se puede probar con el mismo mecanismo. Por ejemplo,strings
no se puede probar con la estrategia 1 ya que eltesting
paquete depende destrings
. Como dijiste, con la estrategia 2 o 3 no tienes acceso a los identificadores privados del paquete, por lo que normalmente es mejor no usarlo a menos que sea necesario.fuente
Una nota importante que me gustaría agregar
import .
de Golang CodeReviewComments :El
import .
formulario puede ser útil en pruebas que, debido a dependencias circulares , no pueden formar parte del paquete que se está probando:En este caso, el archivo de prueba no puede estar en el paquete foo porque usa
bar/testutil
, que importa foo. Entonces usamos la 'importación'. formulario para permitir que el archivo pretenda ser parte del paquete foo aunque no lo sea.Excepto en este caso, no lo utilice
import .
en sus programas. Hace que los programas sean mucho más difíciles de leer porque no está claro si un nombre como Quux es un identificador de nivel superior en el paquete actual o en un paquete importado.fuente