英文:
go - golang test parameterized
问题
在Go语言中,你可以使用测试表格(test table)的方式来实现类似的功能,而无需自己编写循环。下面是相应的Go代码:
func tutu(a int) int {
return a + 1
}
func Test_tutu(t *testing.T) {
tests := []struct {
input int
expected int
}{
{input: 1, expected: 2},
{input: 2, expected: 3},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
assert.Equal(t, tutu(tt.input), tt.expected)
})
}
}
这段代码使用了一个结构体切片来定义测试用例,每个测试用例包含一个输入值和一个期望的输出值。然后,通过遍历测试用例切片,在每次循环中使用t.Run
函数来执行单个测试,并使用断言函数assert.Equal
来验证结果。
希望对你有所帮助!如果还有其他问题,请随时提问。
英文:
In python I can easily do
@pytest.mark.parametrize('input, expected', [(1, 2), [2, 3]])
def test_tutu(input, expected):
assert input + 1 == expected
How can I do the same in golang ? without writting myself a loop
func tutu(a int) int {
return a + 1
}
func Test_tutu(t *testing.T) {
tests := []struct {
input int
expected int
}{
{input: 1, expected: 2},
{input: 2, expected: 3},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
assert.Equal(t, tutu(tt.input), tt.expected)
})
}
}
So what would be the equivalent of this python parametrize in golang ?
def parametrize(all_args_name: str, all_values: List[Any], fn: Callable):
args_name = all_args_name.split(',')
for values in all_values:
args = {k: v for k, v in zip(args_name, values)}
fn(**args)
答案1
得分: 0
最接近GO的功能是subtests,但你仍然需要编写for
循环,就像你在第二个示例中已经做的那样。
英文:
The closest thing GO has is subtests, but you would still need to write the for
loop, like you already did in the second example.
答案2
得分: 0
我找到了一种使用反射的方法。
func parametrize[V any, T any](fn T, allValues [][]V) {
v := reflect.ValueOf(fn)
for _, a := range allValues {
vargs := make([]reflect.Value, len(a))
for i, b := range a {
vargs[i] = reflect.ValueOf(b)
}
v.Call(vargs)
}
}
func tutu(a int) int {
return a + 1
}
func Test_tutu(t *testing.T) {
testsArgs := [][]any{
{t, 1, 2}, {t, 3, 4},
}
test := func(t *testing.T, input int, expected int) {
assert.Equal(t, tutu(input), expected)
}
parametrize(test, testsArgs)
}
这段代码使用了反射来实现一个参数化测试的功能。parametrize
函数接受一个函数 fn
和一个二维切片 allValues
,其中 fn
是一个泛型函数,allValues
是一个包含多组参数的切片。在函数内部,通过反射获取 fn
的值,并遍历 allValues
中的每一组参数。然后,使用反射将参数转换为 reflect.Value
类型,并调用 v.Call(vargs)
来执行函数。
在示例代码中,tutu
函数是一个简单的示例函数,它接受一个整数参数并返回参数加一的结果。Test_tutu
函数是一个测试函数,它使用 parametrize
函数来对 tutu
函数进行参数化测试。testsArgs
是一个包含多组测试参数的切片,每一组参数都是一个切片,第一个元素是 t
(测试对象),后面的元素是输入参数。test
函数是一个测试辅助函数,它接受 t
、输入参数和期望结果,并使用 assert.Equal
来进行断言判断。
通过使用 parametrize
函数,可以方便地对函数进行参数化测试,减少了重复编写测试代码的工作量。
英文:
I found a way using reflect
func parametrize[V any, T any](fn T, allValues [][]V) {
v := reflect.ValueOf(fn)
for _, a := range allValues {
vargs := make([]reflect.Value, len(a))
for i, b := range a {
vargs[i] = reflect.ValueOf(b)
}
v.Call(vargs)
}
}
func tutu(a int) int {
return a + 1
}
func Test_tutu(t *testing.T) {
testsArgs := [][]any{
{t, 1, 2}, {t, 3, 4},
}
test := func(t *testing.T, input int, expected int) {
assert.Equal(t, tutu(input), expected)
}
parametrize(test, testsArgs)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论