除了日常测试,还兼着 FineBI 上数据运维的工作。一个新版本功能上线后,运营需要我提供对应的运营数据,我就向开发咨询对应业务及提供对应 sql 给我参考

原业务复杂其关联多表,但概括来说就是有个查询第三方商品价格记录表 [T]:
|log_id| sku_id | price | delete_flag | add_time |

为了便于理解,补充说明下:

需求是:获取每个 SKU 没删除的最新的价格信息(注:没有相同的 add_time)

一般这种分组排序取最新,oracle 或 impala 的查询 sql 通常都用:
row_number() over(partition by sku_id order by add_time desc) as rn ...where delete_flag=0
然后筛选 rn=1 来做。
不能用这类函数的,可以用下面这种通用写法:
select *
from T t0
join (select sku_id,max(add_time) max_add_time from T where delete_flag=0 group by sku_id) t1
on t0.sku_id=t1.sku_id and t0.add_time=t1.max_add_time

而开发将其对应功能列表的 sql 发给参考,却是类似是这种:
select t0.*
from T t0
where t0.delete_flag=0
and not exists (select * from T t1 where t1.sku_id=t0.sku_id and t1.add_time>t0.add_time)

开发说不要用那个麻烦分组排序,用这个就行了......

其实,虽然这段时间一直和 sql 打交道,但也确实没想过用 not exists 来实现类似的分组取最新的场景。
但这个 sql 却是有问题的:

  1. not exists 会进行主表全扫描,如果很大,性能势必有新影响,但这个不是我关心的。
  2. sql 的结果有 BUG:not exists 后表没有加上条件 delete_flag=0,也就是外表和内表不是同条件的。

那么, 如果存在这样的数据,sku_id-123 就会查询不到:

log_id sku_id price delete_flag add_time
11111 123 10.2 0 2022-08-01 01:01:01
11200 123 10.3 1 2022-08-02 01:01:01

无法确定测试人员为啥没有测出该 BUG,可能是凭经验过于相信开发(是个老开发),用了简单方式:从既有的列表结果来看是否最新的。

而我也自省了一番:如果是我,会不会也会遗漏?

  1. 这是个小需求点(相对于此版本的其他功能),会不会花心思好好设计一番测试场景:还只是简单看下既有的列表结果?
  2. 从场景设计出发,最容易想出以下场景:

你看,从需求角度正向设计用例场景很自然也很习惯,很容易就这样了。

而 “1 个 sku 既有有效,也有无效,且无效的时间大于有效的时间” 这类场景则需要对这个需求点再上点心。

工作多年了,经历瀑布 - 敏捷-DevOps 的过程:为了赶时间,现在不少测试工作都是凭经验来,虽然没出过啥岔子,但也从这个例子上吸取了点教训。

  1. 再小的需求规则都要好好设计测试场景,勿要随意
  2. 有能力的话,还是得看看开发的代码


↙↙↙阅读原文可查看相关链接,并与作者交流