接口测试 接口测试、自动化有必要去数据库捞数据校验么

奇葩是朵花 · 2021年09月07日 · 最后由 Thirty-Thirty 回复于 2022年07月08日 · 9699 次阅读

我以前做接口自动化测试都是有增删改的操作后,调一次查询接口去校验,新公司很多人会去数据库校验,也没问出个所以然来。
比如我创建了一个商品,创建成功会返回一个商品 ID,我可以直接通过 ID 去查询这个商品;但是这边很多同学写了各种工具类去 mysql、ES 里捞数据出来断言,感觉很没有必要。
实在不清楚为什么要去 mysql,ES 里捞数据校验,我从查询接口去校验不是更符合业务测试场景么?

共收到 31 条回复 时间 点赞

接口测试就是通过查询接口去校验,否则就是单测的范围了

我觉得是测试深度和维度的选择问题。你说要到数据库和 ES 里面查询,那肯定业务上需要校验到这部分的数据,而这些数据的准确性可能是直接通过接口验证不到的。
另一个角度来看,存在即合理,你可以多问问团队里的同事为什么要这么做。说不定是因为以前出过类似的问题,所以才特地这么设计的呢?

我觉得接口肯定更要做数据校验的,接口不做等着 ui 做?

还是要做数据校验的,接口测试也要有预期值,这就要用到数据库或者 ES 数据了

db 和 es 校验的比较全面,而且可以确认存储,避免缓存影响等,接口校验比较快速,而且面向用户。

各有不同应用,无需每个 case 都用 db es,但是应该某些 case 覆盖到 db es 的。

主要看测试需求和查询接口的逻辑。
如果查询接口有特别的逻辑,调用查询接口满足不了测试需要,就得自己查。
无脑把所有你要验证的数据查出来的查询接口,可以用来验证。

自己去查的话应该是不信任查询结果或者担心查询接口业务逻辑变动影响自动化测试稳定性吧,当然也可能是顺手把存储一起测试了下。

个人理解:
1、查询本身也是接口,它的查询结果正确性也是未知的,以未知作为期望值还是有风险的
2、接口测试本身来说不应该依赖别的接口来做数据性校验,批量执行时,查询接口出问题,当前接口自动化用例其实相当于没有执行完成。流程性用例也应该是把当前接口作为前置用例来验证查询接口本身。
3、不一定所有需要校验的数据都可通过查询接口查询出来

主要看需求吧!
去 DB 可以查商品对应信息,可以自己组装查询,如果用接口查询可能返回信息没有那么全 (再说接口也是拿的数据库的)

个人理解:

1、根据你这个业务描述,mysql 和 es 都分别有存储,而查询接口很可能只是查其中一个库,另一个有可能就没提供查询接口?这种情况下,只通过查询接口,校验会不够完整。

2、我们以前是因为有一些入库操作是没有直接的查询接口可查的(比如日志表、流水表),或者查询接口查出来的不一定全(比如一些非业务系统用到,但大数据要用到的审计字段,创建时间、创建人之类的),所以要做数据库校验。

3、最主要的点,是数据库校验是对写接口逻辑最直接的校验方式,毕竟写接口的逻辑本质就是在写入数据库,而查询接口已经是另一段和写无关的读逻辑了,为了性能有可能先读缓存,后读库。在极端情况下有可能两个都错在一个位置(比如代码逻辑都映射为 1=false,实际数据库定义 1=true),反而最后看起来是对的结果。这种情况下可能会导致基于数据库数据进行处理的下游应用(比如大数据报表)出问题。

陈恒捷 回复

1、2 点,比如我们的操作日志表,是先写 mysql,再同步 ES,然后日志的查询统计这部分的查询接口走的是 ES,因为我们是中台接口,提供的能力基本是可以做到全量字段的返回的;
关于 3,我觉得写和读虽然是两个无关的逻辑,但最终的业务展现是体现在读上的,所以走查询接口在能查到需要字段的情况下,我觉得是更符合业务测试场景的一种方式;至于你说的极端情况,理论上是会存在,但是再手工校验的过程中是会发现这个问题的。
可能我问题描述的不是很清楚,在手工校验的阶段,是会人工去数据库比对一下数据的,但是写自动化脚本时还有没有这个必要?

