Golang测试失败问题排查:函数返回预期结果但测试不通过
Golang测试失败问题排查:函数返回预期结果但测试不通过
package sqrt
func Sqrt(num int64) float64 {
const precision = 0.001
i := int64(1)
for ; i*i <= num; i++ {
}
result := float64(i - 1)
for ; result*result <= float64(num); result += precision {
}
return result - precision
}
package sqrt
import "testing"
var sqrtTests = []struct {
num int64
result float64
}{
{9, 3.0},
{10, 3.162},
{5, 2.236},
{97, 9.848},
{16, 4.0},
}
func TestSqrt(t *testing.T) {
for _, tt := range sqrtTests {
if got := Sqrt(tt.num); got != tt.result {
t.Errorf("got: Sqrt(%d)=%f, want: Sqrt(%d)=%f", tt.num, got, tt.num, tt.result)
}
}
}
[okumar@oshank-pc:sqrt]🎩 go test
--- FAIL: TestSqrt (0.00s)
sqrt_test.go:19: got: Sqrt(10)=3.162000, want: Sqrt(10)=3.162000
sqrt_test.go:19: got: Sqrt(5)=2.236000, want: Sqrt(5)=2.236000
sqrt_test.go:19: got: Sqrt(97)=9.848000, want: Sqrt(97)=9.848000
FAIL
exit status 1
FAIL <http://github.com/oshankfriends/go-examples/sqrt|github.com/oshankfriends/go-examples/sqrt> 0.001s
更多关于Golang测试失败问题排查:函数返回预期结果但测试不通过的实战教程也可以访问 https://www.itying.com/category-94-b0.html
3 回复
差异可能隐藏在删除的部分之后。我们不应该使用等值比较符来比较浮点数。
应该检查它们是否在目标值的允许误差范围内。
更多关于Golang测试失败问题排查:函数返回预期结果但测试不通过的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Oshank_kumar:
got != tt.result
将其替换为类似这样的函数调用:
func EqualFloat(a, b, precision float64) bool {
diff := a - b
if diff < 0.0 {
diff = -diff
}
return diff < precision
}
问题在于浮点数比较的精度问题。虽然测试输出显示的值看起来相同,但实际计算中存在微小的浮点误差,导致 != 比较失败。
在Go语言中,浮点数不应该直接使用 == 或 != 进行比较,而应该使用误差容忍度进行比较。以下是修复后的测试代码:
package sqrt
import (
"math"
"testing"
)
var sqrtTests = []struct {
num int64
result float64
}{
{9, 3.0},
{10, 3.162},
{5, 2.236},
{97, 9.848},
{16, 4.0},
}
func TestSqrt(t *testing.T) {
const epsilon = 0.001 // 设置误差容忍度
for _, tt := range sqrtTests {
got := Sqrt(tt.num)
diff := math.Abs(got - tt.result)
if diff > epsilon {
t.Errorf("got: Sqrt(%d)=%f, want: Sqrt(%d)=%f, diff=%f",
tt.num, got, tt.num, tt.result, diff)
}
}
}
另外,你的 Sqrt 函数实现也有精度问题。这里是一个改进版本:
func Sqrt(num int64) float64 {
const precision = 0.001
// 整数部分
i := int64(1)
for ; i*i <= num; i++ {
}
result := float64(i - 1)
// 小数部分
for ; result*result <= float64(num); result += precision {
}
// 返回时减去最后一次的增量
return result - precision
}
测试失败的具体原因是:虽然输出看起来是 3.162000,但实际计算值可能是 3.162000000000001 或类似的微小差异,导致直接相等比较失败。使用误差容忍度比较可以正确处理这种情况。

