精准测分:基于函数调用关系链的用例消振算法 ( 上帝视角 )

基于函数调用关系链的功能用例消振算法

---上帝的视角

一、引言

(1)问题简述:当一个功能用例执行时,背后就会有数以千计的函数被调用运行。其中有与这个功能用例息息相关的业务函数,也有与这个功能用例描述无关的数据上报函数、log日志函数。如何区分什么是核心业务函数,什么是无关函数?

(2)《三体》像我们阐述了这样一个事实:一个文明不会孤立的存在,宇宙有其社会学法则。在这个法则的作用下,一个文明或主动或被动的与其他文明产生关联关系。地球文明不是孤岛。

二、函数孤岛?

地球文明不是孤岛,函数呢?从静态的视角观察函数,她只是一个一个在文件中孤立存在的代码片段。但从动态的视角观察,函数与函数之间就天然的发生了关联。这个关联是怎么产生的呢?答案是函数调用关系链。函数调用关系链就是函数自己的宇宙社会学法则,函数不是一个孤岛。我们将这种动态的视角称为---上帝的视角(文中最后部分有解释这个的含义)。

三、函数的宇宙社会学法则导致的用例关联函数问题剖析。

在函数调用关系链的作用下,一个函数或主动或被动的与其他函数产生调用关系。这种调用关系的存在,造成了用例与函数两者在关联的时候,总会出现一系列问题:

1、从函数角度而言,越是基础的公共函数,她被调用的次数就越多,她与其他函数的互相交叉关系就越复杂。如何将函数关联的用例控制在最能描述这个函数的用例集上呢?且不会关联过多无效的用例。

2、从用例角度而言,用例的设计主要是为几个有限的关联业务函数服务的。但是由于函数调用关系链的影响,用例会被动的关联很多跟他的功能描述不相关的函数。若是这个用例操作步骤很复杂,那么其所调用的函数将呈现爆炸式的递增。如何能够将用例关联的函数控制在核心业务函数范围内呢?

要解决上述两个问题,是否可以借鉴《三体》中挽救人类文明于灭亡边缘的“面壁计划”的思路:既然无法突破宇宙社会学法则,那么就利用、学习她,在绝境中寻求浴火重生的机会。我们是否也可以利用函数调用关系链的规则,制定我们自己的“面壁计划”?答案是肯定的,经过我们团队成员不懈的努力,我们找到了解决上述问题的方式:从调用链的两个不同视角来解决这两个问题:

广度视角:利用函数调用关系链hash值来解决问题1。

深度视角:利用函数调用关系链亲密度值来解决问题2。

额,好抽象的视角啊,如何理解?莫急,各位看官请听我将她娓娓道来:

四、广度视角:利用函数调用关系链hash值解决函数关联过多无效用例问题(尤其是公共库函数)。

首先让我们一起将视角调整到:函数与其调用的子函数之间这个角度,站在函数角度而言这是主动的调用,子函数之间是平等的兄弟节点的关系,她是横向的广度

函数有分支的概念,就造成了子函数分派的依附各自的分支中。为了方便大家理解这个概念,我们在这里打一个比方:在一棵树分支中分布的叶子,如图1,我们将一个函数的调用想象成上图中有分支有叶子的树图,树的分支代表函数分支,树的叶子代表函数调用的子函数。

图1

一棵树是靠他的分支像叶子输送养分的,若是在输送养分的过程中,只专门跑一个分支,就会造成其他分支的叶子因得不到养分而渐渐枯萎。为了使每一个分支的叶子都不会枯萎,需要在传输养分的时候保证每一个分支都能被传送到,保证叶子雨露均沾。若是我们再规定每天每一片叶子只能得到一次营养传输机会,那么我们如何严格的保证这个规则的执行呢?因为每一片叶子都是独一无二的,而她又依附于她所在的分支吸收营养,那么我们就可以通过一个分支中所有叶子的集合hash来区分每一个分支。当上图这棵树的三个分支都可以相互区分之后,我们就可以保证每一天每一个分支的每一片叶子一天只得到一次营养传输。若是一天中一个分支第二次意外的遇到有外部营养的传输的时候,我们就可以直接拒绝。