实在不清楚为什么要去 mysql,ES 里捞数据校验,我从查询接口去校验不是更符合业务测试场景么?

违反测试独立性原则,耦合了

主要的原因是数据不一定都有对应的查询接口,或者接口不一定返回所有字段,所以保险起见还是直接从数据存储的地方进行校验。而且查询接口设计成返回所有数据不一定是一种好的做法。

steve 回复

我们是中台接口,接口能力会尽可能提供的完全些,具体要传哪些查询字段,返回哪些数据由业务放的后台再进行编码

独缺 回复

嗯,第二点比较认同,耦合带来的问题可能会导致测试接口无法执行

单接口的测试和接口串联场景测试,可以用不同的校验方式,看业务需求吧

所以走查询接口在能查到需要字段的情况下,我觉得是更符合业务测试场景的一种方式

这里有一个点,校验数据库数据 != 不测试查询接口逻辑。只是把 写接口->读接口 ,进一步拆细为 写接口->数据库验证, 数据库数据->读接口验证 。拆细的好处校验的内容更独立,失败时排查范围也更小(读 + 写 fail 时,你还得通过查库来排查是写的问题还是读的问题)。

所以在符合业务测试场景方面,两个是没差别的,差别只是要不要多做数据库校验这一步。

在手工校验的阶段,是会人工去数据库比对一下数据的,但是写自动化脚本时还有没有这个必要

这个说实话,看实际业务和自动化脚本可以投入的成本有多少。从最严谨的角度说,查库会比不查库更独立,适用范围也更广(特别对于查接口没有那么完备,或者写和读并非一一对应的情况下),问题定位也更高效(比如 fail 时,可以把范围缩小到只是写接口有问题)。但如果说可投入成本有限,且查的接口也确认可以满足,外部业务都只会通过接口而不会通过数据库获取数据,那仅在接口层面确保写和读保持一致,不校验数据库的实际数据情况,也是可以的。

写自动化脚本有没有必要做数据库校验,取决于你是否信任没有校验数据库的脚本的执行结果,是否可以明确认为写 + 读组合逻辑的正确就可以认为功能正确。如果能信任,那就没问题。

@fnngj
接口测试需要验证数据库么?
https://www.cnblogs.com/fnng/p/7494682.html

接口自动化模拟的是开发的代码操作,A 开发写的接口给 B 开发去调用,A 系统的接口给 B 系统去调用,假设我是一个开发,我调用了微信的接口去做获取用户头像,有个用户获取不到,来!微信团队,你让我查查你们的数据库呗!微信肯定不答应。(数据库不是你想查,想查就给你查!)

Thirty-Thirty 回复

来!微信团队,你让我查查你们的数据库呗

完全不能同意,这是偷换概念……我调微信接口并不是我在测试微信接口,而是我自己的业务功能拿微信接口的返回结果作为数据源,默认微信接口的逻辑绝对不会有问题,这个 “不会有问题” 自然有微信团队的测试人员去验证,微信团队测试自己的接口的时候一样可以去数据库查数据验证的。
不然,按照虫师这种逻辑,我们要验证结果是否正确,要得给 oracle、mysql 这些数据库产品做一套完整的测试先保证数据库产品没有问题……

槽神 回复

个人倾向认同@fnngj 观点:

是不是写接口自动化的时候验证数据库就万事大吉了? 数据库没问题就一定 OK ?
所以,分层自动化测试是多维度的。
UI 自动化有自己就应该 从用户的维度写考虑用例的设计。
接口自动化也应该只通过接口的调用去验证数据。
单元测试验证代码的处理逻辑覆盖。
手工(功能)测试、探索测试 也是非常重要的手段。

希望虫师参与讨论,发表高见。

要么数据库要么关联接口校验。建议这两个都用,只是数据库校验不是每个接口都要用的

