导读:近期Flaky Test逐渐成为很多开发团队关注的热点,本文就Flaky Test的背景、定义、根因、检测思路做以简单介绍。
“说谎者不再被信任,即使他说的是真相”
—伊索。
回归测试
程序员小猪搭建了个自动化测试框架,“一键”即可运行系统中的测试用例,一旦系统功能模块受到破坏,对应的测试用例就会运行失败。当系统
* 部署了新模块、
* 提交了补丁、
* 重构了代码、
* 更改了参数配置,
小猪都会跑下系统中的测试用例。如果有测试失败,就意味着新提交的代码存在缺陷且破坏了原系统的功能模块,小猪就会告知开发人员进行修复。
因为此系统,小猪很受欢迎。团队领导表扬小猪的自动化测试框架用人少、检测快,大大提升了开发效率。团队成员感激小猪的系统避免了自己写的bug流入系统。小猪很是开心。
Flaky Test
然而好景不长,小猪陷入了苦恼之中。事情经过是这样的:
1.程序员小马在系统上部署了新模块,小猪跑完测试后,发现有测试用例失败,就告诉小马其代码有缺陷,需要修复;
2.小马按照小猪提供的测试用例(回归测试中失败的测试用例)去调试缺陷。然而,这次不同于以往,小马分析了半天也未能确定自己的哪块代码有问题;
3.不得已,小马去找小猪重跑该测试用例,想获得更多信息来定位缺陷。然而,当再次运行时,该测试用例并竟然神奇地运行成功了。
小马
什么?运行成功,浪费了半天调试不存在的缺陷?×&%¥#@……”(一顿“喷”小猪)
小猪
什么?同样的测试用例,同样的代码并没有任何改变,怎么前面失败了,这次跑成功了?(一脸的困惑)
经过多番调查,小猪了解到了Flaky Test的概念:测试用例在同一个版本的系统上运行多次,有的运行成功,有的运行失败,这样的测试用例被称为Flaky Test,又称不可靠测试用例。小马的案例就是属于这种情况,小猪报告给小马的测试失败不是缺陷引起的,而是Flaky Test引起的。
更糟糕的是,随着系统规模的增大,这样的Flaky Test越来越多,很多程序员开始给小猪抱怨,Flaky Test误导他们调试不存在的缺陷,浪费了精力与时间。更严重的是,他们不再那么相信测试结果了,当小猪再报告提交的代码有缺陷时,都会应付说“你先确定是不是缺陷导致的测试失败,然后再来烦我”。团队的开发效率也因此受到了影响,团队领导对小猪很有意见。
根因分析
小猪emo了好久,决定调查Flaky Test的根因。经过分析,大致分为如下几类:
①并发引起的。系统涉及到多线程,线程执行顺序是不确定的,而开发人员写的测试用例只应对了部分线程执行顺序,当某些测试运行中出现了未考虑到的执行顺序时,就会导致测试运行失败。
②异步引起的。系统涉及到异步通讯,其通讯时间是不确定的。开发人员在写测试用例的时通常会预估一个相应的时间,大部分情况下,异步通讯都能够在预估时间内执行完成,测试用例成功运行,然而也有异常情况,即异步通讯时间超过预估时间,导致测试失败。
③执行顺序依赖引起的。有些测试用例会依赖特定的测试用例执行顺序,如果执行顺序改变了,测试就会失败,比如Test1是检测一个链表是否为空,Test2是检测能否向该链表中插入一个元素。如果执行顺序是Test1àTest2,那么测试就能成功。如果是Test2àTest1,测试就会失败。
④资源泄露引起的。有些测试用例会导致资源泄露,比如内存泄露。如果测试机器的负载较轻,测试能够成功完成,如果负载较重,则可能因资源不够而导致测试失败。
⑤系统时间引起的。很多测试用例涉及到系统时间,程序员经常以某个特定时区的时间为准,而测试用例可能会在别的时区内执行,就会导致有些时段测试成功,有些时段测试失败。
⑥返回值区间要求过于严格引起的。开发人员通常会使用预定好的值来判断测试是否成功,有时设定的值的范围过于严格,会导致某些执行结果落在预定值之外,导致测试失败。
⑦随机数引起的。开发人员有时候会在测试用例中使用随机数,当某些边界值没有考虑到时,就会导致测试用例执行失败,比如除数是随机数时,就可能出现除以0的情况。
Flaky Test检测
虽然flaky test的根因弄清楚了,如何检测Flaky Test仍然是个问题,一番调查后,小猪发现了如下方案:
①“消极”重跑法。当一个测试用例失败后,重跑该测试用例n次(比如n=5),如果其中某次或多次运行成功,即认为该测试用例为Flaky Test,该方法简单且易于部署。
小猪的担心:该方法虽然简单易行,但存在两个问题:1)检测的成功与否完全靠运气,重跑的结果很可能都是一样的,没有任何保证;(2)系统测试用例数量巨大,每次运行会有上千个测试用例失败,如果都是重跑n次,耗时长,成本高。
②“积极”重跑法。这类方法以测试套件为输入,逐一检查测试用例是否为Flaky Test。其方法是多次运行测试用例,如果发现测试用例既有成功又有失败就标记为Flaky Test。为了让Flaky Test能够展现出不可靠性,重跑过程中,会采用各种手段来提高发现Flaky Test失败的概率,比如:
1)DTDetector[1]、iDFlakies[2]通过改变测试用例的执行顺序尽可能快地发现执行顺序相关的Flaky Test失败;
2)FlakeScanner[3]在测试运行中,通过探索不同的事件序列来发现与并发相关的Flaky Test失败;
3)Shaker[4]通过在运行环境中添加“噪音”,比如增加CPU的负荷,来发现与并发相关的Flaky Test失败。
小猪的担心:虽然该类方法提高了Flaky Test检测的成功率,但仍存在问题:1)系统测试用例数据巨大,多次重跑,耗时长,成本高;2)标记出的Flaky Test并未在回归测试中展现出不可靠的现象,程序员不太乐意去解决,比如修复或者隔离等。
③“积极”标注法。这类方法提取已有的Flaky Test的特征并训练一个模型,通过模型来预测一个测试用例是否为Flaky Test,比如:
1)FlakeFlagger[5]通过收集Flaky Test的特征如测试用例坏味道等,根据这些特征预测Flaky Test;
2)Flakify[6]在语言特征预模型之上,通过测试用例坏味道特征数据重训练来获得Flaky Test的检测模型。
小猪的担心:这类方法虽然不用重跑测试用例,但也存在问题:1)建立预测模型需要大量的标注数据,现实中很难构建这样的数据集;2)预测模型的准确率难以保证,并且标记出的Flaky Test并未在回归测试中展现出不可靠的现象,程序员不太乐意去解决。
小猪的理想
虽然已有很多方法,但都未能完美解决小猪的问题。小猪希望能有一套与开发流程吻合、切实可行的Flaky Test检测方法,具体而言:
①针对Flaky Test失败的检测工具。困扰小猪的直接难题是,一次回归测试可能会有上千个用例失败,如何从这些失败中快速辨别出Flaky Test失败,避免给开发人员带来困扰。
②无需重跑。当回归测试完成后,无需重跑即可识别出Flaky Test失败。
参考文献
[1] Sai Zhang, Darioush Jalali, Jochen Wuttke, Kıvanç Muşlu, Wing Lam, Michael D.Ernst, and David Notkin. 2014. Empirically revisiting the test independence assumption. In ISSTA.
[2] Wing Lam, Reed Oei, August Shi, Darko Marinov, and Tao Xie. 2019. iDFlakies: A framework for detecting and partially classifying flaky tests. In ICST.
[3] Zhen Dong, Abhishek Tiwari, Xiao Liang Yu, and AbhikRoychoudhury.2021. Flaky test detection in Android via event order exploration. In ESEC/FSE.
[4] Denini Silva, Leopoldo Teixeira, and Marcelod’Amorim.2020.ShakeIt!Detecting Flaky Tests Caused by Concurrency with Shaker. In IEEE International Conference on Software Maintenance and Evolution.
[5] A. Alshammari, C. Morris, M. Hilton and J. Bell, "FlakeFlagger: Predicting Flakiness Without Rerunning Tests," 2021 IEEE/ACM 43rd International Conference on Software Engineering (ICSE), 2021, pp. 1572-1584, doi: 10.1109/ICSE43902.2021.00140.
[6] Fatima S, Ghaleb T A, Briand L. Flakify: A Black-Box, Language Model-based Predictor for Flaky Tests. TOSEM 2022.
作者简介
董震,复旦大学计算机科学技术学院青年副研究员,上海市领军人才(海外)计划入选者。2017年获得德国海德堡大学博士学位,2017年至2021年在新加坡国立大学计算机系任博后研究员,致力于软件分析与软件测试的相关的研究,获得ICSE'20 ACM SIGSOFT Distinguished Paper Award、AsiaCCS’21 Best Paper Award (1/370)、TOSEM Distinguished Reviewer等奖项或荣誉称号,长期担任国际知名期刊审稿人、国际会议程序委员会委员。
CodeWisdom
Codewisdom平台由复旦大学软件工程实验室运营,提供智能化软件开发平台及线上沙龙相关资讯,关注可了解更多智能化软件开发的最新消息~