AI赋能一键自动检测:页面异常、控件异常、文本异常

栏目: 编程工具 · 发布时间: 6年前

概要:FireEye是通过AI提高测试效率,并降低AI自动化测试使用门槛的 工具 集,一经部署,就可以不用再修改脚本实现模型的使用和更新。本篇文章将具体介绍AI自动化测试过程中用到工程结构、模型选型和重训练的技术细节等。

1 使用效果

目前从功能上分为:页面异常、控件异常、文本异常,测试结果页面如下图所示:

AI赋能一键自动检测:页面异常、控件异常、文本异常

当测试同学发现部分测试出的数据并不符合预期,可以通过页面标注并使用重训练功能实时更新模型,不断提高模型准确率,减少开发人员重新去介入模型的调整和部署。

AI赋能一键自动检测:页面异常、控件异常、文本异常

2.1 工程结构

工程结构如图所示:

AI赋能一键自动检测:页面异常、控件异常、文本异常

这个工程中,训练数据的来源有3方面,样本生成工具生成的模拟样本、闲鱼技术质量门户持续搜集的真实用户截屏图片,还有一个是FireEye的前端页面用户手动打标的重训练数据,数据采集之后,由集成的工具将其转换为所需要的数据类型:JPG、PNG、TXT等,并将其中的资源文件上传至OSS资源管理,当用户触发了重训练命令,会由Jenkins通知服务端的重训练脚本开始重新训练,重训练后的模型保存在云端,可以通过API提供给FireEye以及其他业务场景使用。

2.2 使用模型

我们在针对不同的识别场景对模型的选型也有不同,其中

1, 页面异常 是检测页面是否整体空白或图片中间有很大的错误提示图片,因为这类异常结构简单特征明显,所以用 CNN 做聚类就可以准确区分出这一类的case。

2, 控件异常 是找到页面中有异常特征的控件,如识别截屏里面包含了图片的打底图,说明有图片加载异常,识别出有loading控件,可能用户在这个场景长时间卡住,识别出有error的HUD表示异常提示。我们在工程中选用 SSD 做物体检测,原因是异常控件在一个页面中可能存在多个,使用SSD模型可以识别出异常控件的类型以及在页面的位置和异常的数量。

3, (具体介绍) 文本异常 检测是通过OCR逐行识别出页面中的文本,然后判断文本的语义是否正常,模型部分选用的是 LSTM ,RNN的本质是一个数据推断(inference)机器,它可以寻找两个时间序列之间的关联,只要数据足够多,就可以得到从x(t)到y(t)的概率分布函数, 从而达到推断和预测的目的,而LSTM(Long Short Term Memory Networks)长短时间记忆网络,是RNN的一个变种,避免长期依赖和梯度消失,爆炸等问题,使得LSTM已经成为处理拥有长期依赖问题的序列数据问题的首要方法之一(语言模型、机器翻译等领域)。

文本异常的处理是通过一句话判断是否为异常文本,输入是有时序的一串字符,输出是否异常,符合RNN的5种架构中的many-to-one类型,这是我们选用LSTM的原因。

AI赋能一键自动检测:页面异常、控件异常、文本异常

实际的检测效果如下:

AI赋能一键自动检测:页面异常、控件异常、文本异常

识别结果(其中第三行被识别出包含乱码):

方案的实现上我们使用的是,Keras提供的 LSTM 层来构造网络,然后构建以闲鱼APP里的标题、详情、评论等作为正样本,口字码、拼音码、符号码、锟拷码、代码等作为负样本的训练数据,使用nltk的分词器分词输入训练得到模型,通过OCR提取页面文字输入页面识别输入模型判断。

部分代码:

1,首先统计数据中有多少个不同的词,每句话由多少个词组成

