36

你的测试写全了吗?

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MjM5MjY3OTgwMA%3D%3D&%3Bmid=2652470759&%3Bidx=1&%3Bsn=a113bd59cae397b96cbfcbcfb0d7be24
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

QA设计的测试用例大部分都是面向业务的端到端测试,怎么能保证从DB来的数据通过层层service能顺利的到达前端并被正确的展示出来呢? 我们可以尝试以UI和DB作为data flow的两端串起所有的测试。

场景

想象一个典型的场景,一次sign off接近尾声:

QA 这些个case都有测试吗?

DEV :打开各种IDE,UT cover了case A,JT cover了case B,API test cover了case C

Sign off结束了,但是代码里的测试真的覆盖了QA预期的全部用例吗?

假设一个系统的数据都存储在DB中,而UI是系统与终端用户交互的部分,那么数据在DB和UI之间通过各种service的互相调用而展示或存储的过程就是一种data flow。

QA设计的测试用例大部分都是面向业务的端到端测试,怎么能保证从DB来的数据通过层层service能顺利的到达前端并被正确的展示出来呢?我们可以尝试以UI和DB作为data flow的两端串起所有的测试。

举个例子

某项目有一个叫FileSharing的website,用户可以在上面共享文件。系统的设计是FileSharing Frontend向FileSharing Backend发请求获取file和user信息,FileSharing Backend向File Service发请求获取file信息,File Service从DB读取file信息。其中一个需求是当前用户可以看到自己和其他用户上传的文件,而他人上传且未被该用户下载过的文件名应该显示为粗体。根据这个需求设计出两个test case:

  • User should see new file in bold

  • User should see downloaded(or upload by himself) file not in bold

以这两个case为例,下图展示了数据在代码中的流动过程:

73URNnq.png!mobile

数据的流动方向是从DB到UI,检查测试代码可以先从数据消费终端的UI开始,目的是期望测试可以证明每一步正确处理和返回信息。

第一步:FileSharing Frontend

在file-store的测试文件里找到两个相关测试

  • should_be_shown_as_new_file

  • should_not_be_new_file_after_download

并且通过file-store的代码:

get isNew() {

return !!this.isNewDocumentFromOthers;

}

可以知道需要后端返回isNewDocumentFromOthers

结论 :查看代码已知file-store是前端页面的数据源,这个测试是在file-store level,没有测试保证html画出来相应的item

第二步:FileSharing Backend

打开user的file页面时,前端发了3个请求: 

/files

/files

/user/types

/user/verified

根据上一步得到的信息可以知道/files就是要找的请求

{

{

"id": "9a4af273-2d4e-4491-8f10-a93d2ba15e42",

"country": "US",

"fileName": "Instruction of FileSharing System",

"documentType": "Message",

"isNewDocumentFromOthers": true,

"uploadedAt": "12/16/2019",

"uploadedBy": "ad77d3fc-e0af-499e-8a71-ab020073db34",

"year": 2000

}

在FileController的测试文件里找到一个测试

  • should_flag_new_files_uploaded_from_others

并且通过FileController的代码:

public bool IsNewDocumentFromOthers(Guid userId)

{

return IsUploadedFromOthers() && DocumentType != DocumentType.Consent &&

(DownloadHistories == null ||

DownloadHistories.ToList()

.TrueForAll(HasNotDownloadedByUser));

}

可以知道FileSharing Backend需要File Service传来 IsUploadedFromOthers/DocumentType和DownloadHistory的信息

结论 :这个测试是在API level,基本可以覆盖当前测试用例,不过根据测试金字塔,API更多应该关注是否返回了需要的property,而property的值可以被下层的UT验证

第三步:File Service

在FileController的测试文件里找到一个测试,但是只验证了file的name/year/country

  • should_get_by_user_id

结论 :没有验证返回FileSharing Backend需要的IsUploadedFromOthers/DocumentType和DownloadHistory信息

测试覆盖分析

整理以上的步骤可以得到下面的图(标出了现有/缺失测试的部分)

E3QJvaj.png!mobile

如果从改善当前测试的角度出发,能得到当前测试结构下的测试用例覆盖表:(绿色表示测试基本可以覆盖用例,黄色表示有测试但是覆盖不全,在这个例子里File Service需要验证能返回正确的Uploadby/DocumentType和DownloadHistory的信息)

再从data flow的角度看可以发现更多问题:

  • UI层面没有对html做测试(风险较大)

  • 现有的测试大部分集中在API层面,service层以下的UT测试比较少

  • 服务之间缺乏契约测试导致修改一个API的时候只能人工检查被影响的范围

  • 测试使用的内存DB可能跟实际DB有差别(风险较小)

理想情况下,所有data经过的地方都需要有测试保证data flow不会断(数据被正确的处理和传输)。

改进

基于以上项目现状,可以得出几个投入产出比较高的action:

  • 在signoff的时候DEV可以试着给QA说明现有代码的结构,解释数据流动的方式,帮助QA理解目前测试覆盖的范围,评估没有测试的部分风险有多大,找出manual test的重点

  • 后端service数据传递时如果是靠API测试验证,则需要保证每个property都被测到

  • 保证前端每个view model的行为和状态都有JT cover

敏捷项目中开发写测试所依据的理论主要是测试金字塔,但是测试本身该写到哪一层并没有明确的标准可以遵循,当试着跳出测试金字塔的理论,从数据这个根源沿着data flow去看现有的测试,就会有一些新的发现,从根本上找出缺失或冗余的测试,确保测试做到更有效的覆盖。

- 相关阅读 -

测试人员价值的终极体现

如何知道我们的E2E测试覆盖率? fyIreev.jpg!mobile

点击【阅读原文】可至洞见网站查看原文 &绿色字体 部分的相关链接。

本文版权属ThoughtWorks公司所有,如需转载请在后台留言联系。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK