golang实现SQL、NoSQL和结构化文件数据存储测试的插件库dsunit的使用
Golang实现SQL、NoSQL和结构化文件数据存储测试的插件库dsunit的使用
介绍
dsunit是一个用于Go语言的数据存储测试库,属于黑盒测试范畴,主要关注数据存储的初始状态和最终状态。
该框架提供了两种功能:
- 设置数据存储的初始状态(可以创建空数据存储或用测试数据集准备数据存储)
- 测试最终状态(验证应用程序运行后数据集数据是否匹配预期值)
动机
该库设计目的是为任何平台、语言和云环境下的任何数据存储(SQL、NoSQL、文件日志)提供统一且简单的测试方式。
使用示例
数据设置和验证
1. 使用专用预期数据文件夹
import (
"testing"
"github.com/viant/dsunit"
_ "github.com/go-sql-driver/mysql"
)
func Test_Usecase(t *testing.T) {
parent := toolbox.CallerDirectory(3)
if !dsunit.InitFromURL(t, path.Join(parent, "test", "config.yaml")) {
return
}
// 业务测试逻辑
expectURL := path.Join(parent, "test/case1/data/expect")
expectedData := dsunit.NewDatasetResource("db1", expectURL , "", "")
dsunit.Expect(t, dsunit.NewExpectRequest(dsunit.FullTableDatasetCheckPolicy, expectedData))
}
2. 使用共享预期数据文件夹
func Test_Usecase(t *testing.T) {
parent := toolbox.CallerDirectory(3)
if !dsunit.InitFromURL(t, path.Join(parent, "test", "config.yaml")) {
return
}
// 业务测试逻辑
baseDir := path.Join(parent, "test", "data")
dsunit.ExpectFor(t, "db1", dsunit.FullTableDatasetCheckPolicy, baseDir, "use_case_1")
}
强制在加载数据前清空表
在数据文件中,如果第一个元素是空map,dsunit会在插入提供的数据集前删除表中的所有记录:
[ {},
{"id":1,"name":"name 1"},
{"id":2,"name":"name 2"}
]
空数组会移除表中的所有记录:
[]
逆向工程数据设置和验证
registerResponse := service.Register(dsunit.NewRegisterRequest("db1",
&dsc.Config{
DriverName: "sqlite3",
Descriptor: "[url]",
Parameters: map[string]interface{}{
"url": filename,
},
}))
if registerResponse.Stats != "ok" {
log.Fatal(registerResponse.Error)
}
response := service.Freeze(&dsunit.FreezeRequest{
Datastore:"db1",
DestURL:"/tmp/dn1/expect/users.json",
SQL:"SELECT * FROM users",
})
验证机制
该库使用assertly作为底层验证机制。
宏
宏是带有参数的表达式,用于扩展原始文本值。格式:<ds:MACRO_NAME [json格式的参数数组]>
内置宏:
名称 | 参数 | 描述 | 示例 |
---|---|---|---|
sql | SQL表达式 | 返回SQL表达式的值 | <ds:sql["SELECT CURRENT_DATE()"]> |
seq | 序列/表的自增名称 | 返回序列值 | <ds:seq["users"]> |
指令
数据准备
@autoincrement@ - 指定自增字段
[
{"[@autoincrement](/user/autoincrement)@":"id"},
{"id":1, "username":"Dudi", "active":true, "salary":12400, "comments":"abc","last_access_time": "2016-03-01 03:10:00"},
{"id":2, "username":"Rudi", "active":true, "salary":12600, "comments":"def","last_access_time": "2016-03-01 05:10:00"}
]
@indexBy@ - 指定主键字段
[
{"[@indexBy](/user/indexBy)@":["id"]},
{"id":1, "username":"Dudi", "active":true, "salary":12400, "comments":"abc","last_access_time": "2016-03-01 03:10:00"},
{"id":2, "username":"Rudi", "active":true, "salary":12600, "comments":"def","last_access_time": "2016-03-01 05:10:00"}
]
数据验证
@fromQuery@ - 指定查询以获取实际数据集与预期数据集进行验证
[
{"[@fromQuery](/user/fromQuery)@":"SELECT * FROM users where id <= 2 ORDER BY id"},
{"id":1, "username":"Dudi", "active":true, "salary":12400, "comments":"abc","last_access_time": "2016-03-01 03:10:00"},
{"id":2, "username":"Rudi", "active":true, "salary":12600, "comments":"def","last_access_time": "2016-03-01 05:10:00"}
]
示例项目
RDBMS
- Big Query
- MySQL
- Oracle
- Postgres
NoSQL
- Aerospike
- MongoDB
- Cassandra
- Firebase
- DynamoDB
许可证
源代码根据Apache License, Version 2提供,详见LICENSE
文件。
作者和贡献者
库作者: Adrian Witas
贡献者: Sudhakaran Dharmaraj
更多关于golang实现SQL、NoSQL和结构化文件数据存储测试的插件库dsunit的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang实现SQL、NoSQL和结构化文件数据存储测试的插件库dsunit的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
dsunit: Go语言数据存储测试插件库
dsunit是一个用于测试SQL、NoSQL和结构化文件数据存储的Go语言插件库,它提供了一套统一的API来准备测试数据、验证存储结果以及清理测试环境。
主要特性
- 支持多种数据库类型:MySQL, PostgreSQL, Oracle, SQL Server, SQLite等
- 支持NoSQL数据库:MongoDB, DynamoDB等
- 支持结构化文件:CSV, JSON, XML等
- 提供数据准备和验证功能
- 支持测试数据的外部化配置
安装
go get github.com/viant/dsunit
基本使用示例
1. 初始化测试环境
import (
"github.com/viant/dsunit"
"testing"
)
func TestMain(m *testing.M) {
// 初始化测试环境
dsunit.InitDatastores()
// 运行测试
m.Run()
// 清理测试环境
dsunit.CleanupDatastores()
}
2. SQL数据库测试示例
func TestSQLDatabase(t *testing.T) {
// 注册数据库连接
err := dsunit.RegisterDatabase("test_db", "mysql", "user:password@tcp(localhost:3306)/testdb?parseTime=true")
if err != nil {
t.Fatalf("Failed to register database: %v", err)
}
// 准备测试数据
err = dsunit.PrepareDatastore("test_db", "testdata/users.json")
if err != nil {
t.Fatalf("Failed to prepare data: %v", err)
}
// 执行测试逻辑
// ...
// 验证数据库状态
expectations := dsunit.NewExpectation()
expectations.AddTable("users", dsunit.NewTableExpectation(
dsunit.WithRowCount(3),
dsunit.WithColumnValues("status", "active"),
))
results, err := dsunit.ExpectDatastore("test_db", expectations)
if err != nil {
t.Fatalf("Validation failed: %v", err)
}
if !results.Valid() {
t.Errorf("Data validation failed: %v", results)
}
}
3. MongoDB测试示例
func TestMongoDB(t *testing.T) {
// 注册MongoDB连接
err := dsunit.RegisterDatastore("test_mongo", "mongodb://localhost:27017/testdb")
if err != nil {
t.Fatalf("Failed to register MongoDB: %v", err)
}
// 准备测试数据
err = dsunit.PrepareDatastore("test_mongo", "testdata/products.json")
if err != nil {
t.Fatalf("Failed to prepare data: %v", err)
}
// 执行测试逻辑
// ...
// 验证MongoDB集合
expectations := dsunit.NewExpectation()
expectations.AddCollection("products", dsunit.NewDocumentExpectation(
dsunit.WithDocumentCount(5),
dsunit.WithFieldValue("category", "electronics"),
))
results, err := dsunit.ExpectDatastore("test_mongo", expectations)
if err != nil {
t.Fatalf("Validation failed: %v", err)
}
if !results.Valid() {
t.Errorf("Data validation failed: %v", results)
}
}
4. CSV文件测试示例
func TestCSVFile(t *testing.T) {
// 注册CSV文件存储
err := dsunit.RegisterDatastore("test_csv", "file:///path/to/csv/files")
if err != nil {
t.Fatalf("Failed to register CSV storage: %v", err)
}
// 准备测试数据
err = dsunit.PrepareDatastore("test_csv", "testdata/orders.csv")
if err != nil {
t.Fatalf("Failed to prepare data: %v", err)
}
// 执行测试逻辑
// ...
// 验证CSV文件内容
expectations := dsunit.NewExpectation()
expectations.AddFile("orders.csv", dsunit.NewFileExpectation(
dsunit.WithRowCount(10),
dsunit.WithColumnValues("status", "completed"),
))
results, err := dsunit.ExpectDatastore("test_csv", expectations)
if err != nil {
t.Fatalf("Validation failed: %v", err)
}
if !results.Valid() {
t.Errorf("Data validation failed: %v", results)
}
}
测试数据文件格式
dsunit支持JSON格式的测试数据文件,例如:
{
"users": [
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"status": "active"
},
{
"id": 2,
"name": "Jane Smith",
"email": "jane@example.com",
"status": "active"
}
]
}
高级功能
- 数据模板:支持使用Go模板语法动态生成测试数据
- 变量替换:支持在测试数据中使用变量
- 数据序列:支持自动生成序列ID
- 关联数据:支持跨表/集合的数据关联
最佳实践
- 将测试数据外部化到JSON/CSV文件中
- 为每个测试用例准备独立的数据集
- 在测试完成后清理测试数据
- 使用明确的验证条件确保测试可靠性
- 考虑使用事务回滚来保持测试隔离性
dsunit提供了一种统一的方式来测试不同类型的数据存储,使得测试代码更加简洁和可维护。通过将测试数据外部化,可以更容易地维护和共享测试用例。