测试讲究的是指定的输入得到预期的输出,那接口测试怎么验证实际结果就是预期的呢?
所谓去数据库捞数据校验并不是有没有必要的问题,而是比较省事的做法,而且这只适用于开发告诉你测试的 api 一定能在数据库中产生或修改一条记录的场景。
拿注册用户为例,接口返回注册成功了并不能保证接口一定没有问题,你得调用登录接口验证,那谁能保证登录接口又是好的,还不是数据库里查比较方便么。
按这个思路,我们只要查不出记录就说明接口有问题,具体原因可以再排查,就算是数据库产品的自身问题也不影响被测接口不可用这个事实。

我觉得没毛病啊, 你要从查询 API 结果来对比也可以啊。 2 者不冲突啊。

@Thirty-Thirty 我之前的那篇文章以及下面的讨论,已经比较充分的说明了我的观点,个人更倾向于 每层做每层的事情。 如果不按照自动化分层的思想来,我可以在跑 UI 自动化的时候去验证数据库。 或者跑 UI 的时候,启动一个服务监听抓包,顺便也把接口给测试了,行不行?当然可以!这只是手段,目的是保证质量,发现 bug。

我之前的场景是接口用例后置,就是接口提测之后,边写接口自动化用例边测试,这个过程中会读接口代码逻辑 + 验证数据库,但是自动化用例里面没有操作验证数据库的逻辑。 后续就可以愉快的跑接口自动化了,每次迭代新增接口自动化用例。从经验来来,接口自动化失败一般是接口删除、修改导致。几乎没有遇到过,接口告诉我成功了,但是压根就没有更新数据这种低级错误。 如果我遇到这种问题,我会把他扼杀在我编写接口用例阶段。

最后,我认为单元测试更适合验证数据库。已 django 框架为例:
https://docs.djangoproject.com/en/3.2/topics/testing/overview/

最后,上面引用微信接口的例子确实不当。

虫师 回复

敞亮!
这气度,绝对是个持续成长型大佬,佩服。

若认真 (或较真) 地思考,去数据库捞数据这种结果验证手段是经不起推敲的。
我第一次遇到这种事,是关于供应商信息修改接口测试的验证,几个同事采用的是根据供应商 ID 查询数据库,检查对应列是否已被正确更新。我当时陆续提出以下质疑:

  1. 仅检查修改对应列就行了吗?若其他列被意外更新了呢?
    同事 A:哦,要考虑,我现在就加上!
    同事 B:不需要考虑,那不可能发生!

  2. 仅检查该 ID 对应字段就行了吗?若其它字段 (对应其它供应商信息) 被意外更新了呢?
    同事 A:哦,要考虑,我现在就加上!
    同事 B:不需要考虑,那不可能发生!

  3. 其它已有字段也检查了就行了吗?若意外多出一条字段呢 (比如多了条空的供应商信息)?
    同事 A:哦,要考虑,我现在就加上!
    同事 B:不需要考虑,那不可能发生!

  4. 仅检查这张表就行了吗?若关联表未被更新或被意外更新呢?
    同事 A:哦,要考虑,我现在就加上!
    同事 B:哦,是有可能,但考虑那么多干嘛!

  5. 关联表也检查了就行了吗?若非关联表被意外更新了呢?
    同事 A:哦,要考虑,我现在就加上!
    同事 B:哦,这倒是,那是不是就不该检查数据库?!

上述 5 种情况,包括 B 认为不需要考虑的事情,后来都发生了,他的态度是逐步转变的。
所以,我个人倾向认同 20 楼观点。

看公司的接口测试是前置执行,有专一独立接口测试人员从接口开发完毕就介入第一轮接口测试,产生第一轮基线脚本。
然后前端开发联调结束后,第二轮接口脚本修正。然后业务手工测试人员介入进行全面的系统业务测试,这期间在和手工业务测试人员和接口开发接洽,第三轮接口脚本修正。
这是我个人设计的比较好的,全周期专人接口测试模式,最终接口脚本框架,是有原子性的基线脚本。和一定场景度的场景脚本两大模式。同时如果公司手工业务测试人员推广的好,有一定接口脚本自组装能力,可以用专人接口人员的接口脚本进行自我业务的复杂接口场景的场景化脚本组装。这样就打通了 纯接口脚本人员和业务测试的边界,更好的把握纯接口问题和业务方面的接口上的业务实现规则问题。

