go断言实用函数的行为类似于非阻塞操作。

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

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
英文:

go断言实用函数的行为类似于非阻塞操作。
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)

huangapple
  • 本文由 发表于 2022年7月4日 09:13:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/72850921.html
匿名

发表评论

匿名网友

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

确定