[testing] “testing”패키지를 사용하여 Go 테스트에서 어떻게 인쇄합니까?

Go에서 무언가를 인쇄 (즉, 테스트 디버깅을 위해)하는 문으로 테스트를 실행하고 있지만 아무것도 인쇄하지 않습니다.

func TestPrintSomething(t *testing.T) {
    fmt.Println("Say hi")
}

이 파일에서 go test를 실행하면 다음과 같이 출력됩니다.

ok      command-line-arguments  0.004s

내가 아는 한 실제로 인쇄하는 유일한 방법은 다음과 같이 t.Error ()를 통해 인쇄하는 것입니다.

func TestPrintSomethingAgain(t *testing.T) {
    t.Error("Say hi")
}

다음을 출력합니다.

Say hi
--- FAIL: TestPrintSomethingAgain (0.00 seconds)
    foo_test.go:35: Say hi
FAIL
FAIL    command-line-arguments  0.003s
gom:  exit status 1

Google을 검색하고 설명서를 살펴 봤지만 아무것도 찾지 못했습니다.



답변

구조체 testing.Ttesting.B둘 다 당신이 찾고있는 것처럼 들리는 .Logand .Logf메소드를 가지고 있습니다. .Log.Logf유사하다 fmt.Printfmt.Printf각각.

자세한 내용은 http://golang.org/pkg/testing/#pkg-index를 참조 하세요.

fmt.Xprint 문 테스트 내에서 작동하지만 출력이 예상되는 화면에 없을 수 있으므로 .NET에서 로깅 메서드를 사용해야하는 이유를 알 수 있습니다 testing.

귀하의 경우에서와 같이 실패하지 않은 테스트에 대한 로그를 보려면 플래그 를 제공해야 go test합니다 -v(v는 자세한 정보 표시). 테스트 플래그에 대한 자세한 내용은 https://golang.org/cmd/go/#hdr-Testing_flags 에서 확인할 수 있습니다.


답변

예를 들면

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

명령 이동

테스트 플래그에 대한 설명

-v
Verbose output: log all tests as they are run. Also print all
text from Log and Logf calls even if the test succeeds.

패키지 테스트

func (* T) 로그

func (c *T) Log(args ...interface{})

Log는 Println과 유사한 기본 형식을 사용하여 인수를 형식화하고 오류 로그에 텍스트를 기록합니다. 테스트의 경우 테스트가 실패하거나 -test.v 플래그가 설정된 경우에만 텍스트가 인쇄됩니다. 벤치 마크의 경우 -test.v 플래그의 값에 따라 성능이 달라지지 않도록 항상 텍스트가 인쇄됩니다.


답변

t.Log()테스트가 완료 될 때까지 표시되지 않으므로 중단되거나 성능이 나쁜 테스트를 디버깅하려는 경우을 사용해야 fmt합니다.

예 : Go 1.13 (2019 년 8 월)까지 포함되었습니다.

그리고 그것은 golang.org24929 호에서 뒤따 랐습니다.

다음 (어리석은) 자동 테스트를 고려하십시오.

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)
    }
}

내가 실행하면 go test -v, 내가 모든 때까지 더 로그 출력을 얻을 TestFoo완료 , 모든 때까지 출력이 TestBar수행되지 않으며, 모든 때까지 다시 한번 더 출력이 TestBaz이루어집니다.
테스트가 작동하면 괜찮지 만 버그가있는 경우 버퍼링 로그 출력에 문제가있는 몇 가지 경우가 있습니다.

  • 로컬에서 반복 할 때 변경을 수행하고 테스트를 실행하고 로그에서 무슨 일이 일어나고 있는지 즉시 확인하고 필요한 경우 CTRL + C를 눌러 테스트를 일찍 종료하고 다른 변경을 수행하고 다시 수행 할 수 있기를 원합니다. 테스트를 실행합니다. 느린
    경우 TestFoo(예 : 통합 테스트) 테스트가 끝날 때까지 로그 출력이 표시되지 않습니다. 이것은 반복을 상당히 느리게합니다.
  • 경우 TestFoo는 걸 결코 완전한 일으키는 버그를 가지고, 난 더 로그 출력 무엇이든지를 얻을 것입니다. 이 경우 t.Logt.Logf전혀 쓸모가 있습니다.
    이것은 디버깅을 매우 어렵게 만듭니다.
  • 또한 로그 출력이 표시되지 않을뿐만 아니라 테스트가 너무 오래 중단되면 Go 테스트 시간 제한이 10 분 후에 테스트를 종료하거나 해당 시간 제한을 늘리면 많은 CI 서버가 테스트를 종료합니다. 일정 시간 (예 : CircleCI에서 10 분) 후 출력을 기록합니다.
    이제 내 테스트가 종료되고 로그에 무슨 일이 일어 났는지 알려주는 내용이 없습니다.

