Go 语言测试:单元测试、集成测试、端到端测试从入门到精通

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么在 Go 中进行测试是必要的?

\n

Go (Golang) 是一种用于构建可靠且可扩展系统的现代编程语言。然而,即使是最优雅的代码也无法避免错误。因此,测试是 Go 开发中不可或缺的一部分。内置的 testing 包为编写单元测试、集成测试甚至端到端 (e2e) 检查提供了强大的工具。

\n

在本文中,我们将介绍 Go 中所有级别的测试:从简单的单元测试到复杂的端到端场景。您将学习如何正确组织测试、使用 mock、编写表驱动测试以及使用真实依赖项配置集成测试。本材料对新手和有经验的开发者都很有用,有助于系统化知识。

\n\n

1. Go 中的单元测试:基础中的基础

\n

单元测试在隔离外部依赖的情况下检查单个函数或方法的工作。在 Go 中,使用标准包 testing 来实现。基本规则:测试文件应命名为 *_test.go,测试函数应以 Test 开头。

\n\n

1.1. 简单的单元测试

\n

考虑一个两个数相加的函数:

\n
// math.go\npackage math\n\nfunc Add(a, b int) int {\n    return a + b\n}
\n

它的测试:

\n
// math_test.go\npackage math\n\nimport "testing"\n\nfunc TestAdd(t *testing.T) {\n    result := Add(2, 3)\n    expected := 5\n    if result != expected {\n        t.Errorf("Add(2, 3) = %d; want %d", result, expected)\n    }\n}
\n

运行测试:go test ./... 或 go test -v 以获取详细输出。

\n\n

1.2. 表驱动测试

\n

Go 社区广泛使用表驱动方法来测试多个用例:

\n
func TestAddTableDriven(t *testing.T) {\n    tests := []struct {\n        name string\n        a, b int\n        want int\n    }{\n        {"positive", 2, 3, 5},\n        {"negative", -1, -2, -3},\n        {"zero", 0, 0, 0},\n    }\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            if got := Add(tt.a, tt.b); got != tt.want {\n                t.Errorf("Add() = %d, want %d", got, tt.want)\n            }\n        })\n    }\n}
\n

这种方法使测试易于阅读和扩展。

\n\n

1.3. 错误测试

\n

对于返回错误的函数,使用 t.Fatal 或 t.Errorf:

\n
func TestDivide(t *testing.T) {\n    _, err := Divide(10, 0)\n    if err == nil {\n        t.Fatal("expected error for division by zero")\n    }\n}
\n\n

2. 集成测试:处理依赖项

\n

集成测试检查组件之间的交互:数据库、API、文件系统。在 Go 中,通常使用构建标签或单独的包结构将它们与单元测试分开。

\n\n

2.1. 使用构建标签

\n

在文件开头使用标签 //go:build integration 创建文件:

\n
//go:build integration\n\npackage db\n\nimport (\n    "testing"\n    "database/sql"\n    _ "github.com/lib/pq"\n)\n\nfunc TestPostgresConnection(t *testing.T) {\n    dsn := "host=localhost port=5432 user=test password=test dbname=test sslmode=disable"\n    db, err := sql.Open("postgres", dsn)\n    if err != nil {\n        t.Fatalf("failed to open db: %v", err)\n    }\n    defer db.Close()\n    \n    if err := db.Ping(); err != nil {\n        t.Fatalf("failed to ping db: %v", err)\n    }\n}
\n

仅运行集成测试:go test -tags=integration ./...

\n\n

2.2. Mock 和桩

\n

为了隔离测试,使用接口和 mock。以流行的库 gomock 为例:

\n
// user.go\ntype UserRepository interface {\n    GetUser(id int) (*Us                

博客

书籍推荐