题外话
测试入门
很多受过高等教育的大学生经常问要不要去报测试培训班来入门测试。
答案是否。
高等教育的合格毕业生要具备自学能力,如果你不具备自学能力,要好好地反省一下,为什么自己受了高等教育迷恋于各种入门级别的培训?是没有毅力还是不知道学习方法?
没有毅力的话,要自己多看些励志的书,多想想社会的残酷,亲人的失望等来勉励自己,毕竟企业多半也不会喜欢懒散的人的。
不知道学习方法的话,可以去知乎上看看,有些地方是回答得挺好的。简而言之,读《软件评测师教程》(国内软件评测师教材),《Software Testing Foundations 4th》(强烈推荐 国外测试认证ISTQB教材),《谷歌测试之道》是通常比培训机构更好地入门测试。这些测试入门书籍可以在 qq群144081101 567351477的共享找到。
我身边碰到比较有水平的软件测试,没有一个是什么*石、*testing、*林、*鸟、*内等入门测试的。而且这些机构经常打着包就业的名义骗人去培训,培训的老师通常口才很好,善于包装,但是关键的一点,这些老师多数自己都不是合格的测试。培训完之后有些学生重学几次又无法就业,甚至出现学生和培训机构对簿公堂的情况(这种情况通常是培训机构败诉,如果你身边有这样的被骗朋友可以建议他们先交涉不行再找律师保护自己)。
实体培训业尤其成为打着就业的幌子进行行骗的重灾区,导致现在主流企业一看到有某些机构经历的简历直接连面试机会都没有了。
当然不是一棍子打死所有的测试培训,比如斯特沃克的培训,google的gtac等分享是做得相当不错,建议自己先对测试有一定的了解,了解测试培训授课老师的水平之后再选择培训,尽量自学为主,在身边找有经验的实际测试人员稍微带下。
测试的方向整体是功能测试的工作岗位逐渐减小。facebook就没有测试人员,google也没有专职的功能测试,功能测试由开发、产品、用户等分担会降低沟通等成本。未来的测试人员更加需要开发技能。
对于太极,推拿之类的,视频是一个很好的学习方法。但是对于软件自动化测试,最好的学习方法不是听课,也不是看视频,而是在有经验的专业人士指导下进行项目实战、发现问题、解决问题。实战实战再实战!
本人曾在公司项目中曾手把手教刚毕业的毫无编程基础的技校生接口、性能、自动化等测试,结果3个月之后他们都跳槽,薪水从4k涨到10k以上(2015年)。
自动化测试进阶
IT主要技术体现为英文,要想提升到比较高的水平,必须要有流利的英文阅读能力。
搜索引擎方面要珍惜生命,远离竞价排名,做个有良知不受骗的人,从不用死不悔改的*度开始,优选google,其他的还有 必应 雅虎, 很多QQ群还有免费fanqiang工具。google的搜索通常能直中目标,stackoverlow的回答通常是首选方案。
选择有水平的业内人士帮助是掌握linux、python和测试基础之后一个迅速提升的方法。
- 技术支持qq群: 144081101(后期会录制视频存在该群群文件) 591302926 567351477 钉钉免费群:21745728
自动化测试的层次
从图看出自动化尽量以单元、接口为主,如果你有志在自动化测试深入,还在死磕QTP,selenium等的话,建议看下pytest、pexpect、API测试、单元测试等。
脚本
1-1 不要在实际项目中使用录制和回放
大多数自动化工具(特别是商业工具)具有记录和播放功能,这个功能的表面简单,实际是一个众所周知的陷阱。录制和回放在广告视频和演示文稿中看起来非常棒。但录制的脚本不使用变量,循环和条件。自动创建的程序和函数的名称通常不直观,通常所有操作都录在一个函数中(可能很大),执行不稳定,维护成本也高。
- 录制和回放适用点
- 在学习自动化工具
- 不重用的工作
- 很难识别和处理的控件
1-2 不要使用暂停
暂停,比如python中的:
#!python
import time
time.sleep(5)
定义全局变量可以避免大量代码修改,如下
#!python
WAIT_TIME = 5
...
time.sleep(WAIT_TIME)
上述等待不利于快速执行,较快出现的控件同样需要常见等待。等待对象或对象属性是更好的选择,比如selenium中的显式等待:
#!python
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
又如selenium中的隐式等待:
#!python
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10) # seconds
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
以WebDriverWait一定的时间间隔检查对象的存在(例如每秒一次),如果象出现对,则返回true。如果对象在timeout参数指定的时间内没有出现,则返回false。因此,如果控件一秒钟内出现,那么等待时间将会是 1秒。
当然短时间的等待,有时也是必要的,比如降低CPU使用率,短时间等待状态改变等。
1-3 在循环中超时退出
以常量的形式定义类似超时。例如定义两种类型的短超时(3秒)和长超时(3分钟)。
1-4 不要将自动化测试完全等同于开发
然自动化需要编程技巧,但它通常不是完整的开发项目。自动化常由初级程序员开发,因为工作简单得多,并一般为内部需求。在99%的情况下不需要大多数设计模式。在使用数据库时不会使用事务。测试数据量一般不会很大。
代码要力求简单,快速开发。即使使用了行为驱动开发(BDD:behavior-driven development)或关键字驱动的测试(KDT:keyword-driven testing)等方法也要尽量保证代码简单。
1-5 不要写复杂的代码
在使用条件和条件时,尽量遵循“不超过三个嵌套级别”的规则。
代码嵌套超过三层非常难以调试。宁肯代码多重复也不要嵌套超过三层。
1-6 验证逻辑条件的所有选项
#!python
if A and B or C:
# if (A and B) or (C and D)
定要检查这些代码的每个条件(在这个例子中的A,B,C)和所有可能的True和False。添加括号能增加可读性。
1-7 使用编程规范
初学者通常不太关注变量和函数的名称使用任何规则。尽管如此,几乎所有的语言都有所谓的编码标准。比如python的PEP8, google的编程规范。
在大项目中这些标准成为强制性规则,方便互相理解代码。
1-8 使用静态代码分析器
对于流行的编程语言,有特殊的代码分析器。例如Python的pylint,JavaScript语言的jslint等。
特别指出对python这样的动态类型的语言,这个更加重要。
pylint通常有很多误报,但是mypy的检查则比较实用。参考:python代码分析和lint。
1-9 随机
比如打开菜单有快捷键、下拉菜单、图标等多种方式,尽量写方法随机调用各种方式。以求覆盖各种场景,不过要记得添加日志以便跟踪错误。
1-10 不要使用坐标
非标准控件尽量不要使用坐标,可以用图像识别的方法:
#!python
Window.Toolbar.Click(135, 15)
替换为:
#!python
toolbar_click_button_by_image(Window.Toolbar, "Button Caption")
1-11 学习和使用库
比如:
#!python
full_name = '{0}\\{1}'.format(file_path, file_name)
在linux上就比较尴尬,可以替换为:
#!python
full_name = os.path.join(file_path, file_name)
1-12 避免复制和粘贴
复制的代码维护成本很高,尽量提取为公共库。
1-13 异常捕捉到具体的类
异常通常是程序考虑不周到才会发生:
#!python
try:
x = input('Enter the first number: ')
y = input('Enter the second number: ')
print x/y
except Exception as e:
pass
上述捕捉所有异常并忽略异常的代码通常只在临时代码中使用。通常也要把异常异常信息显示出来。比如
#!python
import sys
try:
x = input('Enter the first number: ')
y = input('Enter the second number: ')
print x/y
except Exception as e:
print e
for item in sys.exc_info():
print item
又如:
#!python
import traceback
import cv2
import numpy as np
def raw2jpg(filename, height=480, width=640):
try:
img = np.fromfile(filename, dtype=np.uint16)
img = img.reshape( (height, width) )
img.astype(np.float)
img = np.sqrt(img)
img = img * (255 / img.max())
#img.astype(np.uint8)
cv2.imwrite(filename+'.jpg', img)
except Exception as info:
print('Error: {}'.format(filename))
print(info)
traceback.print_exc()
return False
return True
更佳的方式是捕捉到具体异常:
#!python
try:
x = input('Enter the first number: ')
y = input('Enter the second number: ')
print x/y
except ZeroDivisionError as e1:
print("ZeroDivisionError")
except TypeError as e2:
print("TypeError")
另外一种异常处理方式:
#!python
far = 0 if not no_number else far_number/float(no_number)
1-14 代码与数据分离
对于小数据集可以使用数组或列表。大数据可以使用数据驱动测试(DDT:data-driven testing)。数据源可能为数据库,Excel或CSV文件等。
注意点:
- 以读模式打开数据文件。
- 每列只存储一种类型的数据。在数据库的情况下,
- 用完关闭与数据源
- 数据文件中不要用空行
1-15 调试
简单的可以多使用print或者logging打印一些信息。更高级的内容有
•断点 •单步执行 •查看本地和全局变量的值 •观察变量和表达式
1-16 不要为未来编写代码
项目的变化是很频繁,可以做一些自动化测试的技术预研,但一般不要书写有些只供未来使用的代码。
1-17 让代码更好
在不影响性能的情况下提高可读性。
1-18 测试选择适当的语言
•很重要:语言上手的难易程序和流行度及库支持。一般而言python因为其容易上手、是胶水语言(与其他语言调用方便)、语法简洁、维护成本低、方便调试,是目前自动化测试占有率最高的首选语言。但是c#在windows平台、java、c++等也有一定的市场。虽然python的占有率最高,但是一定要考虑到有些自动化测试开发可能已经有c++,go,java之类的现成的工具。 •尽量不要产生新的编程语言。 •咨询开发 •可以和开发采用同一种语言,尤其是单元测试,一般为采用和开发一样的语言。 • 简化API测试等其他原因
值得注意的是TCL(Tool Command Language)早起因为expect的命令自动化拥有一定的名声,且testcenter、smartbits等仪表一度不支持python等主流语言。但是TCL的语法晦涩,功能弱小,是能不用就不要去用的语言。
1-19 使用变量前要初始化
这个在python中可以用mypy检查。
测试最佳实践
2-1 不要实现被测应用的功能
因为:
•计算和逻辑可能很复杂,且开发已经实现了 •计算和逻辑可能会更改 •使用浮点数的精度可能和语言有关。
白盒和灰盒测试中一般是知道输入和预期结果就好,不要知道具体内部实现得的过程。
例外:大数据、搜索引擎中间算法等不明确预期结果的测试,经常用python快速实现一遍,与开发用c++等语言实现得结果进行比对。
2-2 测试的独立性
2-3 哪些不应该自动化
主要是基于成本考虑
•难以维护的自动化。 •尽量多做单元测试和接口测试的自动化,少做UI层的自动化 •重复使用次数不多的自动化
有些手工不能做的必要测试,即便自动化的成本很高,也是需要自动化。
2-4 向开发人员寻求帮助
开发在具体的开发方面可以值得学习,但是在自动化测试很方案方面自己定夺比较好。比如结果验证,开发大多喜欢直接从数据库中读数据,但是实际上展示数据库数据的应用也是可能出问题的。
2-5 云测试
云测试
•要测试桌面应用程序,必须打开会话,操作系统是否支持 •硬件相关的测试云测试支持并不方便。 •移动设备的云服务通常比较贵 •Web应用程序的自动化比较适合在云中执行。 •手机兼容性的测试可以考虑云,功能自动化测试则不用云比较好。
2-6 充分利用边界值和等价类
2-7 错误与警告
注意区分自动化测试平台或工具的错误和被测应用的bug。
2-8 使用合适的技术
在测试自动化中使用了许多特定的方法:ODT,DDT,KDT,BDD,页面对象,基于模型的测试等等。比如那么对KDT一般需要一部分写测试平台,一部分写测试库,一部分写测试用例。
2-9 特殊错误的验证
可以书写一个临时的测试来处理某些特定的bug。
2-10 在写真实测试之前做POC
环境
软件测试自动化中有两种主要的环境类型。一个创建和调试测试,另一个用于运行测试。
3-1 为您的需要选择一套适当的工具
以接口自动化测试为例,一些团队,执着的认为java是最好的语言,要用java去发HTTP请求,更有甚者,用jmeter去做接口自动化测试。不排除个别场景,这可能是合适的方式,但是通常的HTTP接口测试,用requests,代码行数通常比java少一个数量级,还不用编译。
python是主流语言中的胶水语言,和其他语言配合都比较完美,通常情况下是自动化测试的首选语言,但是python未必适用所有地方,还需要其他工具和语言进行补充,不过不要太多,学习很多语言也是一件痛苦的事情。
现在还有很多培训机构在鼓吹UI自动化就是自动化测试的全部,一说自动化就是QTP,一问Selenium,Testcomplete之类的都不知为何物,更不用说什么junit,pytest之类的了。
3-2 慎用自动提交bug
配置错误,测试代码错误经常导致测试失败。
测试代码有时难以描述清楚测试步骤
注意不要提交重复的bug。
在没有十足的把握的情况下可以用半自动的方式,发送邮件给测试人员,然后又测试人员提交bug。
3-3 不要使用欺骗的结果
避免注释测试代码的问题部分或改变预期的结果,以便测试不会出现失败。
如果实在用禁用,要知道禁用用例的比例,后面定期检查修改。
3-4 熟练使用工具
比如wingide中Ctrl + \为注释代码的快捷键
3-5 使用版本控制系统
避免文件丢失,方便协作,尽快使用hg、git之类的。
3-6 避免自定义表单
本来自动化就是为了把页面的东西尽可能走后台,你为了取悦领导(附:大陆目前多数测试领导是不太合格的)还是什么原因,搞成形式主义了。
参数可以用配置文件等方式。
3-7 自动化所有能自动化的东东
比如:测试,代码,测试环境,虚拟机,SQL查询,测试数据,报告等等
运行,日志记录,验证
4-1 尽可能经常运行脚本
4-2 测试失败时重新执行
当出现错误时应用程序运行很长一段时间,或特定情况下要尽量定位问题。
一般而言失败的测试先记录下来,所有测试执行完之后在重新执行一次。
4-3 丰富的日志内容
错误日志尽量包含:预期值,实际值,地点和操作。
参数尽量用引号等括起来,以免把包含空格的参数当成多个参数。
4-4 截图
UI测试必要的时候可以截图,同时处理好滚动。
4-5 尽量避免比较图像
审查
审查是保持码清晰易懂的好方法,要做代码的互相评审。
5-1 让非自动化者也可以看懂代码
#!python
def test_login(url, user, password, text):
open_page(url)
login_as(login=user, password=password)
verify_page_opened(text)
5-2 避免不必要的优化
在开始执行任何优化之前如需要慎重考虑。
通常不需要的优化工作看起来像这样:
1.应用程序启动3秒钟,然后进行5秒钟的测试脚本填充搜索字段,还有5秒钟搜索过程,之后脚本用1秒钟读取找到的数据并进行验证。 2.测试人员开始优化读取和验证 3.测试人员花费一天时间进行优化并达到目标:阅读和阅读每次运行时间为半秒
事实上,测试工程师的代码生产力已经翻了一番,但是结果是他整体方案取得了约5%的收益。花一天时间是不值得的。一般需要综合考虑,涉及脚本、被测应用、环境、执行频率等。
建议你在两种情况下优化测试:
•如果测试运行时间过长,并且测试的应用程序是在测试执行期间空闲。 •如果您在代码中看到明显的问题,请更正其中的问题。
pandas大数据分析性能优化实例-read_csv引擎和分组等,这里是一个必要的优化实例。
5-3 定期审查别人的代码
定期审查别人的新代码。可以结对编程,甚至是同时一个人写,一个人看。
5-4 参与论坛和讨论
如果您是自动化领域的初学者,并且在自动化团队中工作,那么会从你的同事那里学到很多东西。如果你是唯一的自动化工程师在公司或你的部门没有人能帮助你?
知乎,特别是stackoverflow等社区常常可以找到自己问题满意的答案。同时试图帮助别人也可以扩展自己的眼见。
5-5 执行重构
重构是对现有代码的简化,功能和应用程序不会改变。尽管测试自动化中的代码通常很多实际应用更简单,有时候你仍然需要重构。
•您可能会发现您所支持的代码太复杂。 •可能有编写新测试的请求,需要修改代码 •可能需要重构来改进已编写的代码
重构后可以执行所有测试来验证,也可以在公共库等地方添加必要的单元测试。
5-6 删除低收益的测试
•测试执行了多少次; •测试发现了多少实际问题; •测试需要多久进行一次维护。
参考资料
本文涉及的python测试开发库 请在github上点赞,谢谢!