testing.T提供Error/ Fatal等错误报告方法,区别在于Error非致命可继续执行,Fatal则立即终止测试;通过t.Run创建子测试实现结构化测试,t.Parallel支持并行执行提升效率。

在Go语言的测试世界里,
testing.T
testing.T
testing.T
假设我们有一个简单的数学库,包含加法和除法函数:
package mymath
import (
"fmt"
"time"
)
// Add performs addition of two integers.
func Add(a, b int) int {
return a + b
}
// Divide performs division of two integers.
// It returns an error if the divisor is zero.
func Divide(a, b int) (int, error) {
if b == 0 {
return 0, fmt.Errorf("division by zero is not allowed")
}
return a / b, nil
}
// SomeComplexOperation simulates a time-consuming operation
func SomeComplexOperation() string {
time.Sleep(50 * time.Millisecond) // Simulate work
return "complex result"
}现在,我们来看如何使用
testing.T
立即学习“go语言免费学习笔记(深入)”;
package mymath_test
import (
"mymath" // Assuming mymath package is in the same module
"testing"
"time"
)
// TestArithmeticOperations 是一个主测试函数,它将包含多个子测试。
func TestArithmeticOperations(t *testing.T) {
// 使用 t.Run() 创建子测试,使得测试结构更清晰,报告更细致。
t.Run("TestAddFunction", func(t *testing.T) {
// t.Logf 用于在测试通过时输出调试信息,或者在测试失败时提供更多上下文。
t.Log("Starting TestAddFunction...")
result := mymath.Add(1, 2)
expected := 3
if result != expected {
// t.Errorf() 报告一个非致命错误。测试会继续执行。
t.Errorf("Add(1, 2) = %d; want %d", result, expected)
}
result = mymath.Add(-5, 10)
expected = 5
if result != expected {
// 即使前面有错误,这个断言也会被执行。
t.Errorf("Add(-5, 10) = %d; want %d", result, expected)
}
t.Log("TestAddFunction finished.")
})
t.Run("TestDivideFunction", func(t *testing.T) {
// t.Cleanup() 确保在当前测试(或子测试)结束后执行清理操作,无论测试通过还是失败。
t.Cleanup(func() {
t.Log("Cleaning up resources for TestDivideFunction.")
// 模拟关闭数据库连接、删除临时文件等操作
// time.Sleep(10 * time.Millisecond)
})
// 测试正常除法
t.Run("ValidDivision", func(t *testing.T) {
result, err := mymath.Divide(10, 2)
if err != nil {
// t.Fatalf() 报告一个致命错误,并立即停止当前子测试的执行。
t.Fatalf("Divide(10, 2) returned an unexpected error: %v", err)
}
if result != 5 {
t.Errorf("Divide(10, 2) = %d; want 5", result)
}
})
// 测试除以零的情况
t.Run("DivideByZero", func(t *testing.T) {
_, err := mymath.Divide(10, 0)
if err == nil {
// t.Fatal() 报告一个致命错误,并立即停止当前子测试的执行。
t.Fatal("Divide(10, 0) did not return an error; want error")
}
expectedError := "division by zero is not allowed"
if err.Error() != expectedError {
t.Errorf("Divide(10, 0) returned unexpected error message: %q; want %q", err.Error(), expectedError)
}
t.Logf("DivideByZero test successfully caught error: %q", err.Error())
})
// 使用 t.Skip() 跳过某些测试
t.Run("SkippedTestExample", func(t *testing.T) {
if testing.Short() { // 当使用 'go test -short' 运行时跳过
t.Skip("Skipping SkippedTestExample in short mode.")
}
// 模拟一个耗时操作,通常只在完整测试中运行
time.Sleep(200 * time.Millisecond)
t.Log("SkippedTestExample completed (should not run in short mode).")
})
// 演示并行测试
t.Run("ParallelTests", func(t *testing.T) {
testCases := []struct {
name string
a, b int
expected int
hasError bool
}{
{"PositiveDiv", 10, 2, 5, false},
{"NegativeDiv", -10, 2, -5, false},
{"LargeDiv", 1000, 10, 100, false},
{"AnotherDivByZero", 5, 0, 0, true}, // 这个应该报错
}
for _, tc := range testCases {
tc := tc // 关键:在并行测试中捕获循环变量
t.Run(tc.name, func(t *testing.T) {
t.Parallel() // 标记这个子测试可以与其他并行子测试并发运行
// 模拟一些计算耗时
time.Sleep(time.Duration(tc.a) * time.Millisecond / 5)
result, err := mymath.Divide(tc.a, tc.b)
if (err != nil) != tc.hasError {
t.Errorf("%s: unexpected error status; got error %v, want hasError %v", tc.name, err, tc.hasError)
}
if !tc.hasError && result != tc.expected {
t.Errorf("%s: Divide(%d, %d) = %d; want %d", tc.name, tc.a, tc.b, result, tc.expected)
}
t.Logf("%s finished with result: %d, error: %v", tc.name, result, err)
})
}
})
})
}
// 辅助函数示例:简化测试中的重复断言逻辑
func assertEqual(t *testing.T, actual, expected interface{}, msg string) {
t.Helper() // 标记此函数为测试辅助函数
if actual != expected {
t.Errorf("%s: got %v, want %v", msg, actual, expected)
}
}
func TestHelperFunctionUsage(t *testing.T) {
assertEqual(t, mymath.Add(1, 1), 2, "Add(1,1) result")
assertEqual(t, mymath.Add(5, 5), 10, "Add(5,5) result")
assertEqual(t, mymath.Add(0, 0), 0, "Add(0,0) result")
// 故意制造一个失败,看看 t.Helper() 的效果
assertEqual(t, mymath.Add(1, 2), 4, "Add(1,2) result should fail")
}testing.T
在Go语言的测试中,
testing.T
Error
Fatal
t.Error(args ...interface{})t.Errorf(format string, args ...interface{})
t.Errorf
fmt.Printf
t.Error
t.Errorf
t.Fail()
t.Log
t.Error
t.FailNow()
本文档讲述在Android2.1上完全自已开发一个驱动去控制硬件口并写应用测试该驱动,通过这样一个例子,解析android下的驱动开发流程的应用调用流程,可以说是很好的入门引导 要达到的效果:通过Android的应用,调用驱动程序,在开发板上控制4个LED的亮灭。感兴趣的朋友可以过来看看
0
t.FailNow()
t.Cleanup
t.Fatal(args ...interface{})t.Fatalf(format string, args ...interface{})
t.FailNow()
t.Fatalf
t.Errorf
t.FailNow
选择哪个方法,很大程度上取决于你对测试失败的容忍度以及你希望测试报告提供的信息粒度。我个人觉得,对于单元测试中的核心断言,
t.Fatal
t.Error
testing.T
在Go的测试框架中,
t.Run()
t.Parallel()
子测试(Subtests)与t.Run()
t.Run(name string, f func(t *T))
*testing.T
TestXxx
t.Run
TestUserManagement/CreateUserSuccess
TestUserManagement/CreateUserInvalidEmail
go test -run 'TestMainFunction/SubtestName'
*testing.T
t.Fatal
t.FailNow
我发现,
t.Run
t.Run
**并行测试(Parallel Tests)与`t
以上就是Golang使用testing.T控制测试流程实例的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号