目录
Q2:介绍一下你实习过程当中比较印象深刻的业务场景(或者印象深刻的bug)
本次改动的背景(新增了modify接口:入参为gender和uid,dpuid)
Q1:谈一谈你实习过程当中负责了什么?
我在百度的实习当中,担任的职务是测试开发工程师(实习生)。在工作当中,主要负责百度网盘的一刻相册的服务端测试。
首先,我想讲一下服务端测试的流程:
服务端测试流程
步骤1:参与需求评审
当产品经理提出需要实现某一个需求的时候,我们一般会组织开一个短会,在会议上面,产品经理会给出这个需求的描述。产出一个交互设计文档,然后技术细节会rd在后面补充进去。写到需求文档当中。
同时,rd和我们QA就会根据这个需求以及对应的需求文档,去考虑这个需求背后的数据库设计、接口的入参、接口的逻辑、各个代码模块之间的联调、返回值的断言等等。同时,我们QA同学也需要对于需求当中的一些边界值、异常情况处理等等向产品经理或者rd同学提出一些疑问,及时反馈等等。
步骤2:介入测试(详细)
在这个步骤当中,rd同学一般都已经把接口开发完成,然后就等待我们进行一些接口测试了。
他们在一般情况下面在提测单当中会写好本次改动或者新增的代码是哪些,以及改动的代码属于哪个模块。同时,在提测单当中也会附有需求文档和接口文档等等。
1⃣️接下来,我们QA同学就去icode上面找到对应的代码模块,拉取对应的代码到自己的服务器当中,启动服务。
2⃣️在数据库当中构造测试可能用到的数据,然后在接口自动化平台上面编写接口的入参以及断言等等情况,来验证接口返回值是否符合预期,功能是否正常等等。
3⃣️在请求接口的过程当中,如果遇到了功能不符合预期的情况,或者接口报错的情况,我们首先会通过日志来分析问题的原因,根据错误日志,来锁定问题,给rd提出解决的方案等等。
步骤二第一步:进行code review
也就是大致看一看代码,查看一下是否有比较明显的语法错误等等。
例如:数组越界、是否存在空指针异常等等。
同时,也需要了解清楚大致的代码逻辑,进行测试。
步骤二第二步:部署测试环境
在测试环境当中,我们需要安装一些必要的软件等等,例如mysql和redis。只有有了这些软件,我们才可以让运行的代码正常运行。
1⃣️接下来,我们QA同学就去icode上面找到对应的代码模块,拉取对应的代码到自己的服务器当中,启动服务。
步骤二第三步:设计测试用例
在了解了大致的测试流程之后,我们需要设计测试用例,包括每一个接口参数是什么?含义是什么等等。
步骤二第四步:接口测试&白盒测试
一般情况下,研发同学会提供一个接口文档和,包含入参是什么、出参是什么。然后我们需要看一下返回是否符合预期。
白盒测试:
我们需要根据接口传入参数的不同,进行白盒测试。
行覆盖(语句覆盖):该代码是否被覆盖到;
判定覆盖:每个判定的分支被测试到。(例如if,else分支等等)
条件覆盖:每个条件的取值至少满足一次。(if语句的各个条件)
此外的话,还需要进行一个步骤就是:进行存储有关系的校验,就是当我请求了接口之后,看一看数据库当中的数据有无写入进去,不应当只是看接口的断言是什么。(跟存储有关系的校验)
步骤3:关于bug(如果有)
bug的等级
当出现了bug之后,我们首先会去找rd同学确认这个bug是否真的与功能存在较大的差异。然后根据bug的影响,确定bug的等级。
最高一级为p0,这这个等级的bug一般就是出现了程序的崩溃,例如代码当中存在死循环、死锁或者锁未释放等等较为严重的情况。
但是一般情况下面,如果出现了逻辑错误,但是不会导致程序崩溃或者停滞不前的,我们一般顶级为P1级别的bug。
其余的P2往下的bug,一般就是一些虽然接口返回错误,但是不影响大体功能,或者就是一些可以优化的逻辑。
bug的处理过程
提出bug:open
开发认为是bug:fix
不认为是bug:not——a——bug==》close
认为是bug但是不是特别严重,选择等一下处理==〉delay
立刻处理,处理结束之后==》resolved:等待验证。
验证通过==〉close
验证不通过==》open
Q2:介绍一下你实习过程当中比较印象深刻的业务场景(或者印象深刻的bug)
在实习过程当中,我遇到了一个比较印象深刻的业务场景是关于一刻相册当中一个根据用户照片,AI智能生成数字人、写真的场景。
原始背景
原有的场景是:用户根据自己的百度账号,登录了一刻相册之后,可以看到一个AI印象馆的标识。
点击进去之后:用户需要上传20张照片,然后会根据这20张照片,请求智能化的接口,生成一一个数字人。这里的用户(user)和数字人的实体关系是(一对多):一个user可以对应多个digital_person_info。也就是一个用户可以制作多个数字人。
数字人有以下几个比较特殊的属性:
属性1:数字人的性别:0女1男;
属性2:数字人的文件缩略图id:fsid;
属性3:数字人的图片属性模板描述(一个json数组,里面包含了动作id,模板的代码描述id:数字人的性别+年龄的id,一共4个组合:例如成年男性是30100,未成年女性是31100......)
然后,每一个数字人下面又可以制作多套写真(protary_info),也就是数字人和写真的数据库关系也是一对多。
本次改动的背景(新增了modify接口:入参为gender和uid,dpuid)
之前用户制作成功了数字人,无法修改性别。但是本次需要对于用户制作的数字人修改性别、名称等等。当修改性别的时候,会再次请求智能化的接口重新制作数字人。
关于加粗字体的部分:
请求下游智能化提供了一个接口给我们,传入的参数主要是(uid)和数字人对应的(dpuid)。
这个接口返回的是一个errorno和msg和fsid。如果errno为0,那么我们在modify接口内部会接下来把gender修改为对应的值,同时修改fsid。
否则不会修改,并且把返回errno为-1,msg为下游的智能化接口返回的值。
技术细节:
(修改之前,数字人的status字段,也就是数字人的状态,设置为1。当用户点击了修改之后,也就相当于调用了modify接口:会首先把数字人的status修改为3:正在制作中)。
制作成功:
制作成功之后修改的结果如上面所说。同时会在modify接口当中把数字人的status改回1.同时更新性别和fsid。
制作失败:
制作失败之后,status改回1,返回errormsg。看到的端上的效果为:原来数字人的fsid对应的缩略图不变化,性别不变更,仍然为原来的值。
测试要点
①考虑性别变更成功的情况
②考虑传入的性别代号和模板对应的性别一致的情况(不可以变更性别)
情况2这种并不在基本事件流里面,但是为了提高代码覆盖率,还是需要测试一下这种情况。
③考虑传入的性别代号和模板对应的性别不一致的情况。(可以进行变更)
④考虑多个数字人同时变更性别的情况。(并发变更)
⑤考虑我方制作之后,下游智能化制作失败的情况。
⑥当前数字人如果正在变更性别当中,是否可以再次变更性别。
⑦当前的数字人,如果正在变更性别当中,是否可以被删除
......
测试发现的bug
在本次测试当中,令我印象比较深刻的bug就是:当数字人正在处于制作当中的时候,如果再次请求,仍然会再次触发请求下游的智能化接口,那么就会重新制作导致原来的那一次制作丢失。
开发一开始不认可
不认可的原因就在于:当制作数字人的时候,同一个设备的端上并不会暴露再次更新的接口,而是会显示“正在更新当中”。因此没必要对于数字人的状态进行限定。
但是:我发现,同一个账号,可以在不同的终端(设备)登陆,那么也就意味着,如果一个设备提示正在更新当中,另一个设备仍然会暴露“更新”的接口。
这个时候,如果在另一个设备B再次点击“更新”按钮,那么就会再次发起一次制作的任务。
每发起一次任务,相当于根据时间戳生成一个taskID。
当使用相同的uid,数字人id再次请求下游智能化接口的时候,如果数字人的状态为3(制作中),那么下游就会终止上一个taskID的制作,立刻回调,这样就会导致原来制作那一次任务的效果不符合预期,更新数字人的性别效果不好,也属于bug~~
给出的改进方案
对于一开始的数字人,先查询一次数据库,如果status为1,才可以进行修改,否则就不会修改。
本次测试遇到的困难
在联调下游智能化接口的时候,这个过程比较复杂。
第一步:需要明确下游服务启动的ip和port,http请求需要打到他们的服务器上面。
第二步:联调时候,需要在他们的服务器看到我们上游传入的logid。需要不断与他们进行沟通,观察日志的情况。
联调应该发生在测试的什么阶段?
首先,我方需要明确我们向下游的接口传入的参数是什么?明确我们传入的参数之后,启动服务之前,就需要开始准备联调了。因为我们请求下游的时候,需要做到:我们这边的问题及时被他们发现,或者他们的问题及时被我们发现,这个就是需要通过logID来传递消息,定位问题。
Q3:介绍一个令你印象最深刻的bug
bug发现的背景:在我完成了上述的测试之后,接下来几天由于没有其他任务可以做,于是我就站在用户的角度,多体验这个产品,看一看有没有bug。(在这里可以吹)虽然我发现的这个bug不属于本次迭代的周期,是一个历史的老bug,但是我认为,身为这个项目测试的一份子,我也需要对整个项目的用户体验负一定的责任。因为如果一旦这个bug被线上的用户发现,那么很可能以后用户对于我们这个产品的体验就会下降很多,所以为了避免出现线上问题,哪怕是不在我的职责范围内的,我也不希望出现~~
bug描述:前面提到了写真嘛,那么用户在制作写真的过程当中,点击了制作按钮之后,回到这个数字人的主页,就会看到数字人的主页呈现一个写真模版正在制作中的提示。
这个时候,我点击了删除当前制作中的写真,就发现删除之后,这个写真模版再也无法制作了,一直处于“正在制作中”的状态。
出现了这个bug我怎么办
第一步:由于这个问题是我在端上发现的,并不是在白盒测试这个阶段发现的。所以我先去在端上抓包,现抓的create接口(创建写真的),发现接口返回errorno为0。说明一开始创建写真的过程没有问题。(无问题)
第二步:然后再去调用delete接口,删除数字人,发现删除的接口的errorno也是0,说明此时写真正在呢制作当中的也可以删除(无问题)
第三步:然后再去调用create接口,发现返回的errorno为32210之类的,就是提示:这个模版正在制作当中,不可以再次创建。(有问题)
现bug之后我的态度
第一时间跟rd同学反馈,这个bug是个线上问题,并且把抓包的结果截图给他看。
得到的回复是:这的确是个bug,原因是:删除写真的时候,没有考虑写真正在制作当中的情况,忘记释放写真模版锁了,导致之前的写真一直处于制作当中。
需求前提:
然后,这边有一个需求就是:当用户正在制作当前数字人的写真的时候,不可以再次使用这个写真模版来制作。
也就是同一个uid下,即使有多个数字人,但是同一个写真模版不可以被同时多次制作写真。
上述需求是如何实现的
当用户调用create接口创建写真的时候,会首先查询一下缓存当中是否存在一个key,这个key是uid和写真模版的id(protaryID)拼接成的一个string字符串,并且设置了缓存过期的时间为86400S。
create接口的开头:
如果这个key存在redis当中,那么说明当前用户正在使用当前模版制作写真,也就是获取不到写真模版锁。
如果这个key不在redis当中,那么说明这个模版没有制作写真,于是就针对这个模版“上锁”。上锁的逻辑就是把key放入缓存(redis)当中。当写真制作成功之后,就释放模版锁:
create接口中间的逻辑:
根据模版id,数字人id等等信息创建任务,生成taskID、制作写真。然后把写真的fsid等信息落库。
但是,如果当前正在操作的写真模版的status为删除状态,就不会走到末尾:释放锁到部分。
create接口的末尾:
也就是当且仅当智能化制作成功之后,在create接口的末尾,删除这个key,让当前用户可以继续使用模版制作这个写真。
问题复现:
正在制作当中的写真,缓存当中是保留了这个key的。
原有逻辑:当写真正处于制作当中的时候,调用delete删除写真,那么只是把当前模板的数据库当中的状态修改为“删除”,并没有考虑删除掉redis当中的key。
理论上应当在修改了写真的状态之后,接下来的代码:把这个key给删除掉,但是一直没有删除,也就一直无法制作成功,也就是这个key一直在缓存当中,那么也就导致这个写真模版锁一直没有被释放。
这个时候:我提出修改代码方案:
方案1:调用delete接口删除正在制作中的写真时候,应当先检查当前这个模版是不是正在制作当中,如果是,那么就提示不删除。
方案2:调用delete接口的时候,直接清空缓存当中的key,达到删除的效果。
后面,我们和产品经理进行讨论:决定,为了方便用户更快地删除不想要的写真,建议采用方案2。