golang数据库测试辅助工具插件库testfixtures的使用
Golang数据库测试辅助工具插件库testfixtures的使用
testfixtures是一个用于简化Golang数据库应用功能测试的工具库,它模仿了Ruby on Rails的测试数据库方式。
警告
这个包会在加载fixtures前清空数据库数据!它应该只用于测试数据库。请仔细确认你是在正确的数据库上运行它。
安装
首先导入包:
import (
"github.com/go-testfixtures/testfixtures/v3"
)
使用方式
创建fixture文件
创建一个文件夹存放fixture文件,每个文件对应一个表,命名为<表名>.yml
:
myapp/
myapp.go
myapp_test.go
...
fixtures/
posts.yml
comments.yml
tags.yml
posts_tags.yml
...
fixture文件内容示例:
# comments.yml
- id: 1
post_id: 1
content: A comment...
author_name: John Doe
author_email: john@doe.com
created_at: 2020-12-31 23:59:59
updated_at: 2020-12-31 23:59:59
- id: 2
post_id: 2
content: Another comment...
author_name: John Doe
author_email: john@doe.com
created_at: 2020-12-31 23:59:59
updated_at: 2020-12-31 23:59:59
测试代码示例
package myapp
import (
"database/sql"
"testing"
_ "github.com/lib/pq"
"github.com/go-testfixtures/testfixtures/v3"
)
var (
db *sql.DB
fixtures *testfixtures.Loader
)
func TestMain(m *testing.M) {
var err error
// 打开测试数据库连接
// 不要在正式数据库中使用fixtures!
// 现有数据会被删除
db, err = sql.Open("postgres", "dbname=myapp_test")
if err != nil {
...
}
fixtures, err = testfixtures.New(
testfixtures.Database(db), // 数据库连接
testfixtures.Dialect("postgres"), // 支持:"postgresql", "timescaledb", "mysql", "mariadb", "sqlite"和"sqlserver"
testfixtures.Directory("testdata/fixtures"), // 包含YAML文件的目录
)
if err != nil {
...
}
os.Exit(m.Run())
}
func prepareTestDatabase() {
if err := fixtures.Load(); err != nil {
...
}
}
func TestX(t *testing.T) {
prepareTestDatabase()
// 你的测试代码...
}
func TestY(t *testing.T) {
prepareTestDatabase()
// 你的测试代码...
}
func TestZ(t *testing.T) {
prepareTestDatabase()
// 你的测试代码...
}
其他加载方式
可以使用Files
选项指定要加载的文件:
fixtures, err := testfixtures.New(
testfixtures.Database(db),
testfixtures.Dialect("postgres"),
testfixtures.Files(
"fixtures/orders.yml",
"fixtures/customers.yml",
),
)
或者使用Paths
选项指定路径:
fixtures, err := testfixtures.New(
testfixtures.Database(db),
testfixtures.Dialect("postgres"),
testfixtures.Paths(
"fixtures/orders.yml",
"fixtures/customers.yml",
"common_fixtures/users"
),
)
单个文件包含多个表
使用FilesMultiTables
选项可以在单个文件中定义多个表的数据:
fixtures, err := testfixtures.New(
testfixtures.Database(db),
testfixtures.Dialect("postgres"),
testfixtures.FilesMultiTables(
"fixtures/test_case1.yml",
"fixtures/test_case2.yml",
"fixtures/posts_comments.yml",
),
)
多表文件示例:
# test_case1.yml
posts:
- id: 1
post_id: 1
content: A comment...
author_name: John Doe
author_email: john@doe.com
created_at: 2020-12-31 23:59:59
updated_at: 2020-12-31 23:59:59
comments:
- id: 1
post_id: 1
content: Post 1 comment 1
author_name: John Doe
author_email: john@doe.com
created_at: 2016-01-01 12:30:12
updated_at: 2016-01-01 12:30:12
高级功能
安全检查和跳过
testfixtures.New(
...
testfixtures.DangerousSkipTestDatabaseCheck(),
)
禁用清理
testfixtures.New(
...
testfixtures.DangerousSkipCleanupFixtureTables(),
)
序列重置
testfixtures.New(
...
testfixtures.ResetSequencesTo(10000),
)
模板支持
testfixtures.New(
...
testfixtures.Template(),
testfixtures.TemplateFuncs(...),
testfixtures.TemplateDelims("{{", "}}"),
testfixtures.TemplateOptions("missingkey=zero"),
testfixtures.TemplateData(...),
)
从现有数据库生成fixtures
dumper, err := testfixtures.NewDumper(
testfixtures.DumpDatabase(db),
testfixtures.DumpDialect("postgres"), // 或你选择的数据库
testfixtures.DumpDirectory("tmp/fixtures"),
testfixtures.DumpTables( // 可选,不指定则导出所有表
"posts",
"comments",
"tags",
),
)
if err != nil {
...
}
if err := dumper.Dump(); err != nil {
...
}
注意事项
并行测试
这个库还不支持并行测试!并行测试可能导致数据库中出现随机数据,这可能会导致测试随机/间歇性失败。
替代方案
如果你认为使用fixtures不是一个好主意,可以尝试以下替代方案:
- factory-go: Go的工厂模式实现
- fixtory: 基于go generate的类型安全测试fixture工厂
- go-txdb: 为每个功能测试使用单一数据库事务
- go-sqlmock: sql.DB接口的mock实现
- dbcleaner: 测试数据库清理工具
更多关于golang数据库测试辅助工具插件库testfixtures的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang数据库测试辅助工具插件库testfixtures的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 数据库测试辅助工具 testfixtures 使用指南
testfixtures 是一个用于 Golang 数据库测试的辅助工具库,它可以帮助你在测试前将数据库置于已知状态,确保测试的一致性。
安装
go get github.com/go-testfixtures/testfixtures/v3
基本使用
1. 准备工作
首先,准备你的测试数据文件。testfixtures 支持 YAML 或 JSON 格式的文件,通常存放在 testdata/fixtures
目录下。
示例 YAML 文件 (users.yml
):
users:
- id: 1
name: "John Doe"
email: "john@example.com"
created_at: "2020-01-01 00:00:00"
- id: 2
name: "Jane Smith"
email: "jane@example.com"
created_at: "2020-01-02 00:00:00"
2. 初始化 testfixtures
package main_test
import (
"database/sql"
"log"
"path/filepath"
"testing"
_ "github.com/go-sql-driver/mysql"
"github.com/go-testfixtures/testfixtures/v3"
)
var (
db *sql.DB
fixtures *testfixtures.Loader
)
func TestMain(m *testing.M) {
var err error
// 1. 初始化数据库连接
db, err = sql.Open("mysql", "user:password@tcp(localhost:3306)/testdb?parseTime=true")
if err != nil {
log.Fatalf("Error opening database: %v", err)
}
// 2. 准备 fixtures 加载器
fixtures, err = testfixtures.New(
testfixtures.Database(db), // 数据库连接
testfixtures.Dialect("mysql"), // 数据库方言
testfixtures.Directory(filepath.Join("testdata", "fixtures")), // fixtures 目录
if err != nil {
log.Fatalf("Error creating fixtures: %v", err)
}
// 运行测试
m.Run()
}
3. 在测试中使用
func TestUserCount(t *testing.T) {
// 加载 fixtures
if err := fixtures.Load(); err != nil {
t.Fatalf("Error loading fixtures: %v", err)
}
// 执行测试查询
var count int
err := db.QueryRow("SELECT COUNT(*) FROM users").Scan(&count)
if err != nil {
t.Fatalf("Error querying user count: %v", err)
}
// 验证结果
if count != 2 {
t.Errorf("Expected 2 users, got %d", count)
}
}
高级功能
1. 跳过重置表
fixtures, err = testfixtures.New(
testfixtures.Database(db),
testfixtures.Dialect("mysql"),
testfixtures.Directory("testdata/fixtures"),
testfixtures.SkipResetTables(), // 跳过表重置
)
2. 使用模板变量
fixtures 文件支持模板变量:
users:
- id: 1
name: "{{.UserName}}"
email: "{{.UserEmail}}"
在代码中设置变量:
fixtures, err = testfixtures.New(
// ...其他选项...
testfixtures.Template(),
testfixtures.TemplateData(map[string]interface{}{
"UserName": "Test User",
"UserEmail": "test@example.com",
}),
)
3. 使用自定义函数
func myCustomFunc() string {
return "custom_value"
}
fixtures, err = testfixtures.New(
// ...其他选项...
testfixtures.Template(),
testfixtures.TemplateFuncs(template.FuncMap{
"myCustomFunc": myCustomFunc,
}),
)
然后在 YAML 中使用:
users:
- id: 1
custom_field: "{{myCustomFunc}}"
4. 只加载特定文件
fixtures, err = testfixtures.New(
// ...其他选项...
testfixtures.Files("users.yml", "products.yml"),
)
支持的数据库
testfixtures 支持多种数据库:
- PostgreSQL
- MySQL
- SQLite
- Microsoft SQL Server
- Oracle
注意事项
- 确保测试数据库与生产数据库分开
- 测试完成后可以考虑回滚事务或清理数据库
- 对于大型测试数据集,考虑使用事务来加速测试
testfixtures 是一个强大的工具,可以显著简化数据库测试的设置工作,确保每次测试都在一致的数据状态下运行。