¿Cómo se imprime en una prueba de Go usando el paquete "testing"?
Estoy ejecutando una prueba en Go con una declaración para imprimir algo (es decir, para depurar pruebas) pero no imprime nada.
func TestPrintSomething(t *testing.T) {
fmt.Println("Say hi")
}
Cuando ejecuto go test en este archivo, este es el resultado:
ok command-line-arguments 0.004s
La única manera de lograr que se imprima, hasta donde yo sé, es imprimirlo mediante t.Error(), así:
func TestPrintSomethingAgain(t *testing.T) {
t.Error("Say hi")
}
Lo que genera esto:
Say hi
--- FAIL: TestPrintSomethingAgain (0.00 seconds)
foo_test.go:35: Say hi
FAIL
FAIL command-line-arguments 0.003s
gom: exit status 1
Busqué en Google y revisé el manual pero no encontré nada.
Las estructuras testing.T
y testing.B
ambas tienen un método .Log
y .Logf
que parece ser lo que estás buscando. .Log
y .Logf
son similares a fmt.Print
y fmt.Printf
respectivamente.
Vea más detalles aquí: http://golang.org/pkg/testing/#pkg-index
fmt.X
Las declaraciones de impresión funcionan dentro de las pruebas, pero encontrará que su salida probablemente no esté en la pantalla donde espera encontrarla y, por lo tanto, debería usar los métodos de registro en testing
.
Si, como en su caso, desea ver los registros de las pruebas que no fallan, debe proporcionar go test
la -v
marca (v para verbosidad). Puede encontrar más detalles sobre las banderas de prueba aquí: https://golang.org/cmd/go/#hdr-Testing_flags
Por ejemplo,
package verbose
import (
"fmt"
"testing"
)
func TestPrintSomething(t *testing.T) {
fmt.Println("Say hi")
t.Log("Say bye")
}
go test -v
=== RUN TestPrintSomething
Say hi
--- PASS: TestPrintSomething (0.00 seconds)
v_test.go:10: Say bye
PASS
ok so/v 0.002s
comando ir
Descripción de las banderas de prueba.
-v Verbose output: log all tests as they are run. Also print all text from Log and Logf calls even if the test succeeds.
Prueba de paquete
función (*T) Registro
func (c *T) Log(args ...interface{})
Log formatea sus argumentos usando el formato predeterminado, análogo a Println, y registra el texto en el registro de errores. Para las pruebas, el texto se imprimirá solo si la prueba falla o si se establece el indicador -test.v. Para los puntos de referencia, el texto siempre se imprime para evitar que el rendimiento dependa del valor del indicador -test.v.
t.Log()
no aparecerá hasta que se complete la prueba, por lo que si está intentando depurar una prueba que se bloquea o funciona mal, parece que necesita usarfmt
.
Sí: así fue hasta Go 1.13 (agosto de 2019) incluido.
Y eso fue seguido en golang.org
el número 24929.
Considere las siguientes (tontas) pruebas automatizadas:
func TestFoo(t *testing.T) { t.Parallel() for i := 0; i < 15; i++ { t.Logf("%d", i) time.Sleep(3 * time.Second) } } func TestBar(t *testing.T) { t.Parallel() for i := 0; i < 15; i++ { t.Logf("%d", i) time.Sleep(2 * time.Second) } } func TestBaz(t *testing.T) { t.Parallel() for i := 0; i < 15; i++ { t.Logf("%d", i) time.Sleep(1 * time.Second) } }
Si ejecuto
go test -v
, no obtengo ningún resultado de registro hasta que todoTestFoo
esté terminado , luego no obtengo ningún resultado hasta que todoTestBar
esté terminado y, nuevamente, no obtengo más resultados hasta que todoTestBaz
esté terminado.
Esto está bien si las pruebas funcionan, pero si hay algún tipo de error, hay algunos casos en los que almacenar en búfer la salida del registro es problemático:
- Al iterar localmente, quiero poder hacer un cambio, ejecutar mis pruebas, ver lo que sucede en los registros de inmediato para comprender lo que está sucediendo, presionar CTRL+C para cerrar la prueba antes si es necesario, hacer otro cambio, volver a ejecutar las pruebas, etc.
SiTestFoo
es lento (por ejemplo, es una prueba de integración), no obtengo ningún resultado de registro hasta el final de la prueba. Esto ralentiza significativamente la iteración.- Si
TestFoo
tiene un error que hace que se cuelgue y nunca se complete, no obtendría ningún resultado de registro. En estos casos,t.Log
yat.Logf
no sirven de nada.
Esto hace que la depuración sea muy difícil.- Además, no solo no obtengo ningún resultado de registro, sino que si la prueba se demora demasiado, el tiempo de espera de la prueba Go finaliza la prueba después de 10 minutos, o si aumento ese tiempo de espera, muchos servidores de CI también finalizarán las pruebas si no hay ningún resultado de registro. registrar la salida después de un cierto período de tiempo (por ejemplo, 10 minutos en CircleCI).
Ahora mis pruebas han sido canceladas y no tengo nada en los registros que me diga qué sucedió.
Pero para (posiblemente) Go 1.14 (primer trimestre de 2020): CL 127120
prueba: salida del registro de transmisión en modo detallado
La salida ahora es:
=== RUN TestFoo
=== PAUSE TestFoo
=== RUN TestBar
=== PAUSE TestBar
=== RUN TestBaz
=== PAUSE TestBaz
=== CONT TestFoo
=== CONT TestBaz
main_test.go:30: 0
=== CONT TestFoo
main_test.go:12: 0
=== CONT TestBar
main_test.go:21: 0
=== CONT TestBaz
main_test.go:30: 1
main_test.go:30: 2
=== CONT TestBar
main_test.go:21: 1
=== CONT TestFoo
main_test.go:12: 1
=== CONT TestBaz
main_test.go:30: 3
main_test.go:30: 4
=== CONT TestBar
main_test.go:21: 2
=== CONT TestBaz
main_test.go:30: 5
=== CONT TestFoo
main_test.go:12: 2
=== CONT TestBar
main_test.go:21: 3
=== CONT TestBaz
main_test.go:30: 6
main_test.go:30: 7
=== CONT TestBar
main_test.go:21: 4
=== CONT TestBaz
main_test.go:30: 8
=== CONT TestFoo
main_test.go:12: 3
=== CONT TestBaz
main_test.go:30: 9
=== CONT TestBar
main_test.go:21: 5
=== CONT TestBaz
main_test.go:30: 10
main_test.go:30: 11
=== CONT TestFoo
main_test.go:12: 4
=== CONT TestBar
main_test.go:21: 6
=== CONT TestBaz
main_test.go:30: 12
main_test.go:30: 13
=== CONT TestBar
main_test.go:21: 7
=== CONT TestBaz
main_test.go:30: 14
=== CONT TestFoo
main_test.go:12: 5
--- PASS: TestBaz (15.01s)
=== CONT TestBar
main_test.go:21: 8
=== CONT TestFoo
main_test.go:12: 6
=== CONT TestBar
main_test.go:21: 9
main_test.go:21: 10
=== CONT TestFoo
main_test.go:12: 7
=== CONT TestBar
main_test.go:21: 11
=== CONT TestFoo
main_test.go:12: 8
=== CONT TestBar
main_test.go:21: 12
main_test.go:21: 13
=== CONT TestFoo
main_test.go:12: 9
=== CONT TestBar
main_test.go:21: 14
=== CONT TestFoo
main_test.go:12: 10
--- PASS: TestBar (30.01s)
=== CONT TestFoo
main_test.go:12: 11
main_test.go:12: 12
main_test.go:12: 13
main_test.go:12: 14
--- PASS: TestFoo (45.02s)
PASS
ok command-line-arguments 45.022s
De hecho, está en Go 1.14, como atestigua Dave Cheney en " go test -v
salida de streaming ":
En Go 1.14,
go test -v
se transmitirát.Log
la salida a medida que ocurra, en lugar de acumularla hasta el final de la ejecución de prueba .
En Go 1.14, las líneas
fmt.Println
y están entrelazadas , en lugar de esperar a que se complete la prueba, lo que demuestra que el resultado de la prueba se transmite cuando se utiliza.t.Log
go test -v
Ventaja, según Dave:
Esta es una gran mejora en la calidad de vida de las pruebas de estilo de integración que a menudo se reintentan durante períodos prolongados cuando la prueba falla.
La transmisiónt.Log
de resultados ayudará a Gophers a depurar esas fallas de prueba sin tener que esperar hasta que se agote el tiempo de espera de toda la prueba para recibir su resultado.
Para probar a veces lo hago
fmt.Fprintln(os.Stdout, "hello")
Además, puede imprimir en:
fmt.Fprintln(os.Stderr, "hello")