t.Log()
fmt
จะไม่แสดงขึ้นจนกระทั่งหลังจากการทดสอบเสร็จสมบูรณ์ดังนั้นถ้าคุณกำลังพยายามที่จะแก้ปัญหาการทดสอบที่จะแขวนหรือทำงานได้ไม่ดีดูเหมือนว่าคุณจำเป็นต้องใช้
ใช่: ในกรณีนี้รวมถึง Go 1.13 (สิงหาคม 2019)
และตามมาในgolang.org
ฉบับ 24929
พิจารณาการทดสอบอัตโนมัติ (โง่ ๆ ) ต่อไปนี้:
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.Log
และt.Logf
ไม่มีประโยชน์เลย
ทำให้การดีบักทำได้ยากมาก
- ยิ่งไปกว่านั้นไม่เพียง แต่ฉันจะไม่ได้รับเอาต์พุตบันทึกเท่านั้น แต่หากการทดสอบหยุดทำงานนานเกินไปการหมดเวลาทดสอบ Go จะฆ่าการทดสอบหลังจากผ่านไป 10 นาทีหรือถ้าฉันเพิ่มระยะหมดเวลานั้นเซิร์ฟเวอร์ CI จำนวนมากจะปิดการทดสอบด้วยหากไม่มี บันทึกเอาต์พุตหลังจากระยะเวลาหนึ่ง (เช่น 10 นาทีใน CircleCI)
ตอนนี้การทดสอบของฉันถูกฆ่าตายและฉันไม่มีอะไรในบันทึกที่จะบอกว่าเกิดอะไรขึ้น
แต่สำหรับ (อาจเป็นไปได้) ไป 1.14 (Q1 2020): CL 127120
การทดสอบ: สตรีมล็อกเอาต์พุตในโหมด verbose
ผลลัพธ์ตอนนี้คือ:
=== 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
มันอยู่ใน Go 1.14 อย่างที่ Dave Cheney ยืนยันใน " go test -v
สตรีมมิ่งเอาท์พุต ":
ใน Go 1.14 go test -v
จะสตรีมt.Log
เอาต์พุตตามที่เกิดขึ้นแทนที่จะกักตุนไว้จนกว่าจะสิ้นสุดการทดสอบที่มันเกิดขึ้นมากกว่าการกักตุนมันถึงจุดสิ้นสุดของการดำเนินการทดสอบ
ภายใต้ Go 1.14 fmt.Println
และt.Log
บรรทัดจะแทรกสลับกันแทนที่จะรอให้การทดสอบเสร็จสมบูรณ์แสดงให้เห็นว่าเอาต์พุตการทดสอบถูกสตรีมเมื่อgo test -v
ใช้งาน
ข้อได้เปรียบตาม Dave:
นี่คือการปรับปรุงคุณภาพชีวิตที่ดีสำหรับการทดสอบรูปแบบการบูรณาการซึ่งมักจะลองซ้ำเป็นเวลานานเมื่อการทดสอบล้มเหลว เอาต์พุตการ
สตรีมt.Log
จะช่วยให้ Gophers แก้ไขข้อบกพร่องของการทดสอบเหล่านั้นโดยไม่ต้องรอจนกว่าการทดสอบทั้งหมดจะหมดเวลาเพื่อรับเอาต์พุต