enhance(tests): 改进测试用例记录与覆盖率报告

- 在 ApiCase 中添加失败原因记录,提升测试结果的可读性
- 更新 CoverageReport 结构,增加总用例、通过用例和失败用例计数
- 优化 PrintCoverage 方法,支持详细输出未通过接口及其失败原因
- 更新 Swagger 生成逻辑,包含失败原因字段,增强调试信息
- 改进 SQL 错误计数逻辑,确保在测试模式下准确记录 SQL 错误
This commit is contained in:
2026-04-13 06:45:16 +08:00
parent 9a9b9c83ff
commit 3430bdec19
9 changed files with 516 additions and 151 deletions
+24 -55
View File
@@ -312,18 +312,13 @@ func (w *TemplateFileWriter) Write(p []byte) (n int, err error) {
// --- 调用者智能过滤 ---
const maxFrameworkDepth = 10
func callerMarshalFunc(_ uintptr, file string, line int) string {
return findCaller(file, line)
}
func findCaller(origFile string, origLine int) string {
frameworkCount := 0
var lastFrameworkFile string
var lastFrameworkLine int
var applicationFile string
var applicationLine int
var lastInfraFile string
var lastInfraLine int
for i := 1; i < 20; i++ {
_, file, line, ok := runtime.Caller(i)
@@ -332,28 +327,17 @@ func findCaller(origFile string, origLine int) string {
}
shortFile := shortenPath(file)
if isHoTimeFrameworkFile(shortFile) {
frameworkCount++
lastFrameworkFile = shortFile
lastFrameworkLine = line
if strings.Contains(shortFile, "application.go") {
applicationFile = shortFile
applicationLine = line
}
if frameworkCount >= maxFrameworkDepth {
return fmt.Sprintf("%s:%d", shortFile, line)
}
if isInfrastructureFile(shortFile) {
lastInfraFile = shortFile
lastInfraLine = line
continue
}
return fmt.Sprintf("%s:%d", shortFile, line)
}
if applicationFile != "" {
return fmt.Sprintf("%s:%d", applicationFile, applicationLine)
}
if lastFrameworkFile != "" {
return fmt.Sprintf("%s:%d", lastFrameworkFile, lastFrameworkLine)
if lastInfraFile != "" {
return fmt.Sprintf("%s:%d", lastInfraFile, lastInfraLine)
}
return fmt.Sprintf("%s:%d", shortenPath(origFile), origLine)
}
@@ -375,52 +359,37 @@ func shortenPath(file string) string {
return file
}
func isHoTimeFrameworkFile(file string) bool {
// zerolog 内部文件
// isInfrastructureFile 判断文件是否为基础设施(日志/DB/缓存/通用工具)管线,
// 这些文件在调用栈中会被跳过,以显示真正的业务调用者。
// 框架业务文件(application.go、context.go、code/makecode.go 等)不在此列,
// 会作为有意义的调用者返回。
func isInfrastructureFile(file string) bool {
if strings.HasPrefix(file, "zerolog/") || strings.HasPrefix(file, "zerolog@") {
return true
}
// logrus 遗留(vendor 中可能存在)
if strings.HasPrefix(file, "logrus/") || strings.HasPrefix(file, "logrus@") {
return true
}
if strings.HasPrefix(file, "runtime/") {
return true
}
if strings.HasPrefix(file, "log/") {
return true
}
lowerFile := strings.ToLower(file)
if strings.Contains(lowerFile, "hotime") {
frameworkDirs := []string{"db/", "common/", "code/", "cache/", "log/", "dri/"}
for _, dir := range frameworkDirs {
if strings.Contains(file, dir) {
return true
}
}
if strings.HasSuffix(file, "application.go") ||
strings.HasSuffix(file, "context.go") ||
strings.HasSuffix(file, "session.go") ||
strings.HasSuffix(file, "const.go") ||
strings.HasSuffix(file, "type.go") ||
strings.HasSuffix(file, "var.go") ||
strings.HasSuffix(file, "mime.go") {
infraPrefixes := []string{"db/", "cache/", "common/", "dri/"}
for _, prefix := range infraPrefixes {
if strings.HasPrefix(file, prefix) {
return true
}
}
frameworkCoreDirs := []string{"db/", "common/", "code/", "cache/"}
for _, dir := range frameworkCoreDirs {
if strings.HasPrefix(file, dir) {
frameworkFiles := []string{
"query.go", "crud.go", "where.go", "builder.go", "db.go",
"dialect.go", "aggregate.go", "transaction.go", "identifier.go",
"error.go", "func.go", "map.go", "obj.go", "slice.go",
"makecode.go", "template.go", "config.go",
"cache.go", "cache_db.go", "cache_memory.go", "cache_redis.go",
}
for _, f := range frameworkFiles {
if strings.HasSuffix(file, f) {
return true
}
lowerFile := strings.ToLower(file)
if strings.Contains(lowerFile, "hotime") {
infraDirs := []string{"db/", "cache/", "common/", "log/", "dri/"}
for _, dir := range infraDirs {
if strings.Contains(file, dir) {
return true
}
}
}