还是接口测试,如果不是上边的模式,就比较难办,会带来许多风险。
比如这个专业或不专职的接口测试,是完全滞后的在业务系统测试完,才独立去理解业务理解服务接口,整了一套。可能这种就是纯接口测试,完全相信手工业务测试是没问题或少量问题的。这样就比较麻烦,因为手工系统业务测试,又取决于这个手工业务测试人员的能力和测试水平能否完全测全服务端的接口问题,就比如数据的落地校验,是否在手工业务测试做了强检查强校验,完全熟知页面 -- 服务接口 -- 数据库表字段 的变化。这个各个公司的业务测试要求又不尽相同,笔者面试过程发现,许多无论是外包还是独立产品独立项目的公司,那真是千差万别,手工业务测试的套路和系统性规则性都完全不一致,外包好的给你数据库堡垒机去查,有的测试完全不熟悉业务表结构关联和字段与服务接口 前端界面的对应关系,可能只是依靠管理后台类的工具去验证前端的数据表单提交类接口。好点的独立产品项目型公司,就给足权限,自己反映射生成表拓扑结构图,各类数据表权限都给足。且该公司测试经理,有强要求关注 界面 接口 库的三者字段一致性。这种后期开展第一模式的接口测试就比较好。

所以这是一个,公司测试流程和对接口测试理解的一个流程性问题,阶段性问题,如果是第一模式,就可避免许多接口测试上的理解偏差。

第一模式下,业务手工测试 做到了 前端界面 服务接口 数据库表字段的强认证 关注,强校验,也可以后期第二轮 第三轮测试阶段中,和专职的接口人员沟通交流,来确保落地数据库验证的。
如果你非要做到剥离数据库验证,那么请先保证你们公司的业务手工系统测试人员,可以和你友好的交流 三端数据验证问题,和他确实保证所有业务的落地数据 提交类 查询类 都和数据库表关联查询验证过,完全熟知各种有服务接口交互的表查询。并可和接口专职人员指导交流和沟通。但实际上,很多公司是第二模式,没办法做到业务手工测试后的质量,这时候又是个只做专职接口的,可能就只是做做接口返回认证,但这是有风险的,接口是会欺骗你的,操作错相似表或字段的。

所以,我的建议是 如果是第一接口测试流程模式 且手工业务测试人员可以和服务接口人员一起参与接口测试的,可能越前期是需要数据库认证的,磨合好了后,接口的数据验证可以依赖接口返回验证了,再想办法剥离数据库验证。
如果,是第二接口测试流程的,比较麻烦,如果接口测试人员 对接口场景和业务更敏感,建议带上数据库验证,然后推广第一种测试流程。

Thirty-Thirty 回复

很赞同!我在电商公司的时候,这几种场景都遇到过,表示很头疼

首先你的接口测试是什么?其实是功能的测试,功能测试是属于黑盒范畴吧,黑盒测试关注的是啥,通过改变输入影响输出,然后验证输出。
输出包括什么?接口的返回、数据库的新增、更新,调用第三方系统的 API 的请求等,都是输出,都是需要检查的。
你手工测试要检查的内容,按道理来说,自动化测试就应该检查。手工和自动化之间,在证明一个被测功能的正确性上,是不应该有本质的区别的。手工和自动化的差别,只是谁执行 testcase 而已。
如果你的自动化,什么都不检查,那么你的自动化测试的测试结果又凭什么能让你信服?

目前我们团队做接口测试,是把接口响应、数据库校验、发送到第三方的请求、消息队列的信息、redis 的信息都做了检查的

Thirty-Thirty 回复

所以,到底要不要检查数据库?

树叶 回复

对于要不要查数据库这个问题,个人倾向认同的观点已经在 20 楼给出了引用。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册