表驱动测试在使用testify时总是将父级显示为失败

huangapple go评论117阅读模式
英文:

Table-driven test always shows parent as failing when using testify

问题

使用testify进行表驱动测试时,如下所示:

  1. func TestFoo(t *testing.T) {
  2. a := assert.New(t)
  3. tc := []struct {
  4. desc string
  5. foo string
  6. }{
  7. {
  8. desc: "fail abc",
  9. foo: "abc",
  10. },
  11. {
  12. desc: "fail def",
  13. foo: "def",
  14. },
  15. }
  16. for _, tC := range tc {
  17. t.Run(tC.desc, func(t *testing.T) {
  18. tC := tC
  19. a.Equal(tC.foo, "ghi")
  20. })
  21. }
  22. }

你会得到模棱两可的失败信息:

  1. --- FAIL: TestFoo (0.00s)
  2. /test.go:27:
  3. Error Trace: /test.go:27
  4. Error: Not equal:
  5. expected: "abc"
  6. actual : "ghi"
  7. Diff:
  8. --- Expected
  9. +++ Actual
  10. @@ -1 +1 @@
  11. -abc
  12. +ghi
  13. Test: TestFoo
  14. /test.go:27:
  15. Error Trace: /test.go:27
  16. Error: Not equal:
  17. expected: "def"
  18. actual : "ghi"
  19. Diff:
  20. --- Expected
  21. +++ Actual
  22. @@ -1 +1 @@
  23. -def
  24. +ghi
  25. Test: TestFoo
  26. FAIL

而不是告诉你哪个子测试失败了,它们都显示父测试失败了(例如TestFoo而不是TestFoo/fail_abc)。如果表中有许多测试,这会使测试完全无用。

英文:

When using testify with table-driven tests as in:

  1. func TestFoo(t *testing.T) {
  2. a := assert.New(t)
  3. tc := []struct {
  4. desc string
  5. foo string
  6. }{
  7. {
  8. desc: "fail abc",
  9. foo: "abc",
  10. },
  11. {
  12. desc: "fail def",
  13. foo: "def",
  14. },
  15. }
  16. for _, tC := range tc {
  17. t.Run(tC.desc, func(t *testing.T) {
  18. tC := tC
  19. a.Equal(tC.foo, "ghi")
  20. })
  21. }
  22. }

Your failures will come back ambiguous:

  1. --- FAIL: TestFoo (0.00s)
  2. /test.go:27:
  3. Error Trace: /test.go:27
  4. Error: Not equal:
  5. expected: "abc"
  6. actual : "ghi"
  7. Diff:
  8. --- Expected
  9. +++ Actual
  10. @@ -1 +1 @@
  11. -abc
  12. +ghi
  13. Test: TestFoo
  14. /test.go:27:
  15. Error Trace: /test.go:27
  16. Error: Not equal:
  17. expected: "def"
  18. actual : "ghi"
  19. Diff:
  20. --- Expected
  21. +++ Actual
  22. @@ -1 +1 @@
  23. -def
  24. +ghi
  25. Test: TestFoo
  26. FAIL

Rather than telling you which subtest failed, they all show the parent test having failed (e.g. TestFoo instead of TestFoo/fail_abc). If there are many tests in the table, this can make the test completely useless.

答案1

得分: 1

当初始化 testify 简写时,必须使用子测试中的 *testing.T。如果你和我一样习惯在每个测试的顶部放置 a := assert.New(t),那么你将会传递父级的 *testing.T,所以失败将始终显示为来自父级。

重写为:

  1. func TestFoo(t *testing.T) {
  2. tc := []struct {
  3. desc string
  4. foo string
  5. }{
  6. {
  7. desc: "fail abc",
  8. foo: "abc",
  9. },
  10. {
  11. desc: "fail def",
  12. foo: "def",
  13. },
  14. }
  15. for _, tC := range tc {
  16. t.Run(tC.desc, func(t *testing.T) {
  17. tC := tC
  18. a := assert.New(t) // 现在在子测试中使用 *testing.T
  19. a.Equal(tC.foo, "ghi")
  20. })
  21. }
  22. }

得到了预期的易读输出(即按子测试和测试名称分解的失败):

  1. --- FAIL: TestFoo (0.00s)
  2. --- FAIL: TestFoo/fail_abc (0.00s)
  3. boop_test.go:27:
  4. Error Trace: /test.go:27
  5. Error: Not equal:
  6. expected: "abc"
  7. actual : "ghi"
  8. Diff:
  9. --- Expected
  10. +++ Actual
  11. @@ -1 +1 @@
  12. -abc
  13. +ghi
  14. Test: TestFoo/fail_abc
  15. --- FAIL: TestFoo/fail_def (0.00s)
  16. boop_test.go:27:
  17. Error Trace: /test.go:27
  18. Error: Not equal:
  19. expected: "def"
  20. actual : "ghi"
  21. Diff:
  22. --- Expected
  23. +++ Actual
  24. @@ -1 +1 @@
  25. -def
  26. +ghi
  27. Test: TestFoo/fail_def
  28. FAIL
英文:

When initializing the testify shorthand, it must use the *testing.T from the sub-test. If you have the same habit as me of putting a := assert.New(t) at the top of every test, you'll end up passing *testing.T from the parent, so the failures will always show as coming from the parent.

Rewriting as

  1. func TestFoo(t *testing.T) {
  2. tc := []struct {
  3. desc string
  4. foo string
  5. }{
  6. {
  7. desc: "fail abc",
  8. foo: "abc",
  9. },
  10. {
  11. desc: "fail def",
  12. foo: "def",
  13. },
  14. }
  15. for _, tC := range tc {
  16. t.Run(tC.desc, func(t *testing.T) {
  17. tC := tC
  18. a := assert.New(t) // Now using *testing.T from within the sub-test
  19. a.Equal(tC.foo, "ghi")
  20. })
  21. }
  22. }

Gets the expected legible output (i.e. failures broken up by sub-test and test names including the description):

  1. --- FAIL: TestFoo (0.00s)
  2. --- FAIL: TestFoo/fail_abc (0.00s)
  3. boop_test.go:27:
  4. Error Trace: /test.go:27
  5. Error: Not equal:
  6. expected: "abc"
  7. actual : "ghi"
  8. Diff:
  9. --- Expected
  10. +++ Actual
  11. @@ -1 +1 @@
  12. -abc
  13. +ghi
  14. Test: TestFoo/fail_abc
  15. --- FAIL: TestFoo/fail_def (0.00s)
  16. boop_test.go:27:
  17. Error Trace: /test.go:27
  18. Error: Not equal:
  19. expected: "def"
  20. actual : "ghi"
  21. Diff:
  22. --- Expected
  23. +++ Actual
  24. @@ -1 +1 @@
  25. -def
  26. +ghi
  27. Test: TestFoo/fail_def
  28. FAIL

huangapple
  • 本文由 发表于 2023年4月18日 05:17:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76039348.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定