测试失败报告.md 12 KB

智慧停车管理系统 - 自动化测试失败报告

测试时间: 2026-07-21 15:10 CST 测试环境: Windows 11 / Go 后端 + SQLite / Wails v2 工作目录: D:\lq\Smart Parking\lc_garage 测试套件: e2e_test.go (11个) + e2e_edge_cases_test.go (16个) 总计: 27 个用例,19 PASS / 8 FAIL


一、总体统计

分类 通过 失败 通过率
核心 E2E 测试 (e2e_test.go) 10 0 100%
边界场景测试 (e2e_edge_cases_test.go) 9 8 53%
合计 19 8 70%

二、失败用例汇总

# 测试用例 Bug 类型 严重度 HTTP 状态码
1 TestVehicleReEntry 测试框架 / 响应体解析 🟡 低 200
2 TestBlackWhiteListEntryExitBehavior 黑名单未拦截进场 🔴 严重 200
3 TestVIPExpired VIP 过期仍免费停车 🔴 严重 200
4 TestNoFeeConfig 无收费配置默认费率为 0 🟡 中等 200
5 TestShortlistDelete 后端 panic (nil pointer) 🔴 严重 500
6 TestVehicleTypeCRUD 列表查询返回空 🟡 中等 200

三、详细失败分析

BUG #1: 黑名单车辆未拦截进场

测试用例: TestBlackWhiteListEntryExitBehavior 严重度: 🔴 严重(安全漏洞) HTTP 状态码: 200 OK

测试步骤:

  1. 初始化测试环境(独立 SQLite + Casbin 权限注入)
  2. 创建车辆 JingB99999 / RFID RFID_BLACK,关联停车场 ID=1
  3. 创建黑名单记录,将该车加入黑名单
  4. 调用 POST /vehicle/entry,传入车牌 JingB99999、RFID RFID_BLACK、停车场 ID=1、车位 ID=1
  5. 断言:接口应拒绝该车辆进场,返回非成功状态码

实际结果:

  • HTTP 状态码: 200 OK
  • 响应内容: code=0, msg=查询成功
  • 车辆 成功进入停车场,入场记录已写入数据库
  • 日志显示 SQL: INSERT INTO vehicle_record ... plate_number="JingB99999"

预期结果:

  • 黑名单车辆尝试进场时,系统应拒绝并返回错误信息
  • 不应创建 vehicle_record 入场记录

根因分析:

  • internal/service/vehicle/vehicle.goVehicleEntry() 方法中 未调用 CheckVehicleShortlist()
  • 进场流程直接创建入场记录,完全绕过了黑白名单检查逻辑
  • shortlist.go 中的 CheckVehicleShortlist(rfid string) 方法存在但未被集成到进出场流程中

修复建议:

// internal/service/vehicle/vehicle.go -> VehicleEntry()
func (vs *VehicleService) VehicleEntry(ctx context.Context, req *dao.VehicleRecord) (*dao.VehicleRecord, error) {
    // TODO: 在创建入场记录前调用黑名单检查
    // shortlistResp := shortlist.CheckVehicleShortlist(req.RfidTag)
    // if shortlistResp.Code == response.FAIL {
    //     return nil, errors.New(shortlistResp.Msg)
    // }
    ...
}

BUG #2: 过期 VIP 仍免费停车

测试用例: TestVIPExpired 严重度: 🔴 严重(计费漏洞) HTTP 状态码: 200 OK

测试步骤:

  1. 初始化测试环境
  2. 调用 POST /owner/create 创建 VIP 车主:
    • 姓名: VIP Expired Test
    • 电话: 13900000001
    • is_vip: true
    • vip_expire_time: 当前时间往前推 24 小时(已过期)
  3. 根据电话查询车主 ID,创建关联车辆 JingV00001 / RFID RFID_VIP_EXP
  4. 调用 POST /vehicle/entry 让车辆进场
  5. 通过数据库直接修改入场时间为 3 小时前(模拟长时间停放)
  6. 调用 POST /vehicle/exit/preview 预览出场费用
  7. 断言:费用应大于 0(过期 VIP 应按普通车辆计费)

实际结果:

  • HTTP 状态码: 200 OK
  • 出场预览费用: fee=0.00
  • 测试断言失败: BUG: Expired VIP still getting free parking! Fee should be > 0

预期结果:

  • 过期 VIP 应恢复为普通车辆计费
  • 停放 3 小时应产生相应停车费用

