Làm cách nào để bạn in trong bài kiểm tra Go bằng cách sử dụng gói “kiểm tra”?


129

Tôi đang chạy kiểm tra trong Go với một câu lệnh in một thứ gì đó (tức là để gỡ lỗi các bài kiểm tra) nhưng nó không in bất cứ thứ gì.

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

Khi tôi chạy go test trên tệp này, đây là kết quả:

ok      command-line-arguments  0.004s

Cách duy nhất để thực sự in nó, theo như tôi biết, là in nó qua t.Error (), như sau:

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

Kết quả đầu ra này:

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

Tôi đã lên Google và xem qua sách hướng dẫn nhưng không tìm thấy gì.


Điều này có thể khả thi đối với Go 1.14 (Q1 2010). Xem câu trả lời của tôi dưới đây .
VonC

@VonC s / b Q1 2020
user2133814

@ user2133814 Đồng ý, thực sự phải là năm 2020 chứ không phải năm 2010. Câu trả lời bên dưới đề cập đến năm 2020. Tôi đã chỉnh sửa câu trả lời đã nói, có tham khảo bài viết của Dave Cheney về tính năng mới đó.
VonC

Câu trả lời:


142

Các cấu trúc testing.Ttesting.Bcả hai đều có một .Log.Logfphương pháp có vẻ là những gì bạn đang tìm kiếm. .Log.Logftương tự với fmt.Printfmt.Printftương ứng.

Xem thêm chi tiết tại đây: http://golang.org/pkg/testing/#pkg-index

fmt.Xin báo cáo làm việc bên trong các bài kiểm tra, nhưng bạn sẽ tìm thấy sản lượng của họ có lẽ không phải trên màn hình mà bạn mong đợi để tìm thấy nó và, vì thế, tại sao bạn nên sử dụng các phương pháp khai thác gỗ trong testing.

Nếu, như trong trường hợp của bạn, bạn muốn xem các bản ghi cho các bài kiểm tra mà không phải là thất bại, bạn phải cung cấp go testnhững -vlá cờ (v cho rườm rà). Bạn có thể tìm thấy thêm chi tiết về cờ thử nghiệm tại đây: https://golang.org/cmd/go/#hdr-Testing_flags


15
t.Log () sẽ không hiển thị cho đến khi quá trình kiểm tra hoàn tất, vì vậy nếu bạn đang cố gắng gỡ lỗi một bài kiểm tra bị treo hoặc hoạt động kém, có vẻ như bạn cần sử dụng fmt. Xem câu trả lời của PeterSO về cách sử dụng go test -v để hiển thị kết quả đầu ra của fmt.Println khi chạy các bài kiểm tra.
voutasaurus,

142

Ví dụ,

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

Ra lệnh

Mô tả cờ thử nghiệm

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

Kiểm tra gói

Nhật ký func (* T)

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

Nhật ký định dạng các đối số của nó bằng cách sử dụng định dạng mặc định, tương tự như Println, và ghi lại văn bản trong nhật ký lỗi. Đối với các bài kiểm tra, văn bản sẽ chỉ được in nếu bài kiểm tra không thành công hoặc cờ -test.v được đặt. Đối với điểm chuẩn, văn bản luôn được in để tránh hiệu suất phụ thuộc vào giá trị của cờ -test.v.


21
verboselà những gì tôi đang tìm kiếm.
cevaris

2
anwa để xem dữ liệu ghi nhận trong moethod ou đang thử nghiệm bản thân
filthy_wizard

7

t.Log()sẽ không hiển thị cho đến khi quá trình kiểm tra hoàn tất, vì vậy nếu bạn đang cố gắng gỡ lỗi một bài kiểm tra bị treo hoặc hoạt động kém thì có vẻ như bạn cần sử dụng fmt.

Có: đó là trường hợp cho đến Go 1.13 (tháng 8 năm 2019).

Và điều đó được tiếp nối trong golang.orgsố 24929

Hãy xem xét các thử nghiệm tự động (ngớ ngẩn) sau:

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

