****************************************************************************
本文主要介绍借助自动化框架实现-短文本相似度模型测试
1.测试需求分析
2.测试环境准备
3.测试数据准备
4.测试分析与执行
5.测试问题总结
****************************************************************************
一、测试需求
1)原始需求:测试短文本相似度接口能力是否符合指定的模型效果
2)理解需求:验证接口的功能、模型评估、性能是否符合需求文档
3)需求思考:短文本相似度是判定2个文本在语义上是否相似,目前使用场景包含信息检索图片、视频、文本等、新闻推荐、智能客服等,本次测试的应用场景是? 研发回答:没有指定场景(这是一个坑!!!)
二、测试环境准备
本次测试接口能力均已封装为镜像文件,所以直接拉取镜像启动即可!
1) 启动能力镜像:
CPU版本:
docker run -d -p 5000:5000 -v /dep_pic/wwq/data/TextSimilarity:/home/TextSimilarity/Data text_similarity_cpu:v1
GPU版本:
docker run -d --gpus "device=1"(显卡号) -p 5000:5000 -v /dep_pic/wwq/data/TextSimilarity:/home/TextSimilarity/Data text_similarity_gpu:v1
2) 代码运行日志在映射目录下Log文件夹中startup.log文件中,查看日志命令为cat startup.log,如下则服务已成功启动:
三、测试数据准备
1)数据分析:需求分析阶段了解到模型并没有指定使用场景,且模型训练依赖主要CMNLI语料库,通过分析CMNLI语料库场景比较单一,经测试建议增加LCQMC语料库,丰富模型使用场景,使模型效果更理想!
2)语料库数据展示
四、测试分析与执行
1)测试方法分析:功能测试利用Postman工具(不讲),模型评估测试利用公司自动化接口框架实现,性能测试利用JMeter工具(不讲)
2)模型评估测试执行
A、获取评估指标预期值:模型评估包含那些指标,通常会在需求文档里面体现出,代表算法工程师自测的结果,如
B、获取评估指标数据量级与数据分布情况:算法工程师通常有2个数据集,训练集与测试集,如本次测试算法工程师训练集在十几万数据,相似与不相似数据分布比例是1:2,所以我的测试数据设计为:相似1000条,不相似2000条
C、执行模型评估测试,本次测试利用公司自动化接口框架,具体框架的架构、涉及技术不是本次重点,本次重点说一下模型评估自动化的实现方法,以往模型评估过程都需要测试人员整合测试结果,然后手工统计出指标值,结果准确性无法保证耗时也比较久。话不多说,直接上代码:
AItool工具类:利用sklearn模块evaluate函数,直接输出模型指标值,如准确率、精确率、召回率、F1 score
sklearn详细用法参考博客:https://blog.csdn.net/hfutdog/article/details/88085878
def evaluate(y_true, y_pred):
Precision_Statistics = {
'precsion': {
'micro': precision_score(y_true, y_pred, average="micro"),
'macro': precision_score(y_true, y_pred, average="macro"),
'weighted': precision_score(y_true, y_pred, average="weighted")},
'recall': {
'micro': recall_score(y_true, y_pred, average="micro"),
'macro': recall_score(y_true, y_pred, average="macro"),
'weighted': recall_score(y_true, y_pred, average="weighted")
},
'f1': {
'micro': f1_score(y_true, y_pred, average="micro"),
'macro': f1_score(y_true, y_pred, average="macro"),
'weighted': f1_score(y_true, y_pred, average="weighted"),
}
}
return Precision_Statistics
def evaluate1(y_true, y_pred):
Precision_Statistics = {
'precsion': {
'precsion': precision_score(y_true, y_pred)
},
'recall': {
'recall': recall_score(y_true, y_pred)
},
'f1': {
'f1': f1_score(y_true, y_pred)
}
}
return Precision_Statistics
def appendlist1(label):
label_list1.append(label)
def appendlist2(label):
label_list2.append(label)
testCase用例实现:收集预期结果与接口返回结果,追加到列表: AItool.appendlist1(label)、 AItool.appendlist2(isDataYes)
# 请求目标接口
(res,headers) = shortTextSimilartiy().getAuthoritys(jsons=data, header={"Content-Type": "application/json"})
logger.info(headers)
isSuccess = headers['X-EBAPI-CODE']
isSuccess1 = headers['X-EBAPI-DESC']
result1 = Checkpoint().checkIfTextExist(isSuccess, "0000")
self.assertEqual(result1, True) # 根据result字段判断接口是否请求成功 如果请求成功继续往下校验是否为预期的相似度
result2 = Checkpoint().checkIfTextExist(isSuccess1, "success")
self.assertEqual(result2, True) # 根据result字段判断接口是否请求成功 如果请求成功继续往下校验是否为预期的相似度
try:
isDataYes = res["content"][0]["data"]
except Exception:
logger.info('获取被测接口的响应label失败')
raise KeyError
result3 = Checkpoint().checkIfTextExist(isDataYes, label)
if label == 'yes':
label = 1
else:
label = 0
if isDataYes == 'yes':
isDataYes = 1
else:
isDataYes = 0
# 追加预期数据与返回数据
AItool.appendlist1(label)
AItool.appendlist2(isDataYes)
self.assertEqual(result3, True) # 根据返回是否相似 与预期值对比
if label == 'yes': # 如果label等于yes 则判断返回值中的相似度是否大于等于0.5(0.5这个阈值可调)
result2 = res["content"][1]["data"] >= 0.5
self.assertEqual(result2, True)
elif label == 'no': # 如果label等于no 则判断返回值中的相似度是否小于0.5(0.5这个阈值可调)
result2 = res["content"][1]["data"] < 0.5
self.assertEqual(result2, True)
report输出报告:报告中调用工具类evaluate1函数,输出模型评估结果
1 def getReportAttributes(self, result):
2 """
3 Return report attributes as a list of (name, value).
4 Override this to add custom attributes.
5 """
6 startTime = str(self.startTime)[:19]
7 duration = str(self.stopTime - self.startTime)
8 status = []
9 #Accuracy = AItool.evaluate(AItool.label_list1, AItool.label_list2)
10 # 输出模型评估指标值
11 Accuracy = AItool.evaluate1(AItool.label_list1,AItool.label_list2)
12 status.append('总计: %s' % (result.success_count + result.failure_count + result.error_count))
13 if result.success_count: status.append('通过: %s' % result.success_count)
14 if result.failure_count: status.append('失败: %s' % result.failure_count)
15 if result.error_count: status.append('错误: %s' % result.error_count)
16 if status:
17 status = ','.join(status)
18 # 合入Github:boafantasy代码
19 if (result.success_count + result.failure_count + result.error_count) > 0:
20 self.passrate = str("%.2f%%" % (float(result.success_count) / float(
21 result.success_count + result.failure_count + result.error_count) * 100))
22 else:
23 self.passrate = "0.00 %"
24 else:
25 status = 'none'
26 return [
27 (u'测试人员', self.tester),
28 (u'开始时间', startTime),
29 (u'合计耗时', duration),
30 (u'测试结果', status + ",通过率: " + self.passrate),
31 (u'统计数据', ''),
32 # (u'precsion', 'micro=' + str(Accuracy['precsion']['micro']) + ', macro = ' + str(
33 # Accuracy['precsion']['micro']) + ' , weighted = ' + str(
34 # Accuracy['precsion']['weighted'])),
35 # (u'recall', 'micro=' + str(Accuracy['recall']['micro']) + ', macro = ' + str(
36 # Accuracy['recall']['micro']) + ' , weighted = ' + str(
37 # Accuracy['recall']['weighted'])),
38 # (u'f1', 'micro=' + str(Accuracy['f1']['micro']) + ', macro = ' + str(
39 # Accuracy['f1']['micro']) + ' , weighted = ' + str(
40 # Accuracy['f1']['weighted']))
41 (u'precsion','precsion='+str(Accuracy['precsion']['precsion'])),
42 (u'recall','recall='+str(Accuracy['recall']['recall'])),
43 (u'f1','f1='+str(Accuracy['f1']['f1']))
44
45 ]
report结果展示:
测试报告中结果展示:
五、测试问题总结
1)LCQMC语料库获取,模型测试数据获取都是靠运气,一般可通过官方网站进行申请(时间比较久,还需要额外审核),自己百度找,需要这份数据集的小伙伴请评论留言!
2)本次模型评估测试采用自动化框架,如果有一定python技术的同学,我建议采用这种方式,首先能够解放双手,其次可以缩短测试时间,尽管前期需要投入开发时间,但是一劳永逸,想探讨接口自动化框架的小伙伴请评论留言!