函数的用例设计也是与上述的类比一样的,为了保证函数的质量,需要为每一个分支设计一个关联的用例。当我们完成了函数每一个分支用例设计的时候,若是突然有一个无关的用例也调用了这个函数,我们如何拒绝将这个函数与这个用例进行关联呢?恩,与叶子是一样的,每一个子函数也是独一无二的,我们可以通过每一个分支的子函数集合hash来标识区分每一个函数的分支。然后在设计分支用例的时候,将每一个分支的hash与与这个用例相关联,这样当我们再遇到一个无关用例关联这个函数的时候,测试分析师就可以有法可依的拒绝这个用例的关联。

汇总:每一个分支的子函数集合hash就是函数调用关系链hash的概念。当一个公共库函数完成了其所有分支用例分覆盖之后,突然有一天多次意外的遇到无关用例主动关联的时候,那么作为测试分析师的我们就可以大胆的拒绝这个关联关系。

五、深度视角:函数调用关系链亲密度值解决用例关联不相关函数的问题。

首先让我们一起将视角调整到:函数与调用这个函数的父函数之间这个视角,站在函数角度而言这是被动的调用(与广度视角正好相反),父函数与函数之间是直系亲属的关系,她是纵向的深度。

由于函数之间有调用与被调用的关系,就造成了函数间:祖父函数、父亲函数、儿子函数、孙子函数、曾孙函数之间直系亲属关联关系的概念。了方便大家理解这个概念,我们在这里打一个比方:清朝皇室族谱中的直系亲属关系,看下图:

图2

我们将一个被调用的函数想象成上图中具有直系亲属关系的族谱图,族谱中的一个人名代表了一个函数。通过生物遗传学的特性,我们发现族谱中父子之间血缘关系是最亲近的,而隔着几代的两个人相互之间的血缘关系却是很淡薄的。

用例与其关联的核心业务函数的关系也是与上述的类比一样的,当我们把用例当做祖先,那么其关联的核心业务函数就是其子孙。调用链层次越上层的函数他所包容的功能越多,越靠近用例所描述的功能,其血缘关系就越近。调用链层次越下层的函数他所包容的功能越少(只是上层函数的一个功能子集),越远离用例所描述的功能,其血缘关系就越浅薄。

我们将用例与函数的血缘关系称为亲密度。若是亲密度的描述在这里就停止,我们相信大家都不会满意: 你们的系统怎么一定可以确认在调用链越下层的函数,就一定不能描述这个用例呢?额,从系统层面确实不能肯定的回答是,好心塞

抛开低落的情绪,让我们平静下来。回头再来看看我们的项目的目标:测分及测试体系精准化、STA(测试分析师)养成。默默的多读几遍,对啊!我们忽略了精准测分最重要、最核心的角色:拥有上帝视角的STA(测试分析师)。因为用例是由STA(测试分析师)创造设计的,他才是用例及其关联函数真正的祖先,他最清楚用例应该关联那些核心业务函数。STA(测试分析师)才是精准测分项目的“面壁者”,其拥有至高的话语权(上帝视角)。

通过测试分析师的选择我们过滤出一批核心业务函数,再在函数调用关系链的作用下,将这批核心业务函数按照调用链的层次分成不同的亲密度值。通过亲密度我们知道,哪些函数跟我这个用例才是最亲密的、哪些用例跟我这个函数才是最亲密的。

为了方便大家更深入理解函数调用关系链亲密度值,这里我们举一个用例设计过程中关联函数的实际例子:模拟器项目中“摇一摇”功能用例,下面是这个用例的描述截图。

图3

通过上面的截图描述我们知晓这个功能用例的主要关联业务函数类型是:界面窗口的摇一摇OnShake、模拟器模块摇一摇事件消息发送SendShake、事件中堆内存的清除。分析了业务函数的类型之后,将他们与这个用例相关联即可,之后系统会根据函数调用关系链计算关联函数的亲密度值。接着当我们继续深入分析界面窗口摇一摇函数OnShake的时候,发现一个用例不能完全覆盖他所有的分支,这时我们就要创造设计出不同的用例对函数OnShake进行高质量的覆盖。上述我们创造设计的用例与函数OnShake的亲密度值均为1,因为他们都是围绕这个函数而生的。但是当还有其他不怎么相关的用例,因为调用关系链的缘故也被迫关联了函数OnShake时,我们就可以通过测试分析师的选择以及函数调用链将其亲密度降低。这样在亲密度值的作用下,测试分析师只需执行亲密度为1的用例,更低亲密度的用例呆一边去。

汇总:函数调用关系链亲密度值的计算通过两个步骤的操作来完成:

