1
0

feat: 系统性改进后端测试体系

- 新增 6 个测试场景 (config load pipe, handler errors, service aggregation, engine degradation, openai decoder edges, negative tests)
- 更新测试工具规格 (mockgen, in-memory SQLite)
- 覆盖率目标从 >80% 提升至 >85%
- 新增 test-unit 和 test-integration Makefile 命令
- 新增死代码清理和 mockgen 需求
- 归档变更至 openspec/changes/archive/2026-04-22-improve-backend-testing/
This commit is contained in:
2026-04-22 13:18:51 +08:00
parent 59179094ed
commit 4e86adffb7
32 changed files with 3374 additions and 729 deletions

View File

@@ -7,49 +7,40 @@ import (
"nex/backend/internal/config"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
// SetupTestDB initializes an in-memory SQLite database with auto-migration.
// Uses :memory: mode with MaxOpenConns(1) to ensure all operations share the
// same connection, avoiding "database is closed" errors from connection pool.
// Enables foreign key constraints for SQLite.
func SetupTestDB(t *testing.T) *gorm.DB {
t.Helper()
db, err := gorm.Open(sqlite.Open(":memory:?_foreign_keys=on"), &gorm.Config{})
assert.NoError(t, err, "failed to open test database")
require.NoError(t, err, "failed to open test database")
// 限制为单连接,确保 :memory: 数据库不被连接池丢弃
sqlDB, err := db.DB()
assert.NoError(t, err, "failed to get underlying sql.DB")
require.NoError(t, err, "failed to get underlying sql.DB")
sqlDB.SetMaxOpenConns(1)
sqlDB.SetConnMaxLifetime(0)
err = db.AutoMigrate(&config.Provider{}, &config.Model{}, &config.UsageStats{})
assert.NoError(t, err, "failed to auto-migrate test database")
require.NoError(t, err, "failed to auto-migrate test database")
return db
}
// CleanupTestDB closes the database after a brief delay to allow async
// goroutines (e.g. stats recording) to finish.
func CleanupTestDB(t *testing.T, db *gorm.DB) {
t.Helper()
// 等待异步 goroutine如 statsService.Record完成
time.Sleep(50 * time.Millisecond)
sqlDB, err := db.DB()
assert.NoError(t, err, "failed to get underlying sql.DB")
require.NoError(t, err, "failed to get underlying sql.DB")
err = sqlDB.Close()
assert.NoError(t, err, "failed to close test database")
require.NoError(t, err, "failed to close test database")
}
// CreateTestProvider creates a test provider and returns it.
func CreateTestProvider(t *testing.T, db *gorm.DB, id string) config.Provider {
t.Helper()
@@ -62,13 +53,11 @@ func CreateTestProvider(t *testing.T, db *gorm.DB, id string) config.Provider {
}
err := db.Create(&provider).Error
assert.NoError(t, err, "failed to create test provider")
require.NoError(t, err, "failed to create test provider")
return provider
}
// CreateTestModel creates a test model and returns it.
// Does NOT assert on error - returns the model and error for caller to verify.
func CreateTestModel(t *testing.T, db *gorm.DB, id string, providerID string, modelName string) (config.Model, error) {
t.Helper()