英文:
go assertion utility functions behave like non-blocking operation
问题
我预期每个断言都是一个阻塞操作,并且一旦检测到失败,测试就会停止。但事实并非如此。
如何让go工具能够预测即将发生的失败并通知我?据我所知,断言的方法都是阻塞的,不应该发生这种情况。我有什么遗漏吗?
❯ go test -run Test_Assert . -v
=== RUN Test_Assert
config_test.go:136:
Error Trace: config_test.go:136
Error: 应该为true
Test: Test_Assert
config_test.go:138:
Error Trace: config_test.go:138
Error: 应该为true
Test: Test_Assert
--- FAIL: Test_Assert (0.00s)
FAIL
FAIL github.com/hazelcast/hazelcast-go-client 0.178s
FAIL
英文:
I expected that each assertion is a blocking operation and test would stop at a point as soon as it detects a failure. But it didn't happened.
How go tool can smell upcoming failures and inform me ? AFAIK, assertion's methods are all blocking, it shouldn't have been happened. Am I missing something ?
❯ go test -run Test_Assert . -v
=== RUN Test_Assert
config_test.go:136:
Error Trace: config_test.go:136
Error: Should be true
Test: Test_Assert
config_test.go:138:
Error Trace: config_test.go:138
Error: Should be true
Test: Test_Assert
--- FAIL: Test_Assert (0.00s)
FAIL
FAIL github.com/hazelcast/hazelcast-go-client 0.178s
FAIL
答案1
得分: 2
假设你在谈论的是 stretchr/testify 中的 assert
函数(https://pkg.go.dev/github.com/stretchr/testify/assert),请注意,assert.True
仅验证某个条件是否为真,如果不是,则调用 t.Errorf
。根据 testing 文档 的说法:
标记函数执行失败,但继续执行。
这与 t.FailNow
不同,t.FailNow
的作用是:
标记函数执行失败,并通过调用 runtime.Goexit 来停止其执行(然后在当前 goroutine 中运行所有延迟调用)。执行将继续进行下一个测试或基准测试。FailNow 必须从运行测试或基准测试函数的 goroutine 中调用,而不是从测试期间创建的其他 goroutine 中调用。调用 FailNow 不会停止这些其他 goroutine 的执行。
(在 testify 包中,还有一系列的 require 函数,它们与 assert
做的事情相同,但在失败时使用 t.FailNow
。这样,你可以调用 require.True
来停止后续的测试。)
顺便说一下,在这里使用 blocking 这个词是不正确的。testing
包运行的每个测试都在一个 goroutine 中,完成(或中止)整个测试是通过完成(或提前退出)goroutine 来实现的,但你提到的函数都是同步(“阻塞”)的 函数调用。
英文:
Assuming you're talking about the assert
functions in stretchr/testify (https://pkg.go.dev/github.com/stretchr/testify/assert), note that assert.True
simply verifies whether something is true and if not, calls t.Errorf
. As the testing
documentation says, this:
> marks the function as having failed but continues execution.
This differs from t.FailNow
, which:
> marks the function as having failed and stops its execution by calling runtime.Goexit (which then runs all deferred calls in the current goroutine). Execution will continue at the next test or benchmark. FailNow must be called from the goroutine running the test or benchmark function, not from other goroutines created during the test. Calling FailNow does not stop those other goroutines.
(In the testify package, there's a require series of functions that do the same thing as assert
but use t.FailNow
when they fail. This lets you invoke require.True
to stop further tests.)
As an aside, the word blocking is the wrong one to use here. Each test run by the testing
package is in a goroutine and finishing (or aborting) the entire test is done by finishing (or exiting early from) the goroutine, but the functions you mention are all synchronous ("blocking") function calls.
答案2
得分: 0
为了在第一个失败的位置停止当前测试,可以使用另一个伴侣包:https://pkg.go.dev/github.com/stretchr/testify/require
require.True(t, reflect.DeepEqual("A", "A"))
require.True(t, reflect.DeepEqual("B", "B"))
...
另外,stretchr/testify
模块还提供了 .Equal(...)
和 .EqualValues(...)
函数:
assert.Equal(t, "A", "A")
require.Equal(t, "B", "B")
expected := "A"
got := executeMyFunc()
assert.Equal(t, expected, got)
require.Equal(t, expected, got)
// 或者
assert.EqualValues(t, expected, got)
require.EqualValues(t, expected, got)
英文:
In order to have a set of utility functions which stop the current test at the first failing site, use the other companion package : https://pkg.go.dev/github.com/stretchr/testify/require
require.True(t, reflect.DeepEqual("A", "A"))
require.True(t, reflect.DeepEqual("B", "B"))
...
as a side note, the stretchr/testify
module also provides the .Equal(...)
and .EqualValues(...)
functions :
assert.Equal(t, "A", "A")
require.Equal(t, "B", "B")
expected := "A"
got := executeMyFunc()
assert.Equal(t, expected, got)
require.Equal(t, expected, got)
# or
assert.EqualValues(t, expected, got)
require.EqualValues(t, expected, got)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论