英文:
Table-driven test always shows parent as failing when using testify
问题
使用testify进行表驱动测试时,如下所示:
func TestFoo(t *testing.T) {
a := assert.New(t)
tc := []struct {
desc string
foo string
}{
{
desc: "fail abc",
foo: "abc",
},
{
desc: "fail def",
foo: "def",
},
}
for _, tC := range tc {
t.Run(tC.desc, func(t *testing.T) {
tC := tC
a.Equal(tC.foo, "ghi")
})
}
}
你会得到模棱两可的失败信息:
--- FAIL: TestFoo (0.00s)
/test.go:27:
Error Trace: /test.go:27
Error: Not equal:
expected: "abc"
actual : "ghi"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-abc
+ghi
Test: TestFoo
/test.go:27:
Error Trace: /test.go:27
Error: Not equal:
expected: "def"
actual : "ghi"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-def
+ghi
Test: TestFoo
FAIL
而不是告诉你哪个子测试失败了,它们都显示父测试失败了(例如TestFoo
而不是TestFoo/fail_abc
)。如果表中有许多测试,这会使测试完全无用。
英文:
When using testify with table-driven tests as in:
func TestFoo(t *testing.T) {
a := assert.New(t)
tc := []struct {
desc string
foo string
}{
{
desc: "fail abc",
foo: "abc",
},
{
desc: "fail def",
foo: "def",
},
}
for _, tC := range tc {
t.Run(tC.desc, func(t *testing.T) {
tC := tC
a.Equal(tC.foo, "ghi")
})
}
}
Your failures will come back ambiguous:
--- FAIL: TestFoo (0.00s)
/test.go:27:
Error Trace: /test.go:27
Error: Not equal:
expected: "abc"
actual : "ghi"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-abc
+ghi
Test: TestFoo
/test.go:27:
Error Trace: /test.go:27
Error: Not equal:
expected: "def"
actual : "ghi"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-def
+ghi
Test: TestFoo
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
,所以失败将始终显示为来自父级。
重写为:
func TestFoo(t *testing.T) {
tc := []struct {
desc string
foo string
}{
{
desc: "fail abc",
foo: "abc",
},
{
desc: "fail def",
foo: "def",
},
}
for _, tC := range tc {
t.Run(tC.desc, func(t *testing.T) {
tC := tC
a := assert.New(t) // 现在在子测试中使用 *testing.T
a.Equal(tC.foo, "ghi")
})
}
}
得到了预期的易读输出(即按子测试和测试名称分解的失败):
--- FAIL: TestFoo (0.00s)
--- FAIL: TestFoo/fail_abc (0.00s)
boop_test.go:27:
Error Trace: /test.go:27
Error: Not equal:
expected: "abc"
actual : "ghi"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-abc
+ghi
Test: TestFoo/fail_abc
--- FAIL: TestFoo/fail_def (0.00s)
boop_test.go:27:
Error Trace: /test.go:27
Error: Not equal:
expected: "def"
actual : "ghi"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-def
+ghi
Test: TestFoo/fail_def
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
func TestFoo(t *testing.T) {
tc := []struct {
desc string
foo string
}{
{
desc: "fail abc",
foo: "abc",
},
{
desc: "fail def",
foo: "def",
},
}
for _, tC := range tc {
t.Run(tC.desc, func(t *testing.T) {
tC := tC
a := assert.New(t) // Now using *testing.T from within the sub-test
a.Equal(tC.foo, "ghi")
})
}
}
Gets the expected legible output (i.e. failures broken up by sub-test and test names including the description):
--- FAIL: TestFoo (0.00s)
--- FAIL: TestFoo/fail_abc (0.00s)
boop_test.go:27:
Error Trace: /test.go:27
Error: Not equal:
expected: "abc"
actual : "ghi"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-abc
+ghi
Test: TestFoo/fail_abc
--- FAIL: TestFoo/fail_def (0.00s)
boop_test.go:27:
Error Trace: /test.go:27
Error: Not equal:
expected: "def"
actual : "ghi"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-def
+ghi
Test: TestFoo/fail_def
FAIL
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论