1、STA(测试分析师)的选择过滤,这是至关重要的选择。不然下面一步的操作就会变成无源之水、无本之木。

2、通过函数调用关系链将1中选择过滤的业务函数进行亲密度值的计算。

根据这些亲密度值,我们就可以将函数关联的用例进一步的过滤消振。

六、总结

通过广度视角:函数调用关系链hash值我们解决了函数关联用例过多的问题,将函数关联的用例在横向方向上过滤出一批。再通过深度视角:函数调用关系链亲密度值我们解决了用例关联函数过多的问题,将用例关联的函数在纵向的方向上再过滤出一批。这样剩下的函数关联用例,用例关系函数,互相之间才是最核心、优先级最高的。自然的,与用例无关的函数、与函数无光的用例都被无情的过滤了。

上述就是桌管安全测试团队针对精准测分中用例消振提出的“面壁计划”

。这里请允许我代表我们团队再郑重的跟大家阐述一下精准测分项目的目标:测分及测试体系精准化、STA(测试分析师)养成,额一不小心泄露了个大秘密

七、名词解释

三体》:是刘慈欣创作的系列长篇科幻小说,由《三体》、《三体Ⅱ·黑暗森林》、《三体Ⅲ·死神永生》组成。

面壁计划”:一个通过利用三体人唯一战略劣势——不能隐瞒自己想法。利用地球人无法被看穿的思想找到阻止三体入侵的方法的计划的总称。

面壁者”(测试分析师):选定一批面壁计划的制定者和领导者,他们完全依靠自已的思维制定战略计划,不与外界进行任何形式的交流,计划的真实战略思想、完成的步骤和最后目的都只藏在他们的大脑中,我们称他们为面壁者。面壁者将被授予很高的权力,使他们能够调集和使用地球已有的战争资源中的一部分。

上帝的视角”:在二维角度(平面)上的点看自己,只是一个点。但是从三维角度看,却是互相关联组成的网状图。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏令仔很忙

UML总结

   描述类与类之间的使用与被使用关系,而其使用关系具有偶然性的、临时性的、非常弱的,但是被使用的一方会影响到使用的一方,比如说:“动物”和“氧气”,动物的生活...

591
来自专栏铭毅天下

干货 | 论Elasticsearch数据建模的重要性

数据模型是抽象描述现实世界的一种工具和方法,是通过抽象的实体及实体之间联系的形式,用图形化的形式去描述业务规则的过程,从而表示现实世界中事务的相互关系的一种映射...

1322
来自专栏前端布道

JavaScript设计模式与开发实践 - 策略模式

引言 本文摘自《JavaScript设计模式与开发实践》 在现实中,很多时候也有多种途径到达同一个目的地。比如我们要去某个地方旅游,可以根据具体的实际情况来选择...

3608
来自专栏battcn

一起学设计模式 - 策略模式

策略模式: 是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类...

742
来自专栏xingoo, 一个梦想做发明家的程序员

【UML】——为什么要使用UML

以前一提到UML,就想到了复杂的流程图。很敬佩哪些想想就能画出整个系统的UML图的人,因为他们头脑中有整个软件架构的蓝图,这样在编写实现的时候,就会知道哪个...

1868
来自专栏跨界架构师

[译文]Domain Driven Design Reference(三)—— 模型驱动设计的构建模块

  这些模式根据领域驱动设计,广泛地推行了面向对象设计的最佳实践。他们指导决策来提炼模型,并使模型和实现保持一致,每一个都增强了其他的有效性。仔细制定模型元素的...

662
来自专栏瓜大三哥

键盘防抖

按键大多是机械式开关结构,一个按键开关在闭合是不会马上接通,在断开时也不会一下在断开,而是会产生一系列的抖动现象。释放按键后,按键信号稳定前出现了多个段脉冲,如...

1899
来自专栏程序员互动联盟

【专业技术】结构化与面向对象到底啥区别?

存在问题: 什么是面向对象什么是结构化,这个问题一直困惑着很多新手,不容易搞清楚。 解决方案: 1.基本原则的对比: 结构化方法的基本思想就是将待解决的问题看作...

2605
来自专栏向治洪

策略模式

策略(Strategy)模式 策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使...

1619
来自专栏斑斓

MongoDB的数据建模

MongoDB是一种面向Document的NoSQL数据库,如果我们还是按照RDB的方式来思考MongoDB的数据建模,则不能有效地利用MongoDB的优势;然...

3106

扫码关注云+社区