golang MySQL集成测试辅助工具插件库go-mysql-test-container的使用

go-mysql-test-container 使用指南

go-mysql-test-container 是一个让 MySQL 集成测试变得轻松的 Golang 测试容器工具。

安装

执行以下命令安装:

go get github.com/arikama/go-mysql-test-container

使用示例

下面是一个完整的使用示例,展示如何在测试中使用 go-mysql-test-container:

package main

import (
	"database/sql"
	"log"
	"testing"

	"github.com/arikama/go-mysql-test-container/mysqltestcontainer"
)

func TestMySQLIntegration(t *testing.T) {
	// 创建MySQL测试容器,数据库名称为"testdb"
	mySql, err := mysqltestcontainer.Create("testdb")
	if err != nil {
		t.Fatalf("Failed to create MySQL container: %v", err)
	}
	defer mySql.Close() // 测试结束后关闭容器

	// 获取数据库连接
	db := mySql.GetDb()
	defer db.Close() // 关闭数据库连接

	// 测试数据库连接
	err = db.Ping()
	if err != nil {
		t.Errorf("Failed to ping database: %v", err)
	}

	// 创建表
	_, err = db.Exec("CREATE TABLE IF NOT EXISTS users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255))")
	if err != nil {
		t.Errorf("Failed to create table: %v", err)
	}

	// 插入数据
	_, err = db.Exec("INSERT INTO users (name) VALUES (?)", "John Doe")
	if err != nil {
		t.Errorf("Failed to insert data: %v", err)
	}

	// 查询数据
	var name string
	err = db.QueryRow("SELECT name FROM users WHERE id = ?", 1).Scan(&name)
	if err != nil {
		t.Errorf("Failed to query data: %v", err)
	}

	if name != "John Doe" {
		t.Errorf("Expected 'John Doe', got '%s'", name)
	}
}

开发环境要求

  1. 确保本地已安装 Docker
docker --version
  1. 确保 Docker 可以正常运行
docker run hello-world
  1. 运行测试
./gotest.sh

功能特点

  • 自动创建和销毁 MySQL 测试容器
  • 提供简单的 API 获取数据库连接
  • 适合集成测试场景
  • 无需手动配置 MySQL 服务器

这个工具非常适合需要在隔离环境中进行 MySQL 相关测试的场景,每个测试用例都会获得一个干净的数据库实例,确保测试之间不会相互影响。


更多关于golang MySQL集成测试辅助工具插件库go-mysql-test-container的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang MySQL集成测试辅助工具插件库go-mysql-test-container的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go-mysql-test-container 使用指南

go-mysql-test-container 是一个用于 Go 语言 MySQL 集成测试的辅助工具库,它基于 TestContainers 项目,可以方便地在测试中启动和管理 MySQL 容器实例。

主要特性

  1. 快速启动 MySQL 容器用于测试
  2. 自动清理测试资源
  3. 支持自定义 MySQL 配置
  4. 与标准 database/sql 包无缝集成

安装

go get github.com/arikama/go-mysql-test-container

基本使用示例

package main

import (
	"database/sql"
	"fmt"
	"log"
	"testing"

	mysqltestcontainer "github.com/arikama/go-mysql-test-container"
	_ "github.com/go-sql-driver/mysql"
)

func TestMySQLIntegration(t *testing.T) {
	// 创建 MySQL 测试容器
	mysqlContainer, err := mysqltestcontainer.NewMysqlTestContainer(mysqltestcontainer.WithPassword("testpassword"))
	if err != nil {
		t.Fatalf("Failed to start MySQL container: %v", err)
	}
	
	// 确保测试结束后容器会被停止
	t.Cleanup(func() {
		if err := mysqlContainer.Close(); err != nil {
			t.Errorf("Failed to stop MySQL container: %v", err)
		}
	})

	// 获取数据库连接字符串
	dsn := mysqlContainer.GetDsn()

	// 连接数据库
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		t.Fatalf("Failed to connect to MySQL: %v", err)
	}
	defer db.Close()

	// 执行测试查询
	var version string
	err = db.QueryRow("SELECT VERSION()").Scan(&version)
	if err != nil {
		t.Fatalf("Failed to query version: %v", err)
	}

	fmt.Printf("MySQL version: %s\n", version)
}

高级配置选项

func TestWithCustomConfig(t *testing.T) {
	// 使用自定义配置创建容器
	mysqlContainer, err := mysqltestcontainer.NewMysqlTestContainer(
		mysqltestcontainer.WithPassword("custompass"),
		mysqltestcontainer.WithDatabase("testdb"),
		mysqltestcontainer.WithUsername("testuser"),
		mysqltestcontainer.WithPort("3307"), // 映射到主机的端口
		mysqltestcontainer.WithVersion("5.7"), // 指定 MySQL 版本
	)
	if err != nil {
		t.Fatal(err)
	}
	defer mysqlContainer.Close()

	// 使用自定义配置连接
	db, err := sql.Open("mysql", mysqlContainer.GetDsn())
	if err != nil {
		t.Fatal(err)
	}
	defer db.Close()

	// 检查数据库是否存在
	var dbName string
	err = db.QueryRow("SELECT DATABASE()").Scan(&dbName)
	if err != nil {
		t.Fatal(err)
	}

	if dbName != "testdb" {
		t.Errorf("Expected database 'testdb', got '%s'", dbName)
	}
}

初始化数据库脚本

func TestWithInitScript(t *testing.T) {
	initScript := `
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE
);

INSERT INTO users (name, email) VALUES 
('Alice', 'alice@example.com'),
('Bob', 'bob@example.com');
`

	mysqlContainer, err := mysqltestcontainer.NewMysqlTestContainer(
		mysqltestcontainer.WithPassword("testpass"),
		mysqltestcontainer.WithInitScript(initScript),
	)
	if err != nil {
		t.Fatal(err)
	}
	defer mysqlContainer.Close()

	db, err := sql.Open("mysql", mysqlContainer.GetDsn())
	if err != nil {
		t.Fatal(err)
	}
	defer db.Close()

	// 查询初始化数据
	var count int
	err = db.QueryRow("SELECT COUNT(*) FROM users").Scan(&count)
	if err != nil {
		t.Fatal(err)
	}

	if count != 2 {
		t.Errorf("Expected 2 users, got %d", count)
	}
}

并行测试支持

func TestParallel(t *testing.T) {
	t.Parallel()

	mysqlContainer, err := mysqltestcontainer.NewMysqlTestContainer()
	if err != nil {
		t.Fatal(err)
	}
	defer mysqlContainer.Close()

	// 测试逻辑...
}

最佳实践

  1. 每个测试用例使用独立的容器实例,避免测试间的相互影响
  2. 使用 t.Cleanup() 确保容器被正确清理
  3. 对于简单的测试,可以使用内存数据库如 SQLite
  4. 考虑使用测试套件级别的容器,减少容器启动时间

替代方案

如果 go-mysql-test-container 不满足需求,也可以考虑:

  1. 直接使用 TestContainers Go 库
  2. 使用 Docker SDK 直接管理容器
  3. 使用本地安装的 MySQL 服务

go-mysql-test-container 简化了 MySQL 测试容器的管理,使得编写集成测试更加方便快捷。

回到顶部