回归测试必须覆盖RETURN值、OUTPUT参数和结果集三类输出;只查SELECT结果是常见错误,漏掉@return_code或@status OUTPUT会导致关键逻辑失效被掩盖,tSQLt是SQL Server唯一能闭环隔离的方案。

回归测试必须覆盖 RETURN 值、OUTPUT 参数和结果集三类输出
只查 SELECT 结果是常见错误,漏掉 @return_code 或 @status NVARCHAR(10) OUTPUT 会导致关键逻辑失效被掩盖。比如一个转账过程返回 0 表示成功、-1 表示余额不足,但测试脚本没捕获 @rc,就永远不知道它是否真的拒绝了非法操作。
- 用
DECLARE @rc INT; EXEC @rc = dbo.usp_Transfer @from=1, @to=2, @amt=100;显式获取 RETURN 值 - OUTPUT 参数必须提前声明变量并加
OUTPUT关键字:DECLARE @msg NVARCHAR(100); EXEC dbo.usp_GetError @id=999, @msg=@msg OUTPUT; - 结果集要用临时表承接:
SELECT * INTO #actual FROM (EXEC dbo.usp_ListUsers) t;(注意:SQL Server 不支持直接INSERT ... EXEC到永久表,临时表更安全)
tSQLt 是 SQL Server 唯一能闭环隔离的方案
手写事务脚本容易漏 rollback、污染数据;外部 Python 脚本无法验证触发器、权限变更或临时表行为。tSQLt 的核心价值在于它强制每个测试在独立事务中运行,并自动回滚——你不用写 ROLLBACK,它在 EXEC tSQLt.Run 'test_class.test_proc' 结束后就清空所有变更。
- 安装前必须启用 CLR:
sp_configure 'clr enabled', 1; RECONFIGURE;,否则tSQLt.AssertEqualsTable等断言函数会报错 - 测试类名必须是 schema,且用
tSQLt.NewTestClass 'test_usp_transfer'创建,不能直接建普通 schema - 测试存储过程名必须以
test_开头、无参数,tSQLt 才会自动发现并执行 - 用
tSQLt.FakeTable 'dbo.Accounts'替换真实表,避免读写生产数据,也绕过外键约束干扰
MySQL 和 PostgreSQL 没有等效框架,得靠显式事务+隔离设计
MySQL 根本不支持数据库内测试框架,START TRANSACTION 后必须手动 ROLLBACK,且一旦存储过程中含 COMMIT 或 DDL(如 CREATE TEMPORARY TABLE),事务就不可逆——这类过程得标记为“不可测”,不能塞进回归套件。
- Python +
pymysql连接时必须设autocommit=False,并在finally块中调用conn.rollback() - PostgreSQL 用
pgTAP,但它的is()函数不自动包裹事务,必须手动写BEGIN; ... ROLLBACK;,否则测试跑完数据就留在库里 - 所有环境必须用最小权限账号执行测试,禁止用
root或sa——否则权限变更引发的ERROR 1142或ORA-00942永远暴露不出来
CI 中失败 90% 是环境漂移,不是逻辑错
视图或存储过程测试在本地通过、CI 失败?先别改代码,检查三件事:DDL 是否一致、测试数据是否隔离、数据库快照是否锁定。很多团队把脚本扔进 Jenkins 就叫自动化,结果每天失败告警全是环境问题。
- 测试前用
pg_dump --schema-only或mysqldump --no-data导出当前结构,与基线 DDL diff,不一致立即中止 - 禁止复用生产 dump;测试数据必须用脚本生成,每条记录带唯一前缀(如
'test_20260804_001'),避免跨用例污染 - 存储过程若依赖系统时间(
GETDATE())、序列号或随机值,测试用例必须 mock 或固定种子,否则结果不可重现

















