golang从SQL文件生成测试数据并在测试后清理的插件库testsql的使用

Golang从SQL文件生成测试数据并在测试后清理的插件库testsql的使用

TestSQL是一个Golang库,用于在测试前从SQL文件生成测试数据,并在测试完成后清理数据。

安装

go get github.com/zhulongcheng/testsql

使用方法

1. 创建文件结构

首先创建一个文件夹结构来存放表结构文件和SQL数据文件:

testsql
├── fixtures
│   └── users.sql
└── schema.sql

2. 准备表结构文件

schema.sql文件包含所有表的结构定义,例如:

CREATE TABLE `users` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(32) CHARACTER SET utf8mb4 NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3. 准备测试数据文件

fixtures/users.sql文件包含测试数据:

INSERT INTO `users` (`id`, `name`)
VALUES
    (1, 'foo');

4. 编写测试代码

var TS *testsql.TestSQL

// 创建TestSQL实例
func newTS() *testsql.TestSQL {
    dsn := "user:password@tcp(host:port)/test_db_name"
    tableSchemaPath := "testsql/schema.sql"
    dirPath := "testsql/fixtures"
    ts := testsql.New(dsn, tableSchemaPath, dirPath)
    return ts
}

// 初始化测试数据库
func initTestDB() {
    TS = newTS()
    
    // 设置sql-driver/orm使用TS的DSN
    // Driver = sql.Open(TS.Config.DSN)
    // ORM = ORM.New(TS.Config.DSN)
}

func TestMain(m *testing.M) {
    initTestDB()
    r := m.Run()
    TS.DropTestDB() // 测试完成后删除数据库
    os.Exit(r)
}

func TestUser(t *testing.T) {
    TS.Use("users.sql") // 使用users.sql文件中的数据
    defer TS.Clear()    // 测试完成后清理数据
    
    // 这里可以编写测试逻辑
    // user := GetUserByID(1)
    // if user.name != "foo" {
    //    t.Errorf("not equal, expected: %s, actual: %s", "foo", user.name) 
    // }
}

API参考

  • TestSQL.Exec: 从SQL字符串生成测试数据
  • TestSQL.Use: 从SQL文件生成测试数据
  • TestSQL.Clear: 删除所有表的数据
  • TestSQL.DropTestDB: 删除TestSQL创建的数据库

常见问题

如何设置sql-driver/orm使用TestSQL的DSN

db := yourSQLDriver.Open(TS.Config.DSN)
// 或者 db := yourORM.Open(TS.Config.DSN)

yourModel.SetDB(db)  // 重置db

TestSQL提供了一种简单的方式来管理测试数据,使得测试更加可靠和可维护。通过使用SQL文件来定义测试数据,可以方便地在不同测试用例中重用相同的数据集。


更多关于golang从SQL文件生成测试数据并在测试后清理的插件库testsql的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang从SQL文件生成测试数据并在测试后清理的插件库testsql的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


testsql - Golang SQL测试数据生成与清理工具

testsql是一个用于在Golang测试中生成测试数据并在测试后清理的实用工具库。它允许你从SQL文件加载数据,自动管理测试数据的生命周期。

安装

go get github.com/go-testfixtures/testfixtures/v3

基本用法

1. 初始化测试数据库

首先,创建一个测试辅助函数来初始化数据库连接和testsql:

package main_test

import (
	"database/sql"
	"os"
	"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
	
	// 初始化数据库连接
	db, err = sql.Open("mysql", "user:password@tcp(localhost:3306)/testdb?parseTime=true")
	if err != nil {
		panic(err)
	}
	
	// 准备fixtures
	fixtures, err = testfixtures.New(
		testfixtures.Database(db),
		testfixtures.Dialect("mysql"),
		testfixtures.Directory("testdata/fixtures"),
	)
	if err != nil {
		panic(err)
	}

	// 运行测试
	code := m.Run()
	
	// 清理
	db.Close()
	os.Exit(code)
}

2. 创建测试数据文件

testdata/fixtures目录下创建YAML或JSON格式的测试数据文件,例如users.yml:

- id: 1
  name: "John Doe"
  email: "john@example.com"
  created_at: "2023-01-01 00:00:00"
  
- id: 2
  name: "Jane Smith"
  email: "jane@example.com"
  created_at: "2023-01-02 00:00:00"

3. 在测试中使用

func TestUserRepository(t *testing.T) {
	// 加载测试数据
	if err := fixtures.Load(); err != nil {
		t.Fatal(err)
	}

	// 执行测试
	t.Run("FindUserByID", func(t *testing.T) {
		var name string
		err := db.QueryRow("SELECT name FROM users WHERE id = ?", 1).Scan(&name)
		if err != nil {
			t.Fatal(err)
		}
		
		if name != "John Doe" {
			t.Errorf("expected John Doe, got %s", name)
		}
	})

	// 测试结束后会自动清理数据
}

高级功能

1. 使用SQL文件

你也可以直接使用SQL文件作为fixture源:

fixtures, err = testfixtures.New(
	testfixtures.Database(db),
	testfixtures.Dialect("mysql"),
	testfixtures.Files(
		"testdata/fixtures/users.sql",
		"testdata/fixtures/posts.sql",
	),
)

2. 跳过清理

如果你需要在测试后保留数据(不推荐):

fixtures, err = testfixtures.New(
	testfixtures.Database(db),
	testfixtures.Dialect("mysql"),
	testfixtures.Directory("testdata/fixtures"),
	testfixtures.SkipReset(), // 跳过自动清理
)

3. 使用模板

fixtures支持Go模板语法,可以在运行时注入变量:

- id: {{.user1.id}}
  name: "{{.user1.name}}"
  email: "{{.user1.email}}"
vars := map[string]interface{}{
	"user1": map[string]interface{}{
		"id":    1,
		"name":  "John Doe",
		"email": "john@example.com",
	},
}

err = fixtures.LoadWithTemplate(vars)

最佳实践

  1. 为每个测试包创建独立的测试数据库
  2. 保持fixture文件小而专注
  3. 避免在fixture中使用外键约束,除非必要
  4. 考虑使用事务来隔离测试数据

替代方案

如果你需要更复杂的数据生成功能,可以考虑以下替代方案:

  • github.com/Pallinder/go-randomdata - 生成随机测试数据
  • github.com/bxcodec/faker - 生成假数据
  • github.com/jaswdr/faker - 另一个假数据生成器

testsql特别适合需要精确控制测试数据场景的情况,特别是当你有大量现有数据需要导入测试环境时。

回到顶部