feat(tests): 增强测试框架的 SQL 日志记录与覆盖率报告

- 在 ApiCase 中添加 SQL 日志记录功能,失败时输出日志以便于调试
- 更新 TestApp 以支持测试模式下的 SQL 日志缓冲,成功与失败的测试均可记录日志
- 改进 PrintCoverage 方法,优化覆盖率报告的输出逻辑,支持部分运行的接口显示
- 增加 Note 备注功能,提升测试用例的可读性与文档化效果
- 更新相关文档,详细说明新功能的使用场景与示例
This commit is contained in:
2026-04-04 01:34:09 +08:00
parent b3f263c965
commit 17e1090077
8 changed files with 531 additions and 28 deletions
+24 -2
View File
@@ -1,6 +1,7 @@
package db
import (
"bytes"
"code.hoteas.com/golang/hotime/cache"
. "code.hoteas.com/golang/hotime/common"
"database/sql"
@@ -33,8 +34,10 @@ type HoTimeDB struct {
mu sync.RWMutex
limitMu sync.Mutex
Dialect Dialect // 数据库方言适配器
testTx *sql.Tx // 测试事务:设置后所有操作都在此事务内,测试结束回滚
testMu *sync.Mutex // 保护 testTx 单连接不被并发访问
testTx *sql.Tx // 测试事务:设置后所有操作都在此事务内,测试结束回滚
testMu *sync.Mutex // 保护 testTx 单连接不被并发访问
testLogBuf *bytes.Buffer // 测试模式:SQL 日志写入此 buffer 而非直接打印,失败时才输出
testLogBufMu sync.Mutex // 保护 testLogBuf 并发写入
}
// SetConnect 设置数据库配置连接
@@ -151,6 +154,25 @@ func trimQuotes(s string) string {
return s
}
// SetTestLogBuffer 设置测试 SQL 日志缓冲区,非 nil 时 SQL 日志写入 buffer 而非直接打印
func (that *HoTimeDB) SetTestLogBuffer(buf *bytes.Buffer) {
that.testLogBufMu.Lock()
that.testLogBuf = buf
that.testLogBufMu.Unlock()
}
// FlushTestLog 取出并清空缓冲区中的 SQL 日志,返回累积的日志文本
func (that *HoTimeDB) FlushTestLog() string {
that.testLogBufMu.Lock()
defer that.testLogBufMu.Unlock()
if that.testLogBuf == nil {
return ""
}
s := that.testLogBuf.String()
that.testLogBuf.Reset()
return s
}
// BeginTestTx 开启测试事务,设置后所有 Query/Exec/Action 都在此事务内执行
func (that *HoTimeDB) BeginTestTx() error {
tx, err := that.DB.Begin()
+17 -2
View File
@@ -4,6 +4,7 @@ import (
"database/sql"
"encoding/json"
"errors"
"fmt"
"math"
"reflect"
"strconv"
@@ -39,8 +40,15 @@ func (that *HoTimeDB) queryWithRetry(query string, retried bool, args ...interfa
defer func() {
if that.Mode != 0 {
that.mu.RLock()
that.Log.Info("SQL:"+that.LastQuery, " DATA:", that.LastData, " ERROR:", that.LastErr.GetError())
msg := fmt.Sprintf("SQL:%s DATA:%v ERROR:%v", that.LastQuery, that.LastData, that.LastErr.GetError())
that.mu.RUnlock()
that.testLogBufMu.Lock()
if that.testLogBuf != nil {
that.testLogBuf.WriteString(msg + "\n")
} else {
that.Log.Info(msg)
}
that.testLogBufMu.Unlock()
}
}()
@@ -117,8 +125,15 @@ func (that *HoTimeDB) execWithRetry(query string, retried bool, args ...interfac
defer func() {
if that.Mode != 0 {
that.mu.RLock()
that.Log.Info("SQL: "+that.LastQuery, " DATA: ", that.LastData, " ERROR: ", that.LastErr.GetError())
msg := fmt.Sprintf("SQL:%s DATA:%v ERROR:%v", that.LastQuery, that.LastData, that.LastErr.GetError())
that.mu.RUnlock()
that.testLogBufMu.Lock()
if that.testLogBuf != nil {
that.testLogBuf.WriteString(msg + "\n")
} else {
that.Log.Info(msg)
}
that.testLogBufMu.Unlock()
}
}()