maxlen = 0  #句子最大长度
word_freqs = collections.Counter()  #词频
num_recs = 0 # 样本数
with open('./train.txt','r+') as f:
   for line in f:
       label, sentence = line.strip().split("t")
       words = nltk.word_tokenize(sentence.lower()
       if len(words) > maxlen:
           maxlen = len(words)
       for word in words:
           word_freqs[word] += 1
       num_recs += 1

目前项目里的乱码识别主要是针对英文和字符类型,所以使用的是nltk库做分词,如果是主要对中文处理,使用结巴分词效果更好,或者用NLTK库中Sinica(中央研究院)提供的繁体中文语料库,from nltk.corpus import sinica_treebank 这样导入

2,建立两个表,word2index和 index2word,用于单词和数字转换,把句子转换成数字序列,长度统一到 MAXSENTENCELENGTH,不够的填0,多出的截掉

MAX_FEATURES = 2000 
MAX_SENTENCE_LENGTH = 40 
vocab_size = min(MAX_FEATURES, len(word_freqs) + 2 
word2index = {x[0]: i+2 for i, x in rate(word_freqs.most_common(MAX_FEATURES)} 
word2index["PAD"] = 0 
word2index["UNK"] = 1 
index2word = {v:k for k, v in word2index.items()} 
X = np.empty(num_recs,dtype=list) 
y = np.zeros(num_recs) 
i=0 
with open('./train.txt','r+') as f: 
    for line in f: 
        label, sentence = line.strip().split("t") 
        words = nltk.word_tokenize(sentence.lower() 
        seqs = [] 
        for word in words: 
            if word in word2index: 
                seqs.append(word2index[word]) 
            else: 
                seqs.append(word2index["UNK"]) 
        X[i] = seqs 
        y[i] = int(label) 
        i += 1 
X = sequence.pad_sequences(X, maxlen=MAX_SENTENCE_LENGTH) ,
Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, test_size=0.2, random_state=42) 
EMBEDDING_SIZE = 128 
HIDDEN_LAYER_SIZE = 64 

3,模型训练,损失函数用 binary_crossentropy,优化方法用 adam,最后导出h5模型。

  1. model = Sequential()

  2. model.add(Embedding(vocab_size, EMBEDDING_SIZE,input_length=MAX_SENTENCE_LENGTH)

  3. model.add(LSTM(HIDDEN_LAYER_SIZE, dropout=0.2, recurrent_dropout=0.2)

  4. model.add(Dense(1)

  5. model.add(Activation("sigmoid")

  6. model.compile(loss="binary_crossentropy", optimizer="adam",metrics=["accuracy"])

  7. BATCH_SIZE = 32

  8. NUM_EPOCHS = 10

  9. model.fit(Xtrain, ytrain, batch_size=BATCH_SIZE, epochs=NUM_EPOCHS,validation_data=(Xtest, ytest)

  10. model.save("garbled.h5");"

4,OCR识别页面文字内容,导入模型中进行预测。(目前使用是谷歌OCR,中文识别的精度还不够)

3 FireEye辅助工具集

3.1 样本生成工具

在工程开始初期从真实用户收集的数据很少,需要大量的样本提供训练,为了能大量生成训练和测试样本并且不影响APP的线上统计数据,开发了一个通用的native的mock库可以截取控件加载数据随机生成mock的数据,用来配合Facebook-WDA截取图片获得样本: 1,mock所有UIImage,随机加载1万个样本数据里的图片url;

2,mock所有UILabel和UITextField,随机从样本库中生成语句和数字,内容数与原有数据相仿;

3,通过Facebook-WDA工具脚本控制APP,随机点击进入不同页面,滑动,截图,判断是否到底部,再随机跳转到别的页面…这样来获得大量样本;

3.2 重训练打标工具

打标一直以来是使用AI困扰大家的一件耗时耗力的步骤,FireEye提供重训练功能的同时提供了相关工具:

其中页面异常的识别的CNN模型和识别文本异常的LSTM模型重训练,可以通过用户在网页上的对结果进行勾选,输入正确的结果来完成标注工作,操作比较简单,最复杂繁琐的是SSD模型的打标,普遍的做法是使用labelImg工具,先准确的框选目标物体输入标签名,然后导出包含物体位置和标签信息的CSV文件,FireEye将这个功能集成到了重训练的系统中,用户可以通过在页面上划线或者画框标出物体大致的位置,位置会传到后端脚本自动裁剪提取前景,得到更精准的物体实际定位并生成CSV文件,其中画框标记的具体实现如下:

1,前端页面打标

下图是使用框选物体来标记右下角的按钮,我们不需要框出准确的位置:

AI赋能一键自动检测:页面异常、控件异常、文本异常

2,调用 Python 脚本,使用OpenCV的grabcut来实现前景提取

img=cv2.imread('tmp2.png')
mask=np.zeros((img.shape[:2]),np.uint8)
bgdModel=np.zeros((1,65),np.float64)
fgdModel=np.zeros((1,65),np.float64)
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
mask2=np.where((mask==2)|(mask==0),0,1).astype('uint8')

下图是grabcut提取前景后识别出的mask图,右下角有部分裁剪后留下的杂点

AI赋能一键自动检测:页面异常、控件异常、文本异常

3,得到前景二值化,查找连通区域,找到最大面积,通过把小面积区域用fillConvexPoly方法填充覆盖,得到

img=img*mask2[:,:,np.newaxis]
gray_temp = mask2.copy() #copy the gray image because function
binary, contours, hierarchy = cv2.findContours(gray_temp, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cv2.drawContours(img, contours, -1, (0, 255, 255), 2)
area = []
for i in xrange(len(contours)):
    area.append(cv2.contourArea(contours[i]))
max_idx = np.argmax(area)
for i in xrange(len(contours)):
     if i != max_idx:
        cv2.fillConvexPoly(mask2, contours[i], 0)

AI赋能一键自动检测:页面异常、控件异常、文本异常

4,再获得外接矩形,得到准确的标记位置并输出CSV文件。

总结

FireEye目标是打造一个精简易用的自动化测试工具集,可以很方便快捷的部署和调整,后面工程的重心会是AutoML的模型自动调参,识别布局异常,以及通过页面元素(控件、文本等)的综合分析,区分业务场景,理解用户操作路径是否正确等方面,欢迎有兴趣的小伙伴一起探讨学习。

AI赋能一键自动检测:页面异常、控件异常、文本异常

识别二维码,前瞻技术尽在掌握

概要:FireEye是通过AI提高测试效率,并降低AI自动化测试使用门槛的工具集,一经部署,就可以不用再修改脚本实现模型的使用和更新。本篇文章将具体介绍AI自动化测试过程中用到工程结构、模型选型和重训练的技术细节等。

1 使用效果

目前从功能上分为:页面异常、控件异常、文本异常,测试结果页面如下图所示:

AI赋能一键自动检测:页面异常、控件异常、文本异常

当测试同学发现部分测试出的数据并不符合预期,可以通过页面标注并使用重训练功能实时更新模型,不断提高模型准确率,减少开发人员重新去介入模型的调整和部署。

AI赋能一键自动检测:页面异常、控件异常、文本异常

2.1 工程结构

工程结构如图所示:

AI赋能一键自动检测:页面异常、控件异常、文本异常

这个工程中,训练数据的来源有3方面,样本生成工具生成的模拟样本、闲鱼技术质量门户持续搜集的真实用户截屏图片,还有一个是FireEye的前端页面用户手动打标的重训练数据,数据采集之后,由集成的工具将其转换为所需要的数据类型:JPG、PNG、TXT等,并将其中的资源文件上传至OSS资源管理,当用户触发了重训练命令,会由Jenkins通知服务端的重训练脚本开始重新训练,重训练后的模型保存在云端,可以通过API提供给FireEye以及其他业务场景使用。

2.2 使用模型

我们在针对不同的识别场景对模型的选型也有不同,其中

1, 页面异常 是检测页面是否整体空白或图片中间有很大的错误提示图片,因为这类异常结构简单特征明显,所以用 CNN 做聚类就可以准确区分出这一类的case。

2, 控件异常 是找到页面中有异常特征的控件,如识别截屏里面包含了图片的打底图,说明有图片加载异常,识别出有loading控件,可能用户在这个场景长时间卡住,识别出有error的HUD表示异常提示。我们在工程中选用 SSD 做物体检测,原因是异常控件在一个页面中可能存在多个,使用SSD模型可以识别出异常控件的类型以及在页面的位置和异常的数量。

3, (具体介绍) 文本异常 检测是通过OCR逐行识别出页面中的文本,然后判断文本的语义是否正常,模型部分选用的是 LSTM ,RNN的本质是一个数据推断(inference)机器,它可以寻找两个时间序列之间的关联,只要数据足够多,就可以得到从x(t)到y(t)的概率分布函数, 从而达到推断和预测的目的,而LSTM(Long Short Term Memory Networks)长短时间记忆网络,是RNN的一个变种,避免长期依赖和梯度消失,爆炸等问题,使得LSTM已经成为处理拥有长期依赖问题的序列数据问题的首要方法之一(语言模型、机器翻译等领域)。

文本异常的处理是通过一句话判断是否为异常文本,输入是有时序的一串字符,输出是否异常,符合RNN的5种架构中的many-to-one类型,这是我们选用LSTM的原因。

AI赋能一键自动检测:页面异常、控件异常、文本异常

实际的检测效果如下:

AI赋能一键自动检测:页面异常、控件异常、文本异常

识别结果(其中第三行被识别出包含乱码)

方案的实现上我们使用的是,Keras提供的 LSTM 层来构造网络,然后构建以闲鱼APP里的标题、详情、评论等作为正样本,口字码、拼音码、符号码、锟拷码、代码等作为负样本的训练数据,使用nltk的分词器分词输入训练得到模型,通过OCR提取页面文字输入页面识别输入模型判断。

部分代码:

1,首先统计数据中有多少个不同的词,每句话由多少个词组成

maxlen = 0  #句子最大长度
word_freqs = collections.Counter()  #词频
num_recs = 0 # 样本数
with open('./train.txt','r+') as f:
   for line in f:
       label, sentence = line.strip().split("t")
       words = nltk.word_tokenize(sentence.lower()
       if len(words) > maxlen:
           maxlen = len(words)
       for word in words:
           word_freqs[word] += 1
       num_recs += 1

目前项目里的乱码识别主要是针对英文和字符类型,所以使用的是nltk库做分词,如果是主要对中文处理,使用结巴分词效果更好,或者用NLTK库中Sinica(中央研究院)提供的繁体中文语料库,from nltk.corpus import sinica_treebank 这样导入

2,建立两个表,word2index和 index2word,用于单词和数字转换,把句子转换成数字序列,长度统一到 MAXSENTENCELENGTH,不够的填0,多出的截掉

MAX_FEATURES = 2000 
MAX_SENTENCE_LENGTH = 40 
vocab_size = min(MAX_FEATURES, len(word_freqs) + 2 
word2index = {x[0]: i+2 for i, x in rate(word_freqs.most_common(MAX_FEATURES)} 
word2index["PAD"] = 0 
word2index["UNK"] = 1 
index2word = {v:k for k, v in word2index.items()} 
X = np.empty(num_recs,dtype=list) 
y = np.zeros(num_recs) 
i=0 
with open('./train.txt','r+') as f: 
    for line in f: 
        label, sentence = line.strip().split("t") 
        words = nltk.word_tokenize(sentence.lower() 
        seqs = [] 
        for word in words: 
            if word in word2index: 
                seqs.append(word2index[word]) 
            else: 
                seqs.append(word2index["UNK"]) 
        X[i] = seqs 
        y[i] = int(label) 
        i += 1 
X = sequence.pad_sequences(X, maxlen=MAX_SENTENCE_LENGTH) ,
Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, test_size=0.2, random_state=42) 
EMBEDDING_SIZE = 128 
HIDDEN_LAYER_SIZE = 64 

3,模型训练,损失函数用 binary_crossentropy,优化方法用 adam,最后导出h5模型。

  1. model = Sequential()

  2. model.add(Embedding(vocab_size, EMBEDDING_SIZE,input_length=MAX_SENTENCE_LENGTH)

  3. model.add(LSTM(HIDDEN_LAYER_SIZE, dropout=0.2, recurrent_dropout=0.2)

  4. model.add(Dense(1)

  5. model.add(Activation("sigmoid")

  6. model.compile(loss="binary_crossentropy", optimizer="adam",metrics=["accuracy"])

  7. BATCH_SIZE = 32

  8. NUM_EPOCHS = 10

  9. model.fit(Xtrain, ytrain, batch_size=BATCH_SIZE, epochs=NUM_EPOCHS,validation_data=(Xtest, ytest)

  10. model.save("garbled.h5");"

4,OCR识别页面文字内容,导入模型中进行预测。(目前使用是谷歌OCR,中文识别的精度还不够)

3 FireEye辅助工具集

3.1 样本生成工具

在工程开始初期从真实用户收集的数据很少,需要大量的样本提供训练,为了能大量生成训练和测试样本并且不影响APP的线上统计数据,开发了一个通用的native的mock库可以截取控件加载数据随机生成mock的数据,用来配合Facebook-WDA截取图片获得样本: 1,mock所有UIImage,随机加载1万个样本数据里的图片url;

2,mock所有UILabel和UITextField,随机从样本库中生成语句和数字,内容数与原有数据相仿;

3,通过Facebook-WDA工具脚本控制APP,随机点击进入不同页面,滑动,截图,判断是否到底部,再随机跳转到别的页面…这样来获得大量样本;

3.2 重训练打标工具

打标一直以来是使用AI困扰大家的一件耗时耗力的步骤,FireEye提供重训练功能的同时提供了相关工具:

其中页面异常的识别的CNN模型和识别文本异常的LSTM模型重训练,可以通过用户在网页上的对结果进行勾选,输入正确的结果来完成标注工作,操作比较简单,最复杂繁琐的是SSD模型的打标,普遍的做法是使用labelImg工具,先准确的框选目标物体输入标签名,然后导出包含物体位置和标签信息的CSV文件,FireEye将这个功能集成到了重训练的系统中,用户可以通过在页面上划线或者画框标出物体大致的位置,位置会传到后端脚本自动裁剪提取前景,得到更精准的物体实际定位并生成CSV文件,其中画框标记的具体实现如下:

1,前端页面打标

下图是使用框选物体来标记右下角的按钮,我们不需要框出准确的位置:

AI赋能一键自动检测:页面异常、控件异常、文本异常

2,调用Python脚本,使用OpenCV的grabcut来实现前景提取

img=cv2.imread('tmp2.png')
mask=np.zeros((img.shape[:2]),np.uint8)
bgdModel=np.zeros((1,65),np.float64)
fgdModel=np.zeros((1,65),np.float64)
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
mask2=np.where((mask==2)|(mask==0),0,1).astype('uint8')

下图是grabcut提取前景后识别出的mask图,右下角有部分裁剪后留下的杂点

AI赋能一键自动检测:页面异常、控件异常、文本异常

3,得到前景二值化,查找连通区域,找到最大面积,通过把小面积区域用fillConvexPoly方法填充覆盖,得到

img=img*mask2[:,:,np.newaxis]
gray_temp = mask2.copy() #copy the gray image because function
binary, contours, hierarchy = cv2.findContours(gray_temp, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cv2.drawContours(img, contours, -1, (0, 255, 255), 2)
area = []
for i in xrange(len(contours)):
    area.append(cv2.contourArea(contours[i]))
max_idx = np.argmax(area)
for i in xrange(len(contours)):
     if i != max_idx:
        cv2.fillConvexPoly(mask2, contours[i], 0)

AI赋能一键自动检测:页面异常、控件异常、文本异常

4,再获得外接矩形,得到准确的标记位置并输出CSV文件。

总结

FireEye目标是打造一个精简易用的自动化测试工具集,可以很方便快捷的部署和调整,后面工程的重心会是AutoML的模型自动调参,识别布局异常,以及通过页面元素(控件、文本等)的综合分析,区分业务场景,理解用户操作路径是否正确等方面,欢迎有兴趣的小伙伴一起探讨学习。

AI赋能一键自动检测:页面异常、控件异常、文本异常

识别二维码,前瞻技术尽在掌握

AI赋能一键自动检测:页面异常、控件异常、文本异常 闲鱼技术

加入闲鱼,一起玩些酷的。(阿里巴巴集团闲鱼官方技术号,欢迎同道者技术交流。) 简历投递:guicai.gxy@alibaba-inc.com

理论 LSTM CNN 机器翻译 语料库 Python OpenCV


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法技术手册(原书第2版)

算法技术手册(原书第2版)

George T. Heineman、Gary Pollice、Stanley Selkow / 杨晨、曹如进 / 机械工业出版社 / 2017-8-1 / 89.00元

本书使用实际代码而非伪代码来描述算法,并以经验主导支撑数学分析,侧重于应用且规范严谨。本书提供了用多种程序设计语言实现的文档化的实际代码解决方案,还介绍了近40种核心算法,其中包括用于计算点集的Voronoi图的Fortune算法、归并排序、多线程快速排序、AVL平衡二叉树实现以及空间算法。一起来看看 《算法技术手册(原书第2版)》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

SHA 加密
SHA 加密

SHA 加密工具