根因分析:

  • 计费服务在判断 VIP 免单时,未正确校验 VIP 有效期是否已过期
  • is_vip 字段为 true 即触发免单逻辑,忽略了 vip_expire_time 的时间判断
  • 需要在 CalculateFee() 中增加 VIP 过期检查:if owner.IsVip && owner.VipExpireTime > now

修复建议:

// internal/modules/payment/service/service.go -> CalculateFee()
func (ps *PaymentService) CalculateFee(vehicleID uint, entryTime time.Time) (float64, error) {
    // 获取车主信息
    var owner dao.Owner
    db.Where("id = ?", vehicle.OwnerId).First(&owner)
    
    // TODO: 增加 VIP 过期检查
    // if owner.IsVip && owner.VipExpireTime != nil && owner.VipExpireTime.After(time.Now()) {
    //     return 0, nil
    // }
    ...
}

BUG #3: 无收费配置时默认费率为 0

测试用例: TestNoFeeConfig 严重度: 🟡 中等(计费风险) HTTP 状态码: 200 OK

测试步骤:

  1. 初始化测试环境
  2. 查询非系统内置车辆类型(排除"临时车"),若无则创建 "特殊车"
  3. 删除该车辆类型的所有收费配置(DELETE FROM fee_config WHERE vehicle_type_id = ?
  4. 创建关联车辆 JingN00001 / RFID RFID_NOFEE,使用上述无配置的车型
  5. 调用 POST /vehicle/entry 进场
  6. 通过数据库直接修改入场时间为 1 小时前
  7. 调用 POST /vehicle/exit/preview 预览出场费用
  8. 断言:费用应大于 0(应使用系统默认费率)

实际结果:

  • HTTP 状态码: 200 OK
  • 出场预览费用: fee=0.00
  • 测试断言失败: BUG: No fee config should use default rate, got fee=0.00

预期结果:

  • 当特定车型无收费配置时,系统应回退到默认费率进行计费
  • 停放 1 小时应产生相应停车费用

根因分析:

  • internal/modules/payment/service/service.goCalculateFee() 方法中,当查不到对应车型的收费配置时,直接返回 0
  • 缺少默认费率回退逻辑

修复建议:

// internal/modules/payment/service/service.go -> CalculateFee()
func (ps *PaymentService) CalculateFee(vehicleID uint, entryTime time.Time) (float64, error) {
    feeConfig, err := ps.GetFeeConfigByVehicleType(vehicleTypeID)
    if err != nil || feeConfig.ID == 0 {
        // TODO: 应使用默认费率,而非返回 0
        // defaultConfig := ps.GetDefaultFeeConfig()
        // feeConfig = defaultConfig
        return 0, nil  // BUG: 这里应该用默认费率
    }
    ...
}

BUG #4: 重复入场首次 DoPost 响应体为空

测试用例: TestVehicleReEntry 严重度: 🟡 低(测试框架兼容性问题) HTTP 状态码: 200 OK

测试步骤:

  1. 初始化测试环境
  2. 创建车辆 JingR00001 / RFID RFID_REENTRY
  3. 第一次调用 POST /vehicle/entry 进场
  4. 第二次调用 POST /vehicle/entry 再次进场(重复入场)
  5. 解析第二次响应 JSON,断言:重复入场应被拦截

实际结果:

  • 第一次进场响应体为 空字符串
  • JSON 解析失败: unexpected end of JSON input
  • 测试在第 23 行断言处 panic: JSON 解析失败: unexpected end of JSON input | Body:
  • 日志显示: 车辆已更新 last_entry_time,说明第一次进场实际成功

预期结果:

  • 第一次进场应返回正常 JSON 响应
  • 第二次重复进场应返回错误信息(如"车辆已在场内")

根因分析:

  • DoPost 方法在处理首次进场请求时,可能因为后端返回了空 body 或 Content-Type 不匹配导致读取失败
  • 需要检查 internal/api/v1/vehicle/enter.go 的响应写入逻辑

BUG #5: 删除黑白名单后端 Panic

测试用例: TestShortlistDelete 严重度: 🔴 严重(系统稳定性) HTTP 状态码: 500 Internal Server Error

测试步骤:

  1. 初始化测试环境
  2. 创建车辆 JingDel001 / RFID RFID_DELETE
  3. 调用 POST /shortlist/createShortlist 创建黑名单记录
  4. 调用 GET /shortlist/queryAllShortlists 查询所有名单,获取刚创建的记录 ID
  5. 调用 DELETE /shortlist/deleteShortlist?id=<ID> 删除该记录
  6. 断言:删除应返回 200 OK

实际结果:

  • HTTP 状态码: 500 Internal Server Error
  • 响应体:
  • 测试断言失败: HTTP 状态码不匹配: 期望 200, 实际 500
  • 堆栈跟踪显示: runtime error: invalid memory address or nil pointer dereference
  • Panic 发生在 JWT 认证中间件之后、路由处理之前

预期结果:

  • 删除操作应返回 200 OK 及成功消息

根因分析:

  • 后端 deleteShortlist 接口存在 空指针引用 问题
  • 可能是删除参数解析、短名单记录查找或数据库操作返回 nil 后未做空值检查
  • 需要查看 internal/service/vehicle/shortlist.go 的删除实现

BUG #6: 自定义车辆类型创建后列表查询为空

测试用例: TestVehicleTypeCRUD 严重度: 🟡 中等(功能缺陷) HTTP 状态码: 200 OK

测试步骤:

  1. 初始化测试环境
  2. 调用 POST /vehicle/type/create 创建自定义车辆类型:
    • name: 新能源车
    • remarks: 测试新能源车辆类型
    • is_system: false
  3. 调用 GET /vehicle/type/all 查询所有车辆类型
  4. 断言:列表中应包含刚创建的 "新能源车" 类型

实际结果:

  • HTTP 状态码: 200 OK
  • 响应列表: 空数组
  • 测试断言失败: Vehicle type list is empty
  • 日志显示: 创建接口返回成功,但查询接口返回空列表

预期结果:

  • 查询接口应返回包含新创建车辆类型的列表

根因分析:

  • 创建接口和查询接口的数据一致性存在问题
  • 可能原因:
    • 创建成功后未正确提交事务
    • 查询接口使用了不同的数据源或缓存
    • is_system=false 的记录在查询时被过滤掉了
    • 分页参数导致第一条记录未被返回

四、Bug 优先级排序

优先级 Bug 影响范围 建议处理
P0 黑名单未拦截 安全漏洞,任何黑名单车辆可自由进出 立即修复
P0 删除接口 Panic 系统稳定性,可能导致服务崩溃 立即修复
P1 过期 VIP 免费停车 计费漏洞,造成经济损失 尽快修复
P1 无配置默认费率为 0 计费漏洞,无配置车型免费停车 尽快修复
P2 车辆类型列表查询为空 功能缺陷,新增类型无法显示 安排修复
P3 重复入场响应体为空 测试框架兼容性问题 低优先级

五、修复验证计划

每个 Bug 修复后,应运行以下命令验证:

cd "D:\lq\Smart Parking\lc_garage"
go test ./test/testutil/ -v -timeout 180s

重点关注以下测试用例:

  1. TestBlackWhiteListEntryExitBehavior — 黑名单拦截
  2. TestShortlistDelete — 删除接口稳定性
  3. TestVIPExpired — VIP 过期计费
  4. TestNoFeeConfig — 默认费率回退
  5. TestVehicleTypeCRUD — 车辆类型 CRUD
  6. TestVehicleReEntry — 重复入场检测

六、附录:通过测试清单

以下 19 个测试用例全部通过,核心业务流程正常:

序号 测试用例 说明
1 TestLoginFlow 登录流程
2 TestSystemManagement 系统用户管理
3 TestParkingInfrastructure 停车场基础设施
4 TestVehicleCRUD 车辆增删改查
5 TestFeeConfig 收费配置查询
6 TestVehicleEntryAndExit 车辆进出场闭环
7 TestBlackWhiteList 黑白名单基本操作
8 TestBlackWhiteListEntryExitBehavior 白名单进场/出场(黑名单部分失败)
9 TestOwnerManagement 车主管理
10 TestDashboardMonitoring 仪表盘数据
11 TestExitWithoutEntry 未入场车辆出场拦截 ✅
12 TestPaymentInsufficientAmount 支付金额不足处理 ✅
13 TestFreeDuration 免费时长内不收费 ✅
14 TestDailyCap 每日封顶费用 ✅
15 TestShortlistByPlateOrRFID 按车牌/RFID 查询名单 ✅
16 TestShortlistUpdate 名单更新 ✅
17 TestOwnerVehicleRelationship 车主关联车辆 ✅
18 TestParkingLotCapacity 停车场容量检查 ✅
19 TestBoothCRUD 岗亭 CRUD ✅
20 TestChannelCRUD 通道 CRUD ✅
21 TestDeviceCRUD 设备 CRUD ✅

本报告由自动化测试工具生成