背景

先说下背景,相信在座大多数测试者都遇到过这样一个问题,频繁地排查自己业务线日常回归自动化脚本失败的原因。

用机器学习来诊断自动化脚本失败原因的探索实践(用机器学习来诊断自动化脚本失败原因的探索实践)(1)

而失败脚本形成的工单闭环在我们组更是纳入了考核!

其实大部分失败原因都是有迹可行,无非是环境问题、账号问题、脚本编写错误之类【此类问题在本司无法避免,测试环境不稳定,经常会导致各类rpc异常以及redis链接失败,另外线上预发环境账号无法实现自动充值,所以余额不足的情况也会经常出现】,既然我们没办法解决环境、账号问题,那么是不是可以另辟蹊径,此类问题导致的case失败是否可以帮我自动排查归类好,也能让我们组员省心省力。

方法抉择
硬编码判断异常?

我们的自动化脚本都是统一用我们的自动化平台执行,所以可以收集到脚本所有的执行日志,包括失败后抛的异常信息。

所以理论上是可以判断每个异常的信息,if contains("rpc异常"),tell me ,这可能是dubbo连接失败,环境原因导致的失败

缺点:错误问题太多,每次升级都得去重新编码,不可能穷举所有异常。 out!

机器学习?

是否可以引入机器学习? 我们训练一个机器狗,每次case失败抛异常后,我们人工训练它,告诉它,这个是环境问题!经过几百次的样本训练后,它就能排查出曾经经历过的所有异常,出现新异常后,就算排查失败,也能被人工纠正!

优点:全是优点

缺点:我不会,但是我可以问人!

到处咨询算法同学中。。。。算法同学告诉我两个算法比较符合我的需求:朴素贝叶斯算法 - 随机森林算法朴素贝叶斯算法

优点:

- 逻辑简单,易于实现

- 所需估计的参数很少

- 对缺失数据不太敏感

- 具有较小的误差分类率

缺点:

- 在属性个数比较多或者属性之间相关性较大时,分类效果相对较差

- 算法是基于条件独立性假设的,在实际应用中很难成立,故会影响分类效果

个人总结:朴素贝叶斯算法常用于文本分类,精确度不算太高,基本原理就是基于统计学的概率分布,对样本的特证要求是互相独立,不能互相影响

随机森林算法

优点:

- 准确率高

- 不仅能处理离散型数据,还能处理连续型数据,而且不需要将数据集规范化

- 训练速度快,能够得到变量重要性排序

缺点:

- 决策树过多的时候,训练要的空间时间会毕竟大

个人总结:随机森林基本就是决策树的升级版,常用于疾病风险以及各类风险问题的问题诊断

看了看上述两算法,既然做不了抉择,那都全都计算下看下准确率再选选

用机器学习来诊断自动化脚本失败原因的探索实践(用机器学习来诊断自动化脚本失败原因的探索实践)(2)

实践出真理

可以看到机器学习的算法,都是大量计算样本的特征,不断学习特征之间的规律,然后用来预测,那我们就先来找特征

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失败已经被我们定位了原因,分布如下

大家可能很奇怪,异常原因、异常信息作为特征很理解,为什么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统一异常信息暴露,自动归类,人工只要在完全不同的异常出现预测失败的情况下进行干预,另外干预后再出现此次异常,也会被计入模型,下次机器人也会自动判断准确了!

用机器学习来诊断自动化脚本失败原因的探索实践(用机器学习来诊断自动化脚本失败原因的探索实践)(3)

,