golang测试数据库清理工具插件库dbcleaner的使用
Golang测试数据库清理工具插件库dbcleaner的使用
基本介绍
DbCleaner是一个用于测试时清理数据库的Golang库,灵感来源于Ruby的database_cleaner。它使用flock系统调用确保测试可以并行运行而不会出现竞争问题。
安装
要获取该包,执行以下命令:
go get gopkg.in/khaiql/dbcleaner.v2
导入该包:
import "gopkg.in/khaiql/dbcleaner.v2"
基本用法
与testify的suite一起使用
import (
"testing"
"gopkg.in/khaiql/dbcleaner.v2"
"gopkg.in/khaiql/dbcleaner.v2/engine"
"github.com/stretchr/testify/suite"
)
var Cleaner = dbcleaner.New()
type ExampleSuite struct {
suite.Suite
}
func (suite *ExampleSuite) SetupSuite() {
// 初始化并设置mysql清理引擎
mysql := engine.NewMySQLEngine("YOUR_DB_DSN")
Cleaner.SetEngine(mysql)
}
func (suite *ExampleSuite) SetupTest() {
// 在测试开始前获取表锁
Cleaner.Acquire("users")
}
func (suite *ExampleSuite) TearDownTest() {
// 测试结束后清理表数据
Cleaner.Clean("users")
}
func (suite *ExampleSuite) TestSomething() {
// 编写实际测试
suite.Equal(true, true)
}
func TestRunSuite(t *testing.T) {
suite.Run(t, new(ExampleSuite))
}
配置选项
DbCleaner提供了多种配置选项来处理可能出现的死锁问题:
type Options struct {
Logger logging.Logger
LockTimeout time.Duration
NumberOfRetry int
RetryInterval time.Duration
}
type Option func(opt *Options)
// SetLogger 设置日志记录器实例,默认为Noop
func SetLogger(logger logging.Logger) Option {
return func(opt *Options) {
opt.Logger = logger
}
}
// SetLockTimeout 设置锁定操作的超时时间,默认为10秒
func SetLockTimeout(d time.Duration) Option {
return func(opt *Options) {
opt.LockTimeout = d
}
}
// SetNumberOfRetry 设置获取表的最大重试次数,默认为5次
func SetNumberOfRetry(t int) Option {
return func(opt *Options) {
opt.NumberOfRetry = t
}
}
// SetRetryInterval 设置每次重试之间的休眠时间,默认为10秒
func SetRetryInterval(d time.Duration) Option {
return func(opt *Options) {
opt.RetryInterval = d
}
}
// 使用自定义配置创建Cleaner实例
cleaner := dbcleaner.New(SetNumberOfRetry(10), SetLockTimeout(5*time.Second))
支持的数据库驱动
- postgres
- mysql
- sqlite3
为其他驱动编写清理器
基本上所有被database/sql
包支持的驱动也都被dbcleaner
支持。对于自定义驱动,实现你自己的engine.Engine
接口并在dbcleaner.Cleaner
实例上调用SetEngine
方法。
许可证
MIT
更多关于golang测试数据库清理工具插件库dbcleaner的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang测试数据库清理工具插件库dbcleaner的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang 数据库清理工具 dbcleaner 使用指南
dbcleaner
是一个用于在测试期间清理数据库的 Go 库,它可以帮助你在测试之间保持数据库的干净状态。下面我将详细介绍如何使用这个工具。
安装
首先安装 dbcleaner 包:
go get github.com/khaiql/dbcleaner
基本使用
1. 初始化 dbcleaner
import (
"github.com/khaiql/dbcleaner"
"github.com/khaiql/dbcleaner/helper/mysql"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
cleaner := dbcleaner.New()
// 设置 MySQL 连接
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/test_db?parseTime=true")
if err != nil {
panic(err)
}
// 添加 MySQL 数据库到 cleaner
cleaner.SetEngine(mysql.Engine(db))
}
2. 在测试中使用
func TestSomething(t *testing.T) {
cleaner := dbcleaner.New()
db, _ := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/test_db?parseTime=true")
cleaner.SetEngine(mysql.Engine(db))
// 在测试开始时获取锁
cleaner.Acquire("users", "products")
defer cleaner.Clean("users", "products") // 在测试结束时清理
// 执行测试...
_, err := db.Exec("INSERT INTO users (name) VALUES (?)", "John Doe")
if err != nil {
t.Fatal(err)
}
// 测试结束后,cleaner.Clean 会自动清理 users 和 products 表
}
高级用法
1. 排除某些表不被清理
cleaner := dbcleaner.New()
cleaner.SetEngine(mysql.Engine(db))
// 设置不清理的表
cleaner.SetIgnoreTables("migrations", "system_settings")
// 只清理指定的表
cleaner.Acquire("users")
defer cleaner.Clean("users")
2. 使用 PostgreSQL
import (
"github.com/khaiql/dbcleaner/helper/postgres"
_ "github.com/lib/pq"
)
func TestPostgres(t *testing.T) {
cleaner := dbcleaner.New()
db, _ := sql.Open("postgres", "user=postgres dbname=test_db sslmode=disable")
cleaner.SetEngine(postgres.Engine(db))
cleaner.Acquire("users")
defer cleaner.Clean("users")
// 测试代码...
}
3. 自定义清理策略
cleaner := dbcleaner.New()
cleaner.SetEngine(mysql.Engine(db))
// 设置自定义的清理函数
cleaner.SetTableTruncateFunc("audit_logs", func(tableName string, db *sql.DB) error {
// 只删除最近3天的记录,而不是清空整个表
_, err := db.Exec("DELETE FROM audit_logs WHERE created_at < NOW() - INTERVAL 3 DAY")
return err
})
cleaner.Acquire("audit_logs")
defer cleaner.Clean("audit_logs")
最佳实践
- 在测试套件初始化时创建 cleaner:可以在测试的
TestMain
中初始化 cleaner,然后在各个测试用例中重复使用。
var testCleaner *dbcleaner.DBCleaner
func TestMain(m *testing.M) {
db, _ := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/test_db")
testCleaner = dbcleaner.New()
testCleaner.SetEngine(mysql.Engine(db))
code := m.Run()
os.Exit(code)
}
func TestUser(t *testing.T) {
testCleaner.Acquire("users")
defer testCleaner.Clean("users")
// 测试代码...
}
-
按功能模块分组表:将相关的表放在一起清理,减少数据库操作次数。
-
注意外键约束:如果表有外键约束,需要按正确的顺序清理表,或者暂时禁用外键检查。
// 对于 MySQL 可以这样禁用外键检查
_, _ = db.Exec("SET FOREIGN_KEY_CHECKS = 0")
defer db.Exec("SET FOREIGN_KEY_CHECKS = 1")
注意事项
- dbcleaner 主要用于测试环境,不要在生产环境中使用
- 清理操作会删除表中的所有数据,请确保你操作的是测试数据库
- 对于大型表,清理操作可能会比较耗时,考虑在测试中使用内存数据库或模拟(mock)
通过合理使用 dbcleaner,你可以确保每个测试用例都在干净的数据库状态下运行,避免测试之间的相互干扰。