用机器学习来诊断自动化脚本失败原因的探索实践(用机器学习来诊断自动化脚本失败原因的探索实践)
先说下背景,相信在座大多数测试者都遇到过这样一个问题,频繁地排查自己业务线日常回归自动化脚本失败的原因。
而失败脚本形成的工单闭环在我们组更是纳入了考核!
其实大部分失败原因都是有迹可行,无非是环境问题、账号问题、脚本编写错误之类【此类问题在本司无法避免,测试环境不稳定,经常会导致各类rpc异常以及redis链接失败,另外线上预发环境账号无法实现自动充值,所以余额不足的情况也会经常出现】,既然我们没办法解决环境、账号问题,那么是不是可以另辟蹊径,此类问题导致的case失败是否可以帮我自动排查归类好,也能让我们组员省心省力。
方法抉择硬编码判断异常?
我们的自动化脚本都是统一用我们的自动化平台执行,所以可以收集到脚本所有的执行日志,包括失败后抛的异常信息。
所以理论上是可以判断每个异常的信息,if contains("rpc异常"),tell me ,这可能是dubbo连接失败,环境原因导致的失败
缺点:错误问题太多,每次升级都得去重新编码,不可能穷举所有异常。 out!
机器学习?是否可以引入机器学习? 我们训练一个机器狗,每次case失败抛异常后,我们人工训练它,告诉它,这个是环境问题!经过几百次的样本训练后,它就能排查出曾经经历过的所有异常,出现新异常后,就算排查失败,也能被人工纠正!
优点:全是优点
缺点:我不会,但是我可以问人!
到处咨询算法同学中。。。。算法同学告诉我两个算法比较符合我的需求:朴素贝叶斯算法 - 随机森林算法朴素贝叶斯算法优点:
- 逻辑简单,易于实现
- 所需估计的参数很少
- 对缺失数据不太敏感
- 具有较小的误差分类率
缺点:
- 在属性个数比较多或者属性之间相关性较大时,分类效果相对较差
- 算法是基于条件独立性假设的,在实际应用中很难成立,故会影响分类效果
个人总结:朴素贝叶斯算法常用于文本分类,精确度不算太高,基本原理就是基于统计学的概率分布,对样本的特证要求是互相独立,不能互相影响
随机森林算法优点:
- 准确率高
- 不仅能处理离散型数据,还能处理连续型数据,而且不需要将数据集规范化
- 训练速度快,能够得到变量重要性排序
缺点:
- 决策树过多的时候,训练要的空间时间会毕竟大
个人总结:随机森林基本就是决策树的升级版,常用于疾病风险以及各类风险问题的问题诊断
看了看上述两算法,既然做不了抉择,那都全都计算下看下准确率再选选实践出真理
可以看到机器学习的算法,都是大量计算样本的特征,不断学习特征之间的规律,然后用来预测,那我们就先来找特征
caseId |
caseEnv |
caseBiz |
status |
errorMsg |
errorRemark |
failreason |
1 |
pre |
1 |
断言失败 |
java.lang.AssertionError |
司机登陆 expected:<620014> but was:<200> |
脚本问题(3) |
2 |
stable |
2 |
执行异常 |
org.apache.dubbo.rpc.RpcException |
No provider available from registry 10.78.128.20:10228 for service |
环境问题(1) |
3 |
stable |
3 |
执行异常 |
redis.clients.jedis.exceptions.JedisCLUSTERException |
CLUSTERDOWN The cluster is down |
环境问题(1) |
......
我看了db,大概有300多条case失败已经被我们定位了原因,分布如下
- - 忽略 119条(一般脚本调试导致)
- - 环境原因 86条
- - 配置问题 56条
- - 脚本原因 49条
- - 代码问题 18条(一般是发现开发代码bug,或者可能疑似问题)
- - 其他(乱七八糟)
大家可能很奇怪,异常原因、异常信息作为特征很理解,为什么caseId、env也作为特征,其实把caseId、env放进来的考量是 可能不同case、不同环境就算是同一个异常也有可能是不同原因的导致的。并且随机森林算法是可以自动算出不同变量的重要性,所以加些轻量的特征不影响准确度
从数据库导入特征,分为训练样本、测试样本,比如3:1,分布进行朴素贝叶斯、随机森林预测
for row in results:
featureItem = []
dict = json.loads(row[3])
featureItem.append(dict["caseId"])
featureItem.append(dict["caseEnv"])
featureItem.append(dict["caseBiz"])
featureItem.append(dict["status"])
featureItem.append(dict["errorMsg"])
featureItem.append(dict["errorRemark"])
featuredict.append(dict)
feature.append(featureItem)
target.append(row[7])
targetnew = {"res": row[7]}
targetdict.append(targetnew)
dict = DictVectorizer(sparse=False)
featuredict = dict.fit_transform(featuredict)
targetdict = dict.fit_transform(targetdict)
x_train, x_test, y_train, y_test = train_test_split(featuredict, targetdict, test_size=0.25)
rf = RandomForestClassifier()
rf.fit(x_train, y_train)
y_predict = rf.predict(x_test)
print("随机森林预测的异常原因:", y_predict)
# 得出准确率
print("随机森林准确率为:", rf.score(x_test, y_test))
print("随机森林每个类别的精确率和召回率:", classification_report(y_test, y_predict))
# 进行朴素贝叶斯算法的预测
mlt = MultinomialNB(alpha=1.0) # 拉普拉斯平滑系数alpha
mlt.fit(x_train_b, y_train_b)
y_predict = mlt.predict(x_test_b)
print("贝叶斯算法预测的异常原因:", y_predict)
# 得出准确率
print("贝叶斯算法准确率为:", mlt.score(x_test_b, y_test_b))
print("贝叶斯算法每个类别的精确率和召回率:", classification_report(y_test_b, y_predict))
随机森林准确率为: 0.8690476190476191
随机森林每个类别的精确率和召回率: precision recall f1-score support
0 0.89 0.89 0.89 27
1 0.96 0.92 0.94 25
2 0.81 0.81 0.81 16
3 1.00 0.85 0.92 13
4 0.67 1.00 0.80 2
5 0.00 0.00 0.00 1
micro avg 0.90 0.87 0.88 84
macro avg 0.72 0.74 0.73 84
weighted avg 0.90 0.87 0.88 84
samples avg 0.87 0.87 0.87 84
贝叶斯算法准确率为: 0.6039603960396039
贝叶斯算法每个类别的精确率和召回率: precision recall f1-score support
0 0.55 0.91 0.69 35
1 0.62 0.81 0.70 26
2 0.00 0.00 0.00 18
3 1.00 0.44 0.62 18
4 0.00 0.00 0.00 3
5 0.00 0.00 0.00 1
accuracy 0.60 101
macro avg 0.36 0.36 0.33 101
weighted avg 0.53 0.60 0.53 101
```
随机森林测试了多次,准确率基本都在 85%以上,少数几次可以达到93%,另外可以看出基本预测失败的原因都在 4、5上(代码原因、其他),这还是训练的样本只有300 的情况,可以证明大部分的常见问题基本都可以正常预测
反观朴素贝叶斯算法基本只在60%-70%徘徊,抛弃!
应用后续的失败报警演进!
失败case统一异常信息暴露,自动归类,人工只要在完全不同的异常出现预测失败的情况下进行干预,另外干预后再出现此次异常,也会被计入模型,下次机器人也会自动判断准确了!
,
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com