知乎专栏 |
最近面试软件自动化测试工程师,感想颇多。面试者都来自大厂或大厂外包,华为,oppo,顺丰,沃尔玛,百丽,腾讯,字节……
开始以为捡到宝了,即使没吃过猪肉也见过猪跑吧,起码参与过自动化测试,面试后大失所望。
面试了很多工作十年的测试工程师仍然在做功能测试,或是功能测试为主,自动化测试打酱油。
什么是打酱油?我们有自动化测试,我们做了。但是自动化对工作的贡献微乎其微,也就是说自动化测试并没有真正为企业带来价值,最后自动化测试脚本不再有人维护,被人遗忘。
问及为什么自动化测试流于形式?实施自动化测试最终摆脱不了失败厄运,会不了了之。每个人都给出无数理由,在我看来是无数借口。
十年前我曾经写过关于自动化测试为什么难以普及的文章,时隔十年,都2021年了,自动化软件测试普及程度跟10几年前情况差不错。究竟问题出在哪里呢?
如果你是管理层,你会发现,自动化测试工程师人在招聘,事在做,钱在花,但是没有成绩。仍然人工测试为主,自动化辅助。
难道无法实现自动化为主,人工为辅吗?
此前我在一直在外企工作,为什么外企能做到自动化为主的测试呢?我认为有以下几点:
你问测试人员我们有没有做自动化,答案是:
这话没毛病,确实不能100%替代,但是自动化测试可以干80%的活。剩下20%人来干。
我不这么认为,我们通过持续集成运行自动化测试脚本,一旦发现流水线测试失败就会立即修复自动化测试脚本。只要紧跟开发,开发动,我就动,联动开发,就可以解决这种问题。写测试脚本的工作量远没有开发的工作量和强度大。更多时候只是修改定位元素标签而已。
人工测试前首先要通过自动化测试,这样可以避免盲目测试。也就是人工测试走了大部分流程后才发现往下走不通了,此时已经浪费了时间,为什么不让自动化程序去发现问题呢?
在国内包括大厂,软件自动化测试处于很低的水平,测试人员水平也相对低于其他团队,例如开发和运维。为什么 DevOps(运维自动化)在国内能风生水起?因为DevOps 在为企业创造价值。
DevOps 降低了IT成本,解决企业面临的众多IT痛点。
管理层重视程度,管理层能力,管理层认知都决定最终结果。
管理层重视自动化测试,但是能力又无法推动。
招聘也存在问题,管理层的认知天花板决定他招聘进来的员工天花板。
即一流人才做面试官,只能招聘到二流人才,二流面试官,只能招聘来三流人才,以此类推。
最终一个乌合之众的测试团队被攒出来。
互联网技术越来越复杂,HTML 4.0 的时候只有 form 表单提交,那时做自动化测试畅通无阻,非常顺利,后来有了ajax 和复杂UI,导致自动化测试难以进行。
很多测试工程师的开发水平仅限于测试,没有从事过前后端开发,遇到问题被卡住,解决不了,就放弃了自动化测试。
测试团队能力不足是最大问题,多数测试人员的职业生涯规划是失败的,从功能测试走到自动化测试的人非常少。
成为自动化测试工程师,需要三个因素:自驱力,外驱力,环境因素。
自驱力是自我学习的动力,外驱力是外部施压强制员工学习,以满足岗位需要,两种力都具备后还需要有环境,包括学习环境(氛围)应用环境(学以致用),实战机会等等。
很多公司的想法是招聘一两个自动化测试人员,更多配置是功能测试。
这个想法就是错误的,从一开始就注定了要以功能测试为主。尤其是当测试组的leader是功能测试者后,他会更坚信自动化测试替代不了人工测试,在自动化测试短期没有成绩的时候,他会本能否定自动化测试,最终将会从自动化专人工。
由于自动化测试人员少,就会有孤独感,遇到问题解决不了,没有人沟通,工作容易被卡住。
所以氛围很重要,要打造学习型团队。提供分工,教练,合作,咨询,培训, 提升团队整体素质。
自动化测试仅仅被认为是替代人工,所以我们看到很多企业实施自动化测试仅仅是将现有的 Test Case 转换成自动化脚本。
这样做既没有提高测试整体水平,也没有改善测试结果。结果是通过手工能测试出来的问题自动化测试可以测试出来,手工测试不出来的问题自动化测试也没有测试出来。
因为测试的观念仍停留在已有 Test Case 阶段,而 Test Case 停留在业务流程测试的阶段。
最终自动化测试仅仅是按照测试用例走一遍业务流程,完成业务流程的检验。
随着技术发展,软件的多样性,测试已经不局限于基于CS结构的GUI测试, 基于BS浏览器WEB UI测试。例如目前的安卓系统,苹果IOS系统,微软的 Windows Mobile 系统等等也加入到自动化测试领域。
应用软件也越来越复杂,例如:
分层的变化:界面层,接口层,业务逻辑层,实体模型层
部署的变化:从单机运行到双机热备份再到负载均衡,最近进化到分布式系统。
存储的变化:关系型数据库,非关系型数据库,缓存数据库,搜索引擎数据库
从下面的金字塔架构可以看出软件展示给用户的只有UI界面层
/\ / \ / UI \ /------\ / API \ /----------\ / Service \ /--------------\ / Component \ /------------------\ / Database \ /______________________\
上面是软件的分层,一个软件经过部署后结构将会更复杂。
/\ / \ /CDN \ /------\ / WEB SER\ /----------\ / APP Server \ /--------------\ / Message Queue \ /------------------\ / Cache|SearchEngine \ / Database| NoSQL \ /________________________\
就WEB应用测试而言,涉及的内容就太广泛了,从浏览器->WEB服务器->APP服务器->缓存->数据库,中间会经过各种代理,负载均衡,分布式文件系统等等。
我们测试要涵盖:
CDN测试,域名解析测试,
WEB UI测试,包括HTML,Ajax
API 服务器测试,api 是非人机交互界面,它是通过特定协议与API服务器交互通信。
代码单元测试
配置测试,配置管理过程中配置变更后的测试,含系统与应用
安全测试,接口安全,认证,权限
注入测试,JS注入,SQL 注入,Shell 注入
缓存测试,命中率测试,包括CDN,WEB服务器,缓存服务器,搜索引擎
压力测试,健壮性测试
扩展性测试,水平扩展测试,垂直扩展测试
高可用测试,集群测试
请参考我的另一篇文章《压力测试中存在的问题》
这里我要再单独强调压力测试,很多人的测试方法是有问题的。
压力测试不是准备一台机器安装压力测试软件就可以开始测试的。 压力测试的环境非常重要,很多工作多年的测试人员都没有意识到这个问题。
压力测试有两个重点,一是压力测试环境的建设,二是压力测试顺序。
压力测试无论是单机还是网络,都需要一个好的压力测试环境,例如网络好比高速公路,如果公路成为瓶颈,你能测试出准确的数据吗?
首先准备测试环境,如单机测试要考虑CPU速度,磁盘IO速度,RAID卡的速度,RAID卡缓存大小,内存速度,PCI—E总线速度,甚至会涉及多对称CPU相关配置,内存与CPU通道的问题......等等
如果是测试分布式系统,除了上述单节点的注意事项,还要考虑到路由器/防火墙的包转发与连接数限制,交换机的背板带宽以及吞吐能力,负载均衡器的转发能力。
操作系统要考虑内核参数优化,TCP/IP栈优化,各种服务器的配置。
压力测试顺序的切入点非常重要,测试顺序上多数人是从UI(人机界面)切入,即由UI驱动业务逻辑,这种测试顺序是错误的,例如用户->浏览器->WEB服务器->APP服务器->缓存->数据库等等,这就带来很多问题。
\------------------/ \ Web server / \ App Server / \ Cache / MQ / \ Database / \ Disk IO/ \ /
软件的性能瓶颈通常是沙漏型的,最大的瓶颈莫过于数据库,其他服务器的瓶颈我们都能从架构的角度去解决性能问题。
所有我们应该先从数据库测试,首先确认数据库的配置优化是否能达到我们预期值。然后是缓存,消息队列,搜索引擎等等.....
至此我们已经知道数据库,缓存,消息队列,搜索引擎不会成为我们压力测试中的瓶颈。接下就可以测试应用服务器和应用软件了。
如果你的测试格局能够放大一点要考虑的远不止上述那些。 你还需考虑硬件,网络,操作内核参数优化,TCP/IP栈优化,验证运维配置是否能满足我们需求等等.....。
我们需要有一套监控解决方案,能够监控到硬件的性能,软件的性能。
测试目的不是为了得出一个结果,告诉开发人员你的软件能支撑XXX并发,而是在我们测试中监控每项操作,计算出每个功能所用的时间,分析出性能的瓶颈,指导开发人员改进软件。
监控分为外部监控与内部监控。
外部监控是最容易实现的,有成熟的工具以及解决方案,CPU,内存,磁盘IO,网络流量等等。
内部监控是指软件运行加载到内存中之后的变化状态,例如内存地址,变量,函数调用,动态链接库载入,打开文件句柄,Socket地址和数据包等等。
持续集成,自动化构建几乎每个测试团队都会实施,但实际境况并不理想,仅仅停留在工具配置的阶段。几乎没有人在生产环境上使用自动化构建。
为什么持续集成无法应用到生产环境?
(待续,敬请关注作者微信公众号,现在已经是早上6点中了,要去睡觉了)
![]() |
软件压力测试是一种基本的质量保证行为,它是每个重要软件测试工作的一部分。软件压力测试的基本思路很简单: 不是在常规条件下运行手动或自动测试,而是在计算机数量较少或系统资源匮乏的条件下运行测试。 通常要进行软件压力测试的资源包括内部内存、CPU 可用性、磁盘空间和网络带宽。
压力测试涵盖,性能测试,负载测试,并发测试等等,这些测试点常常交织耦合在一起。
我归纳一下有几点:
操作系统默认安装,在未做任何优化的情况下实施压力测试
未考虑磁盘IO对软件的影响
未考虑网络带宽对软件的影响
网络软件测试,没有考虑到TCP特点
各种超时参数优化
测试客户端未优化
并发理解有误
WEB服务器,数据库,等等服务器未优化
如果上面几项没有做优化,压力测试数据基本没有任何参考价值,任何一项没有优化,都会导致你的压力测试数据出现偏差。 下面我来逐条说明:
操作系统问题: 操作系统是大众化软件,出厂优化都是面向大众,不可能为某个领域做单独优化。所以我们第一步需要优化操作系统。 Linux 系统优化内核参数,Windows 系统优化注册表等等。
磁盘IO: 这是最容易出现瓶颈的地方,常常是CPU还没有达到极限,磁盘已经不堪重负。
网络IO: 与磁盘IO相同
TCP连接: 几乎所有 B/S, C/S 软件都是采用多线程,或者多进程技术。这种技术有个特点,开发者将程序设计为线程可自动伸缩模式,开启进程后会启动少量线程,当连接不断提高后,线程数逐渐增加,随着线程运行结束后,线程逐渐减少。 这样的设计会更有效地利用硬件资源,在程序空闲时将硬件资源让给其他进程。少有软件设计为开启服务独占资源。 这样测试软件做压力测试,不能一次并发很多请求,而是要采用逐渐增加的方式,否则第一次测试会有一部分并发不能及时响应,导致测试数据偏差。另外也你可以多做几次压力请求(让多线程工作起来),从第三次开始记录测试数据,忽略前面两次的测试数据。
提示:另一个问题是TCP连接复用,这也是一个重要配置项。如果这项没有配置,我想测试出的数据也会有偏差
超时参数: 超时参数在压力测试中是非常重要的参数,例如从WEB到数据库连接超时是60秒,如果有一个SQL查询超过300秒,那么后面的请求会持续排队等待,当连接数达到数据库的最大连接时,接下来的所有请求都是失败的。 通常我们的WEB服务器超时不会超过30秒,有时我设置为10秒,一旦出现超时,宁可让该连接Timeout,不要让他影响整体服务。
客户端: 很多网络软件需要从客户端发出压力测试请求,所以客户端的优化也是必须的,否则客户端压力出不去,服务端压力进不来。
并发: 很多人认为并发,就是同一时间内的最大连接数,这是错误的。如果你写过多线程程序,就会发现多线程运行时有规律的。是顺序排队运行的,根本不是同时运行的。 所以并发是指,相对时间内能完成的连接总和,例如,每秒并发,每分钟并发等等,通常我们已秒为单位。 我们目前使用的操作系统叫分时操作系统,这种系统的特点就是可能实现多用户,多任务。操作系统将进程排队(优先级)轮询运行,只不过这个操作太快了,使你认为多个进程在同时运行。
服务器优化: 主要B/S软件压力测试,WEB,缓存,数据库等等服务器,都需要逐一优化到最佳状态
如果在软件设计阶段都将这些问题元素都考虑进去,同时开发阶段严格执行。那么开发出些软件几乎不用做这个劳人伤神的压力测试。
所以在软件设计阶段就要考虑,灵活性,扩展性,可靠性与性能,还要考虑高可用与负载均衡。
同时软件优化伴随开发,持续集成,持续测试,持续部署。
下面我们举一些例子,讲述压力测试方法,限于篇幅不可能面面俱到,我仅仅是给你提供思路。
测试前你需要一些监控工具,实时监控服务器的资源变化。
例如 Web 服务器压力测试,测试场景是 nginx :
worker_processes 8; 处理器数 worker_rlimit_nofile 65530; 允许最多打开文件数 worker_connections 4096; 最大连接数数为 keepalive_timeout 65; 开启复用连接 gzip on; 压缩传输数据
怎么测试呢?你要获得最大化性能吗?还是相对性能?我们通常需要的是满足需求就好的相对性能,而不是最大化性能。为什么呢?因为要获得最大化性能是要做出很多配置牺牲的,例如关闭日志,禁止访问时间等等。
按照上面的配置你的测试用例应该是,每次并发4000 请求 8000~10000 次, 你不能并发8000 请求 4000 这样测试。很是很多人常常犯的错误,所以测试者需要连接系统的配置参数,不能盲目使用数字实验。
上面我说过线程的开启时随着请求,逐渐增加的,所以首次发起测试数据是不准确的,通过pstree命令可以看到线程数量。等第三次以后线程逐渐增加到4096个,并且之前开启的TCP可以复用,这时测试的结果比较有说服力。
延伸阅读《Netkiller Web 手札》《Netkiller Testing 手札》《Netkiller Linux 手札》
什么事协议? 协议是计算机进程或网络中进行数据交换而建立的规则、标准或约定的集合。
什么是协议测试? 协议测试就是软件界面与应用服务器间通信规则的测试。
需要注意一点,协议测试不是接口测试,接口测试通常是RPC调用,例如基于HTTP SOAP, XML-RPM 并不在本文的讨论范围之内,接口测试可以放在单元测试中。
传统测试更多注重界面的测试,界面是针对用户的,也是唯一可见,也是最容易测试的。我们通过下面的金字塔说明。
```text /\ / \ / UI \ /``````\ / API \ /``````````\ / Service \ /..............\ ```
用户只能看到 UI ,UI测试是有局限的,只能看到冰山一角,越往下层越难发现软件的缺陷。
互联网的今天应用软件已不仅仅是三层架构,互联网特点是多语言混合开发,软件运行在异构平台上。
举例最简单的B/S结构的应用测试如下:
```text 用户 -> DNS -> CDN -> Proxy / SLB -> Web -> Application -> Cache -> Database ```
这已经是最简单的结构了,复杂都远不止这些。中间环节还可以加入搜罗引擎,计划任务,单点登录......
所以仅仅通过UI测试是无法满足,但我们往往看到企业中测试团队的人员比例是,UI测试人数最多,Service 人数最少,呈现出倒金字塔形状。
这里谈的协议,不仅限于UI到服务间的协议,还有服务于服务见的协议,进程与进程间的协议。
这些协议五花八门,有私有协议,有开放式协议,有二进制协议,有文本协议,还有中性协议二进制与文本混用。
难以归类,从不同角度可能做不同的归类。
协议测试可能是传统科班出身测试工程师的门槛,但对于全栈工程师来说相对容易。协议测试通常无法使用现有的测试软件做测试,很多情况需要我们写专用的测试软件。
编写测试软件需要掌握哪些技术呢,除了精通一门语言还要掌握下面最基本的技能?
数据处理:
通信:
信号,线程,存储:
使用现有的测试软件
编写软件模拟协议发出请求然后验证反馈结果
嗅探,植入
目前自动化测试软件发展很快,可以实现很多协议测试,但仍有局限。所以仍然需要用户自己开发测试工具。
对于 HTTP GET / POST 完全可以通过现有测试软件实现我们的测试需求。
对于已知协议的测试是比较容易进行的,更多是工作是,编码/解码,协议的送出与反馈。
对于很多未知的私有协议就需要经验了,需要大量协议嗅探,总结,反复尝试。文本协议门槛比较低,对于私有的二进制协议难度相对高些。
学习协议测试分为几个阶段:
首先从文本协议开始学起,第一步先拿 SMTP 发送邮件 练手,了解基本协议后,就可以进行下一步学习,学习HTTP协议,处理基本的请求。
可以尝试自己开发一个 Web 服务器,不用太复杂,实现基本的目录浏览,文件下载,GET/POST 处理。最后学习ajax, json, websocket 等等,
然后学习二进制协议。早年都欢拿 MSN / QQ 练手,实现一个QQ机器人,这里涉及到其他语言处理C/C++的结构体的问题,就是 pack/unpack 操作,这是一道门槛,阔跨过去前途光明。
目前很多软件架构上尽量避免使用结构体,而是使用序列化例如msgpack/hession/Protobuf等等,主要是方便多语音环境的通信。
最后学习与硬件交互,可以拿GSM Modem AT 命令练手,DTMF 信令解码,AFSK数字信号处理 等等