그러나 (아마도) Go 1.14 (2020 년 1 분기) : CL 127120

테스트 : 상세 모드에서 로그 출력 스트림

이제 출력은 다음과 같습니다.

=== RUN   TestFoo
=== PAUSE TestFoo
=== RUN   TestBar
=== PAUSE TestBar
=== RUN   TestGaz
=== PAUSE TestGaz
=== CONT  TestFoo
    TestFoo: main_test.go:14: hello from foo
=== CONT  TestGaz
=== CONT  TestBar
    TestGaz: main_test.go:38: hello from gaz
    TestBar: main_test.go:26: hello from bar
    TestFoo: main_test.go:14: hello from foo
    TestBar: main_test.go:26: hello from bar
    TestGaz: main_test.go:38: hello from gaz
    TestFoo: main_test.go:14: hello from foo
    TestGaz: main_test.go:38: hello from gaz
    TestBar: main_test.go:26: hello from bar
    TestFoo: main_test.go:14: hello from foo
    TestGaz: main_test.go:38: hello from gaz
    TestBar: main_test.go:26: hello from bar
    TestGaz: main_test.go:38: hello from gaz
    TestFoo: main_test.go:14: hello from foo
    TestBar: main_test.go:26: hello from bar
--- PASS: TestFoo (1.00s)
--- PASS: TestGaz (1.00s)
--- PASS: TestBar (1.00s)
PASS
ok      dummy/streaming-test    1.022s

Dave Cheney가 ” go test -v스트리밍 출력 ” 에서 증명했듯이 실제로 Go 1.14에 있습니다 .

Go 1.14에서는 테스트 실행이 끝날 때까지 저장하지 않고 발생하는대로 출력 go test -v 스트리밍 합니다 .t.Log

Go 1.14에서는 테스트가 완료 될 때까지 기다리지 않고 fmt.Printlnt.Log행이 인터리브되어 사용시 테스트 출력이 스트리밍됨을 보여줍니다 go test -v.

Dave에 따르면 이점 :

이것은 테스트가 실패 할 때 종종 오랜 기간 동안 재 시도하는 통합 스타일 테스트를위한 훌륭한 삶의 질 향상입니다.
스트리밍t.Log 출력은 Gophers가 출력을 받기 위해 전체 테스트 시간이 초과 될 때까지 기다릴 필요없이 테스트 실패를 디버깅하는 데 도움이됩니다.


답변

때로는 테스트를 위해

fmt.Fprintln(os.Stdout, "hello")

또한 다음 위치로 인쇄 할 수 있습니다.

fmt.Fprintln(os.Stderr, "hello)


답변

t.Logt.Logf테스트에 인쇄 않지만 그것이 당신의 시험과 같은 줄에 인쇄 종종 놓칠 수 있습니다. 내가하는 일은 눈에 띄는 방식으로 기록하는 것입니다.

t.Run("FindIntercomUserAndReturnID should find an intercom user", func(t *testing.T) {

    id, err := ic.FindIntercomUserAndReturnID("test3@test.com")
    assert.Nil(t, err)
    assert.NotNil(t, id)

    t.Logf("\n\nid: %v\n\n", *id)
})

터미널에 다음과 같이 인쇄합니다.

=== RUN   TestIntercom
=== RUN   TestIntercom/FindIntercomUserAndReturnID_should_find_an_intercom_user
    TestIntercom/FindIntercomUserAndReturnID_should_find_an_intercom_user: intercom_test.go:34:

        id: 5ea8caed05a4862c0d712008

--- PASS: TestIntercom (1.45s)
    --- PASS: TestIntercom/FindIntercomUserAndReturnID_should_find_an_intercom_user (1.45s)
PASS
ok      github.com/RuNpiXelruN/third-party-delete-service   1.470s


답변

*_test.go파일은 복잡한 데이터 구조, 여기에 예를 덤프해야하는 경우 다른 사람과 같은 이동 소스, 새 로거마다 시간을 초기화 할 수 있습니다 :

// initZapLog is delegated to initialize a new 'log manager'
func initZapLog() *zap.Logger {
    config := zap.NewDevelopmentConfig()
    config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
    config.EncoderConfig.TimeKey = "timestamp"
    config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
    logger, _ := config.Build()
    return logger
}

그런 다음 매번 모든 테스트에서 :

func TestCreateDB(t *testing.T) {
    loggerMgr := initZapLog()
    // Make logger avaible everywhere
    zap.ReplaceGlobals(loggerMgr)
    defer loggerMgr.Sync() // flushes buffer, if any
    logger := loggerMgr.Sugar()
    logger.Debug("START")
    conf := initConf()
    /* Your test here
    if false {
        t.Fail()
    }*/
}


답변