题目
实现并测试带边界条件的字符串反转函数
信息
- 类型:问答
- 难度:⭐⭐
考点
表格驱动测试, 边界条件处理, 子测试使用, 测试覆盖率
快速回答
本题需要实现字符串反转函数并编写表格驱动测试:
- 定义包含输入/预期输出的测试用例结构体切片
- 使用
t.Run()为每个用例创建子测试 - 覆盖空字符串、Unicode字符、数字等边界条件
- 处理panic场景时使用
recover() - 通过
go test -cover验证测试覆盖率
问题背景
在Go测试中,表格驱动测试是核心实践方法。本题要求实现字符串反转函数并编写测试,重点考察:
- 表格驱动测试的组织结构
- 边界条件的全面覆盖
- 子测试的合理使用
- 异常场景的处理能力
解决方案
1. 实现反转函数
// reverse.go
package main
func Reverse(s string) string {
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}关键点:
- 使用
[]rune处理Unicode字符 - 双指针原地交换提高效率
2. 表格驱动测试实现
// reverse_test.go
package main
import (
"testing"
)
func TestReverse(t *testing.T) {
tests := []struct {
name string
input string
want string
wantErr bool
}{
{"English", "hello", "olleh", false},
{"Chinese", "你好世界", "界世好你", false},
{"Empty", "", "", false},
{"Numbers", "12345", "54321", false},
{"Space", "a b c", "c b a", false},
{"Surrogate", "\uD800\uDC00", "\uD800\uDC00", false}, // Unicode代理对
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Reverse(tt.input)
if got != tt.want {
t.Errorf("Reverse(%q) = %q, want %q", tt.input, got, tt.want)
}
})
}
}3. 边界条件处理
- 空字符串:单独测试用例防止越界
- Unicode字符:使用
[]rune而非[]byte - 特殊字符:测试空格、数字等场景
- 异常场景:如需panic测试:
defer func() { if r := recover(); r == nil && tt.wantPanic { t.Error("Expected panic did not occur") } }()
最佳实践
- 表格结构:包含name/input/want/wantErr字段
- 子测试命名:
t.Run()使用描述性名称 - 覆盖率:通过
go test -cover确保100%覆盖 - 错误信息:使用
t.Errorf输出详细错误上下文
常见错误
- 字节切片处理中文:
[]byte("中文")导致乱码 - 边界遗漏:忘记测试空字符串或单字符
- 子测试未命名:直接循环执行导致测试报告不清晰
- 未处理panic:未对可能panic的场景进行恢复
扩展知识
- Golden Files:复杂输出可使用
testdata保存预期结果 - 并行测试:在
t.Run()内调用t.Parallel() - 性能测试:结合
testing.B进行基准测试 - 测试辅助函数:通过
t.Helper()标记帮助函数