@yanglfyangl
2018-12-05T04:03:04.000000Z
字数 3582
阅读 690
测试自动化
CI/CD的能力模型中,很重要的一点就是测试自动化的能力,这一点也是很多公司没有做到的能力(有不少大公司都是比0多不了多少)。究其原因,自动化测试的工作量比较是大家很慎重深入它的一个原因。
AI时代,机器学习的发现变化,是不是能有所帮助呢,下面就是碰到一个场景后的一些思考。
大概情况是这样的,朋友问了一个问题,有一大批的数据,这些数据做为输入后,会将最终结果落在数据库中,类似如下场景
数据的格式(虽然贴出来,但其实也看不懂)
<EuronextCode>LU1840350067</EuronextCode><IsinCode>LU1840350067</IsinCode>。。。。。。。。。。。。<ExerciseType>2</ExerciseType><MarketType>301</MarketType><UnderlyingIsinCode>NL0011794037</UnderlyingIsinCode><UnderlyingMep>AMS</UnderlyingMep><FirstTradingDate>2018-09-21</FirstTradingDate><IssueDate>2018-09-21</IssueDate><UnderlyingType>301</UnderlyingType><StrikePrice>18.675798</StrikePrice>。。。。。。。。。。。。<AuctionTime>00:00:00</AuctionTime>
主要的输出的格式
{payload:" ",effective_from:" ",effective_to:" "}
当然,主要还有几张表,这个表结构就不多说了。
问题是,在这个场景下,如何快速的进行测试呢?如果考虑边界值,等价类,因果等等的覆盖度,就会陷入下面的情况
1. Case过多2. 测试时间过长3. 需求变化对测试影响过大。
能不能用人工智能的方式来简化测试
这个例子是很多测试同学面临的难题,如果按照黑盒测试的方法,有足够的时间,可能还好。但一旦要求快速,就会面临如下难题
1. 量大2. 中间经过的服务并不是很确定(至少对于测试工程师来说,理解起来不容易)3. 给的测试时间并不是充分的4. 逻辑变化导致问题的可能点多,不易发现
当然,自然有人会想到机器学习来“学”出对应的逻辑,再进行测试,不过
1. 不能假设输入与输出一一对应。(逻辑肯定会使用原有的数据库中的值)2. 数据不是多对一或一对一的,而是多对多的
在机器学习领域,主要分成了
1. 监督学习2. 非监督学习
当然,背后的各种算法就很多了。
对于这个例子,测试团队估计不太会愿意做“监督”学习,因为样本的建立工作量很大,而且每次逻辑的变化可能都会导致样本重新来做,很划不来的。
这时候,我们能不能换个思路,其实现在的场景中,我们并不是要做预测,而是知道输入和输出的情况下,看输入与输出是不是正确的,这个是不是一个“异常值检测” 的场景呢?
我们先看看使用异常检测的场景
1. 大部分情况下都是正常的2. 正常的样本数据也大致趋同3. 小部分情况下是异常的4. 异常的故障可能多种多样
| 入参1 | 入参2 | 入参3 | 。。。 | 入参N | 出参1 | 出参2 | 出参N |
|---|---|---|---|---|---|---|---|
| LU1840350067 | AMS | I am ok | abc | ad | adf | 0.5 | {type:1, value:2} |
| ... | ... | ... |
这步主要是进行剔除,比如对于ID,可能对我们需要最终的影响从功能上已知是没有多少影响的,就可以从参数列表里去除了。
| 参数 | 向量化方法 | 描述 |
|---|---|---|
| 入参1 | —————————— | 数据ID,不参与训练 |
| 入参2 | 将AMS转化对应的枚举值 | |
| 入参3 | 利用CountVectorizer进行文字向量化 | |
| 出参N | 将Json拆解出新的参数维度,增加参数N+1。。。 |
这里,每个参数都有可能出现没有的情况,这时候要考虑如何进行补值,按下面思路考虑
如果参数可有可无,补平均值就可以了,目的是不影响最终结果如果参数很重要,补一个远离平均值的(异常值),这样最终结果也容易发现异常。如果不知道。。。最好找人弄清楚,要实在弄不清楚,先补0吧。
最终的txt文件会是这样的
200, 111, 0.5, ..., ..., ..., ..., 0.69874201, 100, 0.8, ..., ..., ..., ..., 0.69874.........201, 100, 0.8, ..., ..., ..., ..., 0.51345
上面的过程是把数据准备出来了,下面是看看怎么用这些数据了。
其实,选择什么样的异常值算法,还是要根据你的场景的,但这个例子中,主要的场景其实是给人工测试一个方法,能够快速的发现问题,所以建议采用的是K-Means算法(非监督&聚类),当然,最好是考虑K-Medians或均值漂移聚类,这样不需要考虑质心的问题。

最终可能会出现下面的图。
这时候,测试同学就可以
1. 取样质心中的数据,看看是不是逻辑有问题,如果质心的逻辑数据有问题,那么肯定是重大逻辑错误了。2. 取样非质心数据,看看是不是有逻辑问题。
自动化测试很核心的点就是不需要人工参与的情况下,自动评估结果是否达到预期,所以聚类的方法还是有些问题的,阈值很难定义。特别是如果算法有问题,多聚类出来一个不应该存在的质心,是不容易进行自动化判断代码是否是符合要求的。
这时候,我们就要找一些能够通过阈值来进行异常值查找的算法了,比如:高斯模型(正态分布)。

这时候,我们呆可以把(μ-σ,μ+σ)范围内的面积做为阈值。
比如,我们认为测试的结果应该有90%符合预期才能进入下一步,就可以进行设定,因为有了“标准”的值,所以自动化就可以跑了。当然,这时候就会产生几个问题
1. 怎么训练模型2. 怎么计算这个面积2. 怎么设定这个面积的合理值。
挨个来说
怎么训练模型
说简单也简单,但说复杂,也有一点,需要对所有的输入,进行一个归一化处理,并计算出和来。
mu, sigma , num_bins = 0, 1, 总数x = mu + sigma * 归一化(x1, x2...xn)# 正态分布的数据n, bins, patches = plt.hist(x, num_bins, normed=True, facecolor = 'blue', alpha = 0.5)//拟合曲线y = mlab.normpdf(bins, mu, sigma)
怎么计算面积
import mathdef pdf(x):return math.exp(-(x) ** 2 / (2)) / (math.sqrt(2 * math.pi))def sum_fun_xk(xk, func):return sum([func(each) for each in xk])def integral(a, b, n, func):h = (b - a)/float(n)xk = [a + i*h for i in range(1, n)]return h/2 * (func(a) + 2 * sum_fun_xk(xk, func) + func(b))def cdfd(a,b,u,o):return integral((a-u)/o,(b-u)/o,10000,pdf)测试一下cdfd(2,3,2,1)Out: 0.3413399854638336
这个问题不容易有一个明确合理的答案。最好的方式可能是先分析一下你的测试,然后找一个认为合适的质量要求度。当然,这个里面最重要的是先用聚类进行第一轮的人工测试,然后新数据与老数据聚类的结果进行第一要素的评判,如果聚类出的核数都有差距,则说明本次有重大功能问题了(或功能有比较大的变化了)
大概的伪代码如下:
var threadhold = 0.05; //简而言之,要求95%的信心var lastKernNumber = getLastKernNumbers();var thisKernNumber = getThisKernNumbers();if(hunmanConfiredNotCheck || lastKernNumber != thisKernNumber) {throw("自动测试失败,发现与上次有比较大的区别,请重新确认")}if(threadhold < getUnNormalArea()){throw("自动测试失败,测试结果中异常值过多")}