技术标签: 测试分析
请注意pre/post不能算是典型意义上的设计模式,Pre/post是契约式编程思想的概念。但是在从chromium代码中确实能看到不少他们的身影。
契约式编程(英语:Design by Contract,缩写为DBC)在Wiki上的解释:契约式编程是一种设计计算机软件的方法。这种方法要求软件设计者为软件组件定义正式的,精确的并且可验证的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。这种方法的名字里用到的“契约”或者说“契约”是一种比喻,因为它和商业契约的情况有点类似。
在《程序员修炼之道:从小工到专家》中专门有一条讲的就是契约式编程(按合约设计)。
DesignbyContract的核心是断言(assertion)。所谓“断言”,是指永远为真的布尔型语句,如果不为真,则程序必然存在错误。通常情况下,检查断言的时机,应该局限于调试(debug)阶段,而不是代码的实际执行阶段。实际上,完成的程序永远不应期望断言会被检查。
DesignbyContract使用了三类断言:后继条件(post-conditions),前提条件(pre-conditions),以及不变量(invariants)。其中前驱条件与后继条件都是针对操作(operation)而言的。
前提条件preconditions:acondition that must hold up on invocation of a function在方法被调用之前就必须满足的条件。
后继条件post-conditions:acondition that must hold up on exit from a function法被调用之后所要保持的条件
不变量invariants:acondition that must always hold for objects of the class,except while a public member function is executing.在方法的执行过程中,不变量可能为假,但是,在其他任何对象能够与被调用方进行交互的时刻,不变量断言必须恢复为真。
在之前MBT的探索中,我们曾经尝试使用了PRE/POST模型,可参考文章http://tmq.qq.com/2016/11/pre_post_explore/。
虽然c++11不支持contract的语法,但是从chromium的代码上也可以看到代码也采用了pre/post的方式来设计。
我们可以从chromium的启动代码中看下pre/post思想是怎么使用的。
下图是Chromium中浏览器启动时候的代码顺序:
具体函数调用可以参考网上文章(http://blog.gclxry.com/chromium-framework-start/)。
启动的主要逻辑都是在Browser Main RunnerImpl,可以看到下面这段函数也是典型的pre/post的设计:
上面函数在main_loop_->Main Message Loop Start之前, 先调用main_loop_->Pre Main Message Loop Start准备相应的环境, 在执行完main_loop_->Main Message Loop Start之后又调用main_loop_->Post Main Message Loop Start来做后置条件的相关操作。
在每个layer里面都有对应的pre/post代码:
Browser MainLoop 里面的Pre Main Message LoopStart 又会调用对应的平台的Chrome应用(_parts对应的就是Chrome Browser Main Parts,不同的平台的应用不一样,windows上面就是Chrome Browser Main Parts Win)的Pre Main Message Loop Start。
在Chrome Browser Main Parts里面Pre Main Message Loop Start又会调用chrome_extra_parts_(多个扩展应用Chrome Browser Main Extra Parts:其中Chrome Browser Main Parts是对应的平台,
Chrome Browser Main Extra Parts是对应不同的Chrome toolkits (e.g., GTK, VIEWS, ASH, AURA, etc.))的Pre Main Message Loop Start。
在编程语言不支持了DBC的情况下,在代码层面采用PRE/POST的设计可以极大地提高代码的易读性和可维护性。且建立这种契约明确了我们什么时候什么阶段该干什么事。
维基百科的解释:委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。委托模式使得我们可以用聚合来替代继承,它还使我们可以模拟mixin。
Chromium是一个复杂的开源项目,其中应用了丰富的设计模式来组织代码,应用最广泛的应该算是Delegate Pattern(委托模式)。
在chromium中,每个模块具体功能的实现基本上都是通过Delegate类来实现的,如果开发者继承该Delegate类,并加以实现就能很方便的完成定制,倘若开发者不需要某个模块的功能,也就不用实现相关的Delegate类,那么该模块就不会发挥效用。
Delegate的使用使得自动化测试也非常容易,这些测试需要能直接检测Chromium中的某个特性或功能能不能正常工作,检查新添加的代码对原有的代码有没有影响,但是由于有些功能需要手动干预才能正常工作,比如下载模块中弹出的对话框需要手动选择保存文件的地址和文件名;这些会给自动测试代码带来麻烦,但是有了delegate的设计,我们在测试代码中可以直接实现对应的Test的delegate,继承正常工作的delegate,该类做一些简单的修改事先填好一些数据,从而绕开需要手动输入代码块的执行。这就一方面完成了对已有代码的测试,也同时兼具了自动化。
在Chromium项目中有个Download Manager类(content里面),它负责完成任务的下载功能,当在浏览器中点击某个不能被渲染的链接时,浏览器就认为该链接的文件需要下载,就通过Download Manager来完成下载流程。
当在浏览器中点击某个不能被渲染的链接时,浏览器就认为该链接的文件需要下载,就通过Download Manager来完成下载流程。但是下载文件的实际工作都是在Download Manager Delegate中完成的,比如选择文件的路径,检查文件路径名是否合法,下载时候完成之类等。开发者只需要自己设计一个新的Delegate类来继承Download Manager Delegate,并覆盖相应的方法即可完成下载功能,另外需要通过Set Delegate方法,在程序开始时把自定义类的对象注册到Download Manager中。目前Chrome,Content Shell,CEF3和Crosswalk都有自己的实现。
Chrome基于Download Manager Delegate的UML类图:
下面看看自动化测试中应该怎么使用设置test的delegate:
首先,基于Chrome Download Manager Delegate实现自己的测试的delegate:Delaying Download Manager Delegate。
上面代码就是基于Chrome Download Manager Delegate定义了测试所需要的Delaying Download Manager Delegate类,并重写了方法Should Complete Download 这样就可以绕开真实的delegate里面复杂的Should Complete Download逻辑判断,并简单的返回了false来进行测试。
在对应的测试用例代码里面调用set Delegate替换为测试的delegate。
定义完了测试的delegate类,调用SetDelegate来使得Delaying Download Manager Delegate生效。
**未完待续……
版权所属,禁止转载
扫描下方二维码,关注微信公众号:腾讯移动品质中心TMQ,获取更多测试干货!
最后更新于2020.8.2请为作者点一个赞,这是对作者最大的支持。记得收藏,此文章长时间更新。链接如果有问题请及时在评论区报错,我看到后会及时补链,一定要说明清楚是哪一条链接出问题。请珍惜作者的劳动成果。本文章内容的一部分来自下面列出的链接,一部分来自本作者的链接,感谢这些页面内容的提供者。来源链接列表:[1]使用指南假设你把sdk安装到d:\android-sdk,则里面的目录结构应该是这样的:d:\android-sdk\tools这个目录里有ddms.bat等文件d:\
平均值不等式:对任意的n个正数a1,a2,a3,...,ana_1,a_2,a_3,...,a_n,有a1+a2+a3+...+ann≥a1a2a3...an−−−−−−−−−−√n≥n1a1+1a2+1a3+...+1an。\frac{a_1+a_2+a_3+...+a_n}{n} \ge \sqrt[n]{a_1a_2a_3...a_n} \ge \frac{n}{\frac{1}{a_1}
写代码除了两个显示器以外,如果再配上一个好用的机械键盘,真的敲代码的时候感觉都不一样,那是真的开心,敲代码的时候你就是最靓的仔.。所以,小编联合几位公众号主给大家送9个 全新黑爵混彩机械...
文章中如果有什么描述不恰当或者不对的地方,希望大家能够及时指正,我尽快修改,以免再误导其他人。拜托啦最近在复习郭霖老师的《第一行代码》中的内容,遇到了一些各式各样的问题。一些是自己粗心的问题,一些是由于版本的问题,所以我打算记录下来,一方面可以帮自己整理一下思路,记录问题,另一方面也希望自己的经历能够帮助其他一起学习《第一行代码》的同学,我们共同进步。这篇博客的内容是针对第九章——网络编程中的...
Mac环境下composer安装和使用定义作用安装常用命令create-project创建一个larabel项目使用创建依赖库文件composer.json下载依赖库第三方依赖库和项目工程的composer.json文件区别自动加载配置加速镜像国内镜像附件通过软链和composer部署项目 composer官网composer学习定义Composer 是 PHP5.3以 的一个依赖管理工具。它涉及 “packages” 和 “libraries”,但它在每个项目的基础上进行管理,在项目的某个目录中
题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。如果不存在则输出0。如 数组{1,2,3,2,2,2,5,4,2}。数字2在数组中出现了5次,超过数组长度的一半,最终输出2。思路:目前只找到O(n)的解法。初始认为数组第一个数就是目标数(target)。之后遍历数组后面的元素,如果等于目标数,计数++; 否则计数--;如果发现目标数的计数
一、引言在 SSH 工具的使用过程中,我是一直都不满意的:SecureCRT 收费,并且界面不能接受;XShell5 不再可以免费使用;XShell6 收费,功能确实强大,使用不可描述的版本,总是要一个月重新安装一次;Finalshell 是国人写的,界面确实小巧好看,但是功能总是觉得不够强大;在网上搜来搜去,终于看到了 MobaXterm,有基本能够满足需求的免费版供我们下载使用…但是,我还是 PASS 掉了 MobaXterm:因为他的字符编码中没有 CBK2312 的选项,也就是
设计图 实现 // PortScan.cpp : 定义控制台应用程序的入口点。// //#include <stdafx.h> #include <stdio.h> #include <Winsock2.h> #pragma comment(lib,"Ws2_32.lib") //目标地址#define IP "172.16.180.38" //线程个数#define THREAD
原文:[UWP]如何使用Fluent Design System (上)1. 前言微软在Build 2017中公布了新的设计语言Fluent Design System(以下简称FDS),不过官网只是堆砌了各种华丽的词语以及一堆动画。至于在UWP中要做成怎么样,怎么做,可以参考这个视频:Build Amazing Apps with Fluent De...
imageDataAugmenter()是MATLAB自带的图像增强选项,**返回的是一组设置(options)**,比如要不要反转,或者随机缩放多少之类的,而不是直接返回增强后的图像。
1. 在CUDA运行时API中有很多函数可以帮助管理这些设备,使用这些运行时API查询设备信息,代码如下:#include <stdio.h>#include <stdlib.h>#include <cuda_runtime.h>#include <math.h>#define EXIT_FAULLURE -1#define EX...
tag: Web; JavaScript; SVG; DOM; 动画 SVG最近在项目中遇到了「带动画 SVG 图标」与 「image」标签结合使用的场景,使用过程中发现水还是有点深,因此整理出来,供有相似场景的童鞋以参考。问题背景我们这里有一个的带动画 SVG 文件这是一个水波纹效果的 SVG,动画时长是固定的,但是我们希望不同的标记动画的播放时长可以略有不同,进而产生错落交错的感觉。...