Nếu tôi chạy go test -v, tôi không nhận được đầu ra nhật ký nào cho đến khi tất cả TestFoođược hoàn thành , sau đó không có đầu ra nào cho đến khi hoàn thành tất cả TestBarvà một lần nữa không có đầu ra nào nữa cho đến khi tất cả TestBazhoàn thành.
Điều này là tốt nếu các thử nghiệm đang hoạt động, nhưng nếu có một số loại lỗi, có một số trường hợp đầu ra nhật ký đệm có vấn đề:

  • Khi lặp lại cục bộ, tôi muốn có thể thực hiện thay đổi, chạy thử nghiệm của mình, xem những gì đang xảy ra trong nhật ký ngay lập tức để hiểu điều gì đang xảy ra, nhấn CTRL + C để tắt thử nghiệm sớm nếu cần, thực hiện một thay đổi khác, tái chạy các bài kiểm tra, v.v.
    Nếu TestFoochậm (ví dụ: đó là kiểm tra tích hợp), tôi không nhận được kết quả ghi nhật ký nào cho đến khi kết thúc kiểm tra. Điều này làm chậm đáng kể sự lặp lại.
  • Nếu TestFoocó lỗi khiến nó bị treo và không bao giờ hoàn thành, tôi sẽ không nhận được bất kỳ đầu ra nhật ký nào. Trong những trường hợp này, t.Logt.Logfkhông có ích gì cả.
    Điều này làm cho việc gỡ lỗi rất khó khăn.
  • Hơn nữa, tôi không chỉ không nhận được đầu ra nhật ký, mà nếu quá trình kiểm tra bị treo quá lâu, hoặc thời gian chờ kiểm tra Go sẽ giết kiểm tra sau 10 phút hoặc nếu tôi tăng thời gian chờ đó, nhiều máy chủ CI cũng sẽ ngừng kiểm tra nếu không có. ghi đầu ra sau một khoảng thời gian nhất định (ví dụ: 10 phút trong CircleCI).
    Vì vậy, bây giờ các bài kiểm tra của tôi đã bị giết và tôi không có gì trong nhật ký để cho tôi biết điều gì đã xảy ra.

Nhưng đối với (có thể) Go 1.14 (Q1 2020): CL 127120

kiểm tra: đầu ra nhật ký phát trực tuyến ở chế độ tiết

Kết quả bây giờ là:

=== 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

Nó thực sự là trong Go 1.14, như Dave Cheney chứng thực trong " go test -vđầu ra phát trực tuyến ":

Trong Go 1.14, go test -vsẽ phát trực tiếp t.Logđầu ra khi nó xảy ra, thay vì tích trữ nó cho đến khi kết thúc quá trình chạy thử nghiệm .

Trong Mục 1.14 fmt.Println, t.Logcác dòng và và được xen kẽ , thay vì đợi quá trình kiểm tra hoàn thành, chứng tỏ rằng đầu ra kiểm tra được phát trực tuyến khi go test -vđược sử dụng.

Lợi thế, theo Dave:

Đây là một cải thiện chất lượng cuộc sống tuyệt vời cho các bài kiểm tra kiểu tích hợp thường thử lại trong thời gian dài khi bài kiểm tra không đạt.
Phát trực tuyến t.Logđầu ra sẽ giúp Gophers gỡ lỗi các lỗi kiểm tra đó mà không cần phải đợi cho đến khi hết thời gian kiểm tra để nhận đầu ra của chúng.


5

Để thử nghiệm đôi khi tôi làm

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

Ngoài ra, bạn có thể in tới:

fmt.Fprintln(os.Stderr, "hello)

Đầu tiên trong số đó chỉ có thể là fmt.Println("hello").
Duncan Jones

2

t.Logt.Logfin ra trong bài kiểm tra của bạn nhưng thường có thể bị bỏ sót vì nó in trên cùng dòng với bài kiểm tra của bạn. Những gì tôi làm là Ghi lại chúng theo cách khiến chúng nổi bật, tức là

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

in nó vào thiết bị đầu cuối dưới dạng,

=== 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

-2

Các *_test.gotập tin là một nguồn Go như những người khác, bạn có thể khởi tạo một logger mới mỗi lần nếu bạn cần để đổ cấu trúc dữ liệu phức tạp, ở đây một ví dụ:

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

Sau đó, mọi lúc, mọi thử nghiệm:

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()
    }*/
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.