0
0
Lập trình
Admin Team
Admin Teamtechmely

pgdbtemplate – Tăng tốc kiểm thử PostgreSQL trong Go

Đăng vào 6 tháng trước

• 6 phút đọc

Giới thiệu về pgdbtemplate

Bạn có mệt mỏi khi phải chờ đợi bộ kiểm thử của mình tạo và di chuyển cơ sở dữ liệu PostgreSQL một cách chậm chạp qua từng lần kiểm thử? Nếu bạn đang phát triển các ứng dụng xử lý dữ liệu lớn bằng Go, bạn chắc hẳn đã trải qua nỗi đau này. Thời gian mà các bài kiểm thử của bạn tiêu tốn để thiết lập cơ sở dữ liệu thường nhiều hơn thời gian thực sự kiểm tra logic của bạn.

Nhưng nếu tôi nói với bạn rằng có một cách để làm cho quá trình này nhanh hơn 1.5 lần, sử dụng 17% ít bộ nhớ hơn, và dễ dàng mở rộng đến hàng trăm cơ sở dữ liệu kiểm thử?

Chào mừng bạn đến với pgdbtemplate – một thư viện Go hiệu suất cao tận dụng các cơ sở dữ liệu mẫu của PostgreSQL để cách mạng hóa quy trình kiểm thử của bạn.

Vấn Đề: Thiết lập cơ sở dữ liệu truyền thống chậm

Cách tiếp cận truyền thống cho các bài kiểm tra tích hợp thường như sau:

Copy
func TestUserService(t *testing.T) {
    // 1. Tạo cơ sở dữ liệu mới
    // 2. Chạy tất cả các di chuyển (CREATE TABLE, INDEX, FK...)
    // 3. Chạy bài kiểm tra của bạn
    // 4. Xóa cơ sở dữ liệu
}

Các bước 1 và 2 sẽ lặp lại cho mỗi bài kiểm tra, tiêu tốn thời gian và tài nguyên quý giá. Đặc biệt là khi sơ đồ của bạn phức tạp, quá trình này càng trở nên chậm chạp hơn.

Giải Pháp: Cơ sở dữ liệu mẫu PostgreSQL

PostgreSQL có một tính năng tuyệt vời: các cơ sở dữ liệu mẫu. Bạn có thể tạo một cơ sở dữ liệu "vàng" với tất cả các di chuyển đã áp dụng một lần, và sau đó sử dụng nó như một mẫu để tạo ra các cơ sở dữ liệu mới, giống hệt nhau trong vài mili giây.

pgdbtemplate tự động hóa quá trình này, cung cấp một API đơn giản phù hợp hoàn hảo với thiết lập kiểm thử hiện tại của bạn.

Bắt đầu chỉ trong vài phút

Đầu tiên, hãy cài đặt thư viện:

Copy
go get github.com/andrei-polukhin/pgdbtemplate

Dưới đây là cách bạn sử dụng nó trong bộ kiểm thử của mình:

Copy
package main

import (
    "context"
    "testing"

    "github.com/andrei-polukhin/pgdbtemplate"
)

var templateManager *pgdbtemplate.TemplateManager

func TestMain(m *testing.M) {
    ctx := context.Background()

    // Thiết lập quản lý mẫu một lần
    connStringFunc := func(dbName string) string {
        return "postgres://user:pass@localhost/" + dbName
    }

    provider := pgdbtemplate.NewPgxConnectionProvider(connStringFunc)
    migrationRunner := pgdbtemplate.NewFileMigrationRunner(
        []string{"./migrations"},
        pgdbtemplate.AlphabeticalMigrationFilesSorting,
    )

    tm, _ := pgdbtemplate.NewTemplateManager(pgdbtemplate.Config{
        ConnectionProvider: provider,
        MigrationRunner:    migrationRunner,
    })

    // Khởi tạo mẫu với các di chuyển (một lần duy nhất)
    tm.Initialize(ctx)

    templateManager = tm
    code := m.Run()

    // Dọn dẹp mọi thứ
    tm.Cleanup(ctx)
    os.Exit(code)
}

func TestUserRepository(t *testing.T) {
    ctx := context.Background()

    // Mỗi bài kiểm tra có cơ sở dữ liệu riêng biệt ngay lập tức!
    testDB, testDBName, err := templateManager.CreateTestDatabase(ctx)
    if err != nil {
        t.Fatal(err)
    }
    defer testDB.Close()
    defer templateManager.DropTestDatabase(ctx, testDBName)

    // Chạy logic kiểm thử của bạn trên một cơ sở dữ liệu mới
    repo := NewUserRepository(testDB)
    user, err := repo.CreateUser("test@example.com")
    // ... các khẳng định của bạn
}

Hiệu Suất Thực Tế: Số liệu không biết nói dối

Chúng tôi đã thực hiện nhiều bài kiểm tra so sánh giữa việc tạo cơ sở dữ liệu truyền thống và phương pháp mẫu. Kết quả thật ấn tượng:

🚀 So sánh tốc độ (thấp hơn tốt hơn)

