在Python中我可以轻松做到
@pytest.mark.parametrize('input, expected', [(1, 2), [2, 3]])
def test_tutu(input, expected):
assert input + 1 == expected
我如何在 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)
})
}
}
那么 Go 中的 Python 参数化相当于什么?
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)
我找到了一种使用反射的方法
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)
}
GO 最接近的是 subtests,但您仍然需要编写
for
循环,就像您在第二个示例中所做的那样。