Độ phức tạp sơ đồ Phương pháp truyền thống Phương pháp mẫu Cải thiện
1 Bảng 28.9ms 28.2ms 1.03x
3 Bảng 39.5ms 27.6ms 1.43x
5 Bảng 43.1ms 28.8ms 1.50x

📈 Mở rộng đến hàng trăm cơ sở dữ liệu

Số lượng cơ sở dữ liệu Truyền thống Mẫu Thời gian tiết kiệm
20 DBs 906.8ms 613.8ms 32%
50 DBs 2.29s 1.53s 33%
200 DBs 9.21s 5.84s 37%
500 DBs 22.31s 14.82s 34%

Phương pháp mẫu duy trì hiệu suất đồng nhất bất kể độ phức tạp của sơ đồ, trong khi phương pháp truyền thống ngày càng chậm hơn khi bạn thêm nhiều bảng, chỉ mục và ràng buộc.

Các Tính Năng Nổi Bật

  • ⚡ Nhanh chóng: Tạo cơ sở dữ liệu kiểm thử trong vài mili giây thay vì vài giây
  • 🔒 An toàn luồng: Hoàn hảo cho việc thực thi kiểm thử song song (t.Parallel())
  • 🔄 Hỗ trợ hai driver: Hoạt động với cả database/sql + pqpgx
  • 🧹 Dọn dẹp tự động: Dọn dẹp toàn diện các cơ sở dữ liệu kiểm thử
  • 🐳 Sẵn sàng với Testcontainers: Tích hợp dễ dàng với PostgreSQL trong container
  • 📊 Linh hoạt di chuyển: Hỗ trợ các runner di chuyển dựa trên tệp và tùy chỉnh

Cách Hoạt Động Bên Trong

  1. Khởi tạo: Tạo một cơ sở dữ liệu mẫu và chạy tất cả các di chuyển một lần
  2. Kiểm thử: Đối với mỗi bài kiểm tra, tạo một cơ sở dữ liệu mới bằng cách sử dụng CREATE DATABASE... TEMPLATE
  3. Dọn dẹp: Xóa các cơ sở dữ liệu kiểm thử và cuối cùng dọn dẹp mẫu

Phép màu xảy ra ở bước 2 – PostgreSQL xử lý việc sao chép cơ sở dữ liệu mẫu ở cấp độ hệ thống tệp, điều này nhanh hơn rất nhiều so với việc chạy các di chuyển SQL lặp đi lặp lại.

Sử Dụng Nâng Cao

Sử dụng với testcontainers-go

Copy
func setupTemplateManagerWithContainer(ctx context.Context) error {
    pgContainer, _ := postgres.RunContainer(ctx,
        testcontainers.WithImage("postgres:15"),
        postgres.WithDatabase("testdb"),
        // ... cấu hình khác
    )

    connStr, _ := pgContainer.ConnectionString(ctx, "sslmode=disable")

    provider := pgdbtemplate.NewStandardConnectionProvider(
        func(dbName string) string {
            return pgdbtemplate.ReplaceDatabaseInConnectionString(connStr, dbName)
        })

    // Tạo và sử dụng quản lý mẫu như trước
    // ...
}

Tùy Chọn Pool Kết Nối

Cấu hình kết nối của bạn để đạt hiệu suất tối ưu:

Copy
// Đối với database/sql + pq
provider := pgdbtemplate.NewStandardConnectionProvider(
    connStringFunc,
    pgdbtemplate.WithMaxOpenConns(25),
    pgdbtemplate.WithMaxIdleConns(10),
)

// Đối với pgx
provider := pgdbtemplate.NewPgxConnectionProvider(
    connStringFunc,
    pgdbtemplate.WithPgxMaxConns(10),
    pgdbtemplate.WithPgxMinConns(2),
)

Khi Nào Bạn Nên Sử Dụng pgdbtemplate?

  • Bạn có >10 bài kiểm tra cơ sở dữ liệu trong bộ kiểm thử của mình
  • Sơ đồ của bạn có >3 bảng với chỉ mục và mối quan hệ
  • Bạn chạy kiểm thử thường xuyên trong quá trình phát triển
  • Pipeline CI/CD của bạn bao gồm các kiểm thử tích hợp cơ sở dữ liệu
  • Bạn đánh giá phản hồi nhanh hơn cả thời gian nghỉ cà phê

Hãy Thử Ngay!

Bạn đã sẵn sàng để tăng tốc bộ kiểm thử của mình chưa? Bắt đầu thật dễ dàng:

Copy
go get github.com/andrei-polukhin/pgdbtemplate

Hãy kiểm tra kho GitHub để xem tài liệu đầy đủ, các ví dụ nâng cao, và hướng dẫn đóng góp.

Bạn đã có kinh nghiệm gì với kiểm thử PostgreSQL trong Go chưa? Bạn đã thử các phương pháp khác để tăng tốc bộ kiểm thử của mình chưa? Chia sẻ ý kiến của bạn trong phần bình luận bên dưới!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào