51Testing软件测试网

 
 

常用链接

  • 我的随笔
  • 我的评论
  • 我参与的随笔

留言簿(3)

  • 给我留言
  • 查看公开留言
  • 查看私人留言

随笔档案

  • 2021年6月 (1)
  • 2021年3月 (1)
  • 2020年9月 (1)
  • 2020年3月 (1)
  • 2020年1月 (2)
  • 2019年12月 (3)
  • 2019年11月 (5)
  • 2019年10月 (1)
  • 2019年9月 (2)
  • 2019年8月 (14)
  • 2019年7月 (20)
  • 2019年6月 (15)
  • 2019年5月 (12)
  • 2019年4月 (19)
  • 2019年3月 (20)
  • 2019年2月 (9)
  • 2019年1月 (16)
  • 2018年12月 (17)
  • 2018年11月 (21)
  • 2018年10月 (16)
  • 2018年9月 (20)
  • 2018年8月 (22)
  • 2018年7月 (3)
  • 2018年6月 (1)
  • 2018年5月 (7)
  • 2018年4月 (1)
  • 2018年3月 (3)
  • 2018年2月 (6)
  • 2018年1月 (2)
  • 2017年9月 (8)
  • 2017年8月 (28)
  • 2017年7月 (3)
  • 2016年11月 (1)
  • 2016年6月 (1)
  • 2016年4月 (1)
  • 2016年2月 (2)
  • 2015年7月 (1)
  • 2015年5月 (1)
  • 2015年4月 (2)
  • 2015年3月 (1)
  • 2015年2月 (2)
  • 2015年1月 (6)
  • 2014年12月 (3)
  • 2014年11月 (3)
  • 2014年10月 (3)
  • 2014年9月 (2)
  • 2014年8月 (8)
  • 2014年7月 (16)
  • 2013年12月 (5)
  • 2013年11月 (1)
  • 2013年10月 (3)
  • 2013年9月 (2)
  • 2013年8月 (2)
  • 2013年7月 (3)
  • 2013年5月 (1)
  • 2013年4月 (2)
  • 2013年3月 (2)
  • 2013年2月 (3)
  • 2013年1月 (4)
  • 2012年12月 (4)
  • 2012年11月 (4)
  • 2012年10月 (3)
  • 2012年9月 (4)
  • 2012年8月 (3)
  • 2012年7月 (4)
  • 2012年6月 (2)
  • 2012年5月 (2)
  • 2012年4月 (1)
  • 2012年3月 (2)
  • 2012年2月 (2)
  • 2012年1月 (1)
  • 2011年12月 (3)
  • 2011年11月 (2)
  • 2011年10月 (1)
  • 2011年9月 (4)
  • 2011年8月 (3)
  • 2011年7月 (2)
  • 2011年6月 (4)
  • 2011年5月 (4)
  • 2011年4月 (2)
  • 2011年3月 (4)
  • 2011年2月 (4)
  • 2011年1月 (7)
  • 2010年12月 (7)
  • 2010年11月 (5)
  • 2010年10月 (4)
  • 2010年9月 (7)
  • 2010年8月 (7)
  • 2010年7月 (3)
  • 2010年6月 (3)
  • 2010年5月 (4)
  • 2010年4月 (4)
  • 2010年3月 (5)
  • 2010年2月 (3)
  • 2010年1月 (4)
  • 2009年12月 (3)
  • 2009年11月 (3)
  • 2009年10月 (1)
  • 2009年9月 (3)
  • 2009年8月 (2)
  • 2009年7月 (3)
  • 2009年6月 (1)
  • 2009年5月 (2)
  • 2009年4月 (4)
  • 2009年3月 (5)
  • 2009年1月 (1)
  • 2008年11月 (2)
  • 2008年7月 (5)
  • 2008年6月 (4)

文章分类

  • 行业资讯(45) (rss)
  • 软件业务知识(43) (rss)
  • 软件开发知识(33) (rss)
  • 软件测试工具(39) (rss)
  • 软件测试技术(157) (rss)
  • 软件测试管理(40) (rss)
  • 软件测试职业发展(57) (rss)

51testing软件测试网

搜索

  •  

最新评论

  • 1. re: 淘宝后台技术大揭秘,不看这篇你双十一要损失几个亿!
  • 关注官方公众号“Atstudy网校”,点击中间菜单栏“双11”,领取双十一技术内幕资料。
  • --51testing
  • 2. re: 软件测试流程的一点感悟
  • 提交缺陷时只需要描述现象即可,过多的分析可能会误导开发
  • --凡客诚品
  • 3. re: 软件测试流程的一点感悟
  • 阿达宿建德江阿斯顿
  • --凡客礼品卡
  • 4. re: 手机软件测试的经验总结
  • 很好啊~不错
  • --乐蜂网
  • 5. re: 手机软件测试的经验总结
  • 很好啊~
  • --罗莱家纺

阅读排行榜

  • 1. 软件测试流程的一点感悟(1091)
  • 2. 5年经验之谈:月薪3000到30000,测试工程师的变“行”记!(940)
  • 3. 测试自动化及软件测试工具的比较(858)
  • 4. 银行线上信贷系统如何做好接口测试?手把手教你接口工具Postman(825)
  • 5. 软件为什么要做异常测试?测试员必知的22个测试点总结!(807)

评论排行榜

  • 1. 软件测试流程的一点感悟(4)
  • 2. 软件测试的原则和经验 (4)
  • 3. 嵌入式软件测试技巧(2)
  • 4. 手机软件测试的经验总结 (2)
  • 5. 常用软件测试工具的分析与比较(1)

Powered by: 博客园
模板提供:沪江博客
IT博客 | 首页 | 发新随笔 | 发新文章 | 联系 | 聚合 | 管理

资料丨一套python学习视频,学完python基本可出师!

视频总共4套
本人好不容易收集过来
同时在论坛开启此帖进行分享
已经和论坛管理员商量好3种获取路径

链接:http://bbs.51testing.com/thread-1099351-1-1.html

End.

如果对软件测试感兴趣,想了解更多的软件测试知识,请大家关注“51Testing软件测试网”头条号。

相关热门文章

http://www.toutiao.com/i6426594521361940994/

http://www.toutiao.com/i6439201903241855490/

http://www.toutiao.com/i6439580855500276226/

http://www.toutiao.com/i6439919722615013889/

posted @ 2017-08-30 17:23 51testing 阅读(120) | 评论 (0) | 编辑 收藏
 
实战丨大神手把手教你拿下百度账号!
XSS漏洞想必很多行内人士都有所耳闻,这次我要分享的挖洞经历也是非常的意外。
  很多时候自己随手播种下的xss代码,有可能会在某一天神奇的带给你惊喜。
  这里不会讲XSS的基础知识,但是会通过一个真实的案例带你挖掘百度网盘的一个存储型XSS漏洞,这个漏洞原理非常简单,我能挖掘到更多的是靠运气,同时他也会是一个非常基础的实战教材。
  故事还要从很久以前说起,在以前百度网盘的客户端上有一个可以修改昵称的地方,当时使用百度网盘客户端本身来修改这个昵称最多只能修改10位,但是我通过抓包,修改包,重发包这个步骤发现可以将该昵称修改为一个很长的字符串。
  当时就想,既然他们这里只是前端做了限制,那么是不是意味着我把<script>alert(1)<script>这样的字符串放进去也是不会做过滤?而且刚好通过这种方法也绕过了前端的长度限制,有可能这里存在存储型XSS漏洞,因此我将昵称修改为了<script>alert(document.cookie)<script>。
  存储型XSS是什么呢?存储型XSS漏洞又叫做持久型XSS漏洞,因为这种漏洞本身是将具有攻击性的代码(又叫playload)持久化的存储在目标业务中的某个地方(比如说数据库, 缓存等),在另一个地方又会把这个攻击代码显示到页面上,显示的时候浏览器会将它当作合法的script脚本执行,便开始执行了具有攻击性的JavaScript脚本。这个提交你的攻击代码的地方就叫做输入点,显示你具有攻击性代码的那个位置就叫做输出点。
  既然是挖掘存储型XSS漏洞,并且我们已经找到了输入点,那么就要找输出点了。当时我在百度网盘的各个页面都做了全局搜索,结果能找到的地方都过滤了输出。于是我就没有去管这个漏洞了。
  大概过了几个月之后,偶然有一天晚上我在网上认识的一个网友准备通过百度网盘自带的给好友分享功能给我分享文件的时候,突然他跟我说在点击分享列表准备选择分享用户的时候突然弹出了一个网页对话框,内容就是他的cookie,我突然心中一惊,莫非输出点是在这个地方?原来这种输出点是需要交互,点开某个窗口之后才会渲染出来的,这属于一种比较隐蔽的输出点,怪不得我之前一直没有找到。看来渗透测试是一个细节点都不能放过啊。
  如果大家有心,平时可以随手把自己注册过的一些网站的个人信息改成各种xss脚本,说不定哪天运气好就挖到了一个XSS。随手播种,坐等收获。
  于是赶忙再去通过抓包,改包,重放这个过程,将昵称改为xss平台的收信脚本,然后重现这个过程,发现居然可以打到cookie,而且cookie中包含了百度账号最关键的BDUSS字段,该字段是百度账号用于鉴别用户身份的唯一字段,几乎所有百度业务中只要有该字段,等于拥有了同等账号权限。
  通过社工让对方给你分享文件的时候,神不知鬼不觉的情况下,你就把对方的百度账号沦陷了,而且现在很多人都用了百度网盘的云盘同步等功能,导致你手机上的短信,通话记录,通讯录,照片图库等一览无余。尤其是短信同步功能很危险,比如说百度贴吧的吧主审批操作就是通过短信验证码的方式判断,如果短信同步了,那么我们在拥有这个账号的情况下,只要通过查看同步到云端的短信,就可以通过他的账号审批通过自己账号的吧主申请,想想多么可怕。
  这个漏洞最后我是提交到了乌云,rank给了13,送了娃娃钥匙扣等小礼物。后来我听一个安全圈的朋友说他提交过类似漏洞是有很多积分,可以换各种购物卡之类的等额现金奖励,我这个漏洞如果提交到百度私有的BSRC可能有三位数到四位数的现金奖励,唉有点可惜啊。
  如果你们在各大乌云镜像站搜索【百度网盘】等关键词应该能找到该漏洞详情。
End.

如果对软件测试感兴趣,想了解更多的软件测试知识,请大家关注“51Testing软件测试网”头条号。

原文链接:

http://www.51testing.com/html/23/n-3720723.html

相关热门文章:

http://www.toutiao.com/i6426594521361940994/

http://www.toutiao.com/i6439201903241855490/

http://www.toutiao.com/i6439580855500276226/

http://www.toutiao.com/i6439919722615013889/
posted @ 2017-08-28 17:28 51testing 阅读(214) | 评论 (0) | 编辑 收藏
 
测试已死?我看未必!
 “测试已死”的观点在业内仍然存在着争议,很多公司缩减了测试人员,开发测试比屡创新高。本文旨在通过介绍软件测试的新趋势和新技术来展示软件测试行业面临的机遇与挑战,为软件测试工程师的职业规划提供参考。
  安全测试
  从孟加拉国银行 8100 万美元被黑客成功盗取到美国民主党邮件泄露事件可以看出,网络安全事件已经被推到了风口浪尖。随着物联网逐步普及,智能家居、汽车电子等设备的网络化水平大幅提升。但物联网的安全却不容乐观,很多中小企业往往忽视安全防护。开源软件的源代码公开,黑客可以通过阅读源代码更容易的分析出软件的安全漏洞,使得网络安全迎来了新的挑战。当开源社区中发布出 cve 漏洞时,需要厂商及时的合入补丁,否则将给黑客入侵敞开大门。
  新的编程语言的出现在提高了编码效率的同时,也为软件产品增添了安全挑战,需要安全厂商尽快推出相应的安全工具和安全加固方案。随着 SaaS 的普及,相信会有更多的安全工具问世。渗透测试需要测试工程师阅读源码来找出漏洞,与安全合规测试相比,需要更高的技术水平。在未来相当长的一段时间内渗透测试工程师将有很大的缺口。
  人工智能测试
  近年来,人工智能(AI)被越来越多的应用在 IT 行业,如智能汽车、智能家居和机器人等。尤其是 2016 年 AlphaGo 在围棋领域掀起一股热潮之后,AI 更多地成为人们热议的焦点。人工智能是一个新的领域,对于人工智能本身的测试方案和测试工具还有待完善。
  对于人工智能在软件测试领域的应用,即利用人工智能来优化其他软件的测试,目前已经取得了一定的进展。人工神经网络是软件测试领域使用相对广泛的 AI 技术之一。神经网络是基于生物学中神经网络的基本原理,在理解和抽象了人脑结构和外界刺激响应机制后,以网络拓扑知识为理论基础,模拟人脑的神经系统对复杂信息的处理机制的一种数学模型。目前在 OCR,语音识别,医学诊断等方面已经取得了很大的成功。在软件测试中,它非常适合 GUI 测试、内存使用测试及分布式系统功能验证等场景。
  遗传算法是另一个软件测试中用到的 AI 技术。它是模仿生物遗传和进化机制的一种最优化方法,它把类似于遗传基因的一些行为,如交叉重组、变异、选择和淘汰等引入到算法求解的改进过程中。遗传算法的特点之一是,它同时保留着若干局部最优解,通过交叉重组或者解的变异来寻求更好的解。在软件单元测试中,已知输入的参数的范围,求解哪些参数的组合能够达到最大的代码覆盖率(也有些研究是能达到最大的路径覆盖 / 分支覆盖)。因此,遗传算法可以用于选择最优的单元测试用例,也就是单元测试的最优输入集。同时利用人工智能还可以优化测试工具,将软件测试的上下文与测试用例结合起来,选择最优的测试用例集进行测试。
  静态分析与符号执行
  软件可靠性是对软件在设计、开发以及所预定的环境下既有能力的置信度的一个度量,是衡量软件质量的主要参数之一。而软件测试则是保证软件质量、提高软件可靠性的最重要手段。静态分析工具可以直接对源码进行扫描,但其误报率的问题有待改善。
  大量可靠性问题隐藏在未知场景和不熟悉的开源代码中,有必要通过程序行为分析工具来遍历各种异常分支、代码的所有路径。符号执行技术是精确的路径遍历,是随机测试、FUZZ 测试的有益补充。
  符号执行代表工具 KLEE,在第一次学术使用(2008)便发现了 unix 系统中最常用的程序的多个问题,有的问题已经存在超过 15 年。符号执行技术在之前没有得到大规模应用,主要原因是技术本身需要大量的计算资源(路径爆炸)。随着软硬件技术的发展,平均计算成本比之前降低了很多,为符号执行的发展和推广提供了有利的客观条件。目前符号执行技术已应用在许多公司的产品测试当中,如 HP、微软等公司都已经有 10 年以上的符号执行探索经验。当前基于 KLEE 的二次开发工具已经大量应用在软件可靠性测试中,如 Mayhem 已发现了 DebianOS 的上千个 crash 问题,以及 Linux 和 Windows 系统的几十个可利用漏洞。
  精准测试
  在当前敏捷测试的时代,版本发布日趋频繁,快速发布高质量的软件是很多企业的目标。对于急于发布的软件版本,全量运行所有的用例往往需要花费较长的时间,已经不能满足产品发布的节奏。如何避免过度测试并在时间、质量、成本中找到最佳的平衡?
  精准测试可让软件测试过程可量化衡量、可追溯,清楚的展示出测试用例运行的路径,并可以实现测试用例与代码的双向追踪。对于代码量较大的系统的软件,通过精准测试可以获取到曾经执行过某段代码的测试用例,当这部分代码进行修改后,只需执行对应的用例即可,大大缩短了测试的时间,加快了产品上线速度。因此精准测试成为了近期软件测试技术的新方向之一。精准测试的实施对测试人员的代码开发、测试设计、需求理解、架构理解、自动化测试能力均有较高的要求。
  云测试
  云计算是一种按需提供计算资源的技术,它可以减少用户基础设施投入并降低管理成本。然而,云平台在近年来不断出现大面积宕机的情况,这为云计算测试技术提出了新的挑战。需要测试人员深入理解云平台底层、中间层和上层技术,构建符合云平台质量要求的测试工程能力和质量保障方案。
  很多测试服务提供商已经将测试服务部署到云上,这种方式有很多的优势。首先,它可以按需提供服务,用户可以根据需求灵活的占用云端资源,避免了传统测试中的资源浪费。例如手机应用提供商可以把应用程序通过云平台进行主流手机的兼容性测试,而不必直接购买各品牌的手机。其次,云平台可以提供较为全面的测试环境和测试工具,免去了部署环境和工具的时间,使测试工程师可以将更多的精力投入到业务中。再次,当云平台和容器技术结合起来时,可以快速构建可扩展可伸缩的测试环境,并行执行测试用例,从而减少测试执行时间。
  物联网测试
  IoT 是一个包含大量网络设备、传感器和计算基础设施的庞大系统。IoT 的应用覆盖了军事、家庭、医疗、零售等多个领域。其使用场景复杂,解决方案多元化,使得 IoT 设备以及解决方案的测试面临很大的挑战。下面笔者提出了一些观点和思路供大家参考。
  仿真
  基于效率和成本的考虑,测试人员无法针对所有的 IoT 设备、连接协议以及服务节点进行全面覆盖。依靠 IoT 场景仿真能力,测试人员可以在少量可用的物理设备上创建各类虚拟设备并建立不同协议的虚拟连接,从而模拟出真实应用场景,达到全面测试覆盖的目的。不仅能够节约时间和成本,还具有更好的灵活性和扩展性。
  安全
  当前 IoT 发展的重点是技术的创新、推广和应用,安全问题没有受到足够的重视。相对传统移动互联网,IoT 的规模、应用和服务都更加庞大复杂,安全问题无疑具有极大的挑战性。
  自动化
  在 IoT 领域,目前自动化测试工具和系统的发展还处于比较初级的阶段。在测试执行、场景构建、性能度量及状态监控等各个方面都需要有强有力的工具、框架和规范的出现,来支撑复杂的 IoT 自动化测试。
  开源测试
  开源软件本着“不要重复造轮子”的原则,与商业软件相比,拥有使用成本低、可定制性高等特点。目前开源测试工具种类繁多,涵盖测试管理、缺陷管理、持续集成、功能测试、性能测试、测试框架、测试设计、安全测试等类别。下面列举了这些分类中一些典型的测试工具。而针对我们自身的业务需求,可以通过修改源代码来适配自己的业务,从而实现工具定制化。
  测试管理: TestLink、Testopia
  缺陷管理:Redmine、Bugzilla、Mantis
  持续集成:Jenkins、Buildbot
  功能测试:Selenium、LTP
  性能测试:lmbench、Sysbench、Iperf、Fio
  测试框架:JUnit、Autotest
  测试设计:Xmind、StarUML、UML Designer
  安全测试:Metasploit、Nessus、AppScan
  为了减少研发成本,很多公司都制定了基于开源软件进行二次开发的策略。在重点测试自研特性的同时,面对大量的开源代码,测试工程师需要与开源社区互动,及时将发现的问题提交给社区并同步社区的问题单和 cve 补丁。
  然而,当前很多开源社区中的测试并不到位,很多特性在发布之后长时间没有对应的文档和测试用例。以 kernel 社区的 user namespace 内核特性为例,其是在 2013 年 2 月 18 日随内核 3.8 版本正式发布的,然而直到 2015 年 5 月 21 日,社区才拥有第一个该特性的测试用例。二者时间间隔在两年以上,版本的质量保证令人堪忧。对于这部分特性,需要测试工程师根据业务需要自行补充测试。测试工程师同时还要注意构建社区影响力,以保证与自己平台相关的测试用例能够顺利的被社区接收,从而减少测试代码维护成本。感兴趣的读者可以阅读 《让我们成为开源软件测试者》。
  容器化 /Devops/ 微服务
  容器为开发、测试、运维三个团队提供一致的环境,避免因为环境不统一产生的缺陷误报。同时使开发人员可以很容易的通过容器镜像复现测试人员和客户报来的缺陷。利用容器还可以避免环境污染和批量快速的启动多个测试环境并行测试来提高测试效率。微服务将软件细分为多个子模块,各模块间相对独立,便于测试进行迁移以便及早的发现缺陷。Devops 通过成熟的自动化解决方案,同时配合容器、微服务技术,打通了开发、测试、运维团队的壁垒。随着容器、微服务时代的到来,配置基于 CI/CD 的 Devops 流程成为了测试人员必备的技能。感兴趣的读者可以阅读 《Docker 引领测试革新》。
  敏捷测试
  传统的软件测试方法将开发和测试视作两个团队的两种不同的工作模式,团队之间沟通比较有限,团队壁垒较为明显。在这种开发模式下,软件缺陷通常在项目后期才逐步被发现。近年来,在客户需求频繁变化、高强度的外部竞争压力和软件交付迭代频繁的大环境下,传统的软件测试方式已经不能满足需求。
  敏捷测试强调从客户的角度进行测试,重点关注持续迭代地测试新开发的功能,而不再强调传统测试过程中严格的测试阶段,同时提倡尽早开始测试。它强调开发和测试团队在合作、透明、灵活的环境下协同工作,以测试前移、持续集成、自动化等方式为优化手段,可以很好的适应快速、需求变更频繁的软件交付。
  目前敏捷测试已经受到了行业内的认可,相信会有更多的公司将会进行敏捷转型,敏捷教练的薪水也会水涨船高。
  大数据测试
  当前全球信息数据量增长迅猛,据市场调研机构 IDC 预测,到 2020 年,全球数据总量将达到 40ZB,相当于每人拥有一千张 DVD 光盘以上的信息量。如此大量的数据为测试数据的备份和管理带来了挑战,测试人员需要确认数据完整性,保证数据质量。面对大量而动态变化的数据和有限的测试时间,需要制定出行之有效的测试策略,开发出适用的测试工具,并完善自动化测试。
  随着大数据应用的快速增长,我们需要更快速的完成数据处理。大数据挖掘的目的是找出数据与数据的关联关系,与传统软件相比,很多大数据场景中的输出是无法直接确定的,同时数据又具有多样性,需要测试人员具备更多的发散思维;面对爆炸式的数据服务,测试时需要搭建可扩展伸缩的测试平台模拟大量的测试客户端。而面对大数据中很多场景下程序输出的不确定性、大数据结构多样化、定位数据因果关系困难等问题为测试工程师带来了新的挑战。
  自动化测试
  传统的自动化测试需要测试工程师直接编写测试程序,而这样的程序往往可维护性不强,当开发代码变更时往往需要重新适配自动化测试程序。测试驱动开发是软件工程中的一个里程碑,即开发在提交开发代码修改时同时要提交测试代码,但这种方式仍然需要较多的人力投入到测试代码的编写中。而一些程序可以通过录制或符号执行等方法自动生成自动化代码,免去了手工编写的不便。另外通过埋点、mock 等技术还可以辅助自动化测试。随着测试业务日趋多样化,需要不断开发新的自动化测试框架、测试平台来满足业务需求。当自动化测试与云平台相结合时,可以方便的进行任务迁移、回滚、故障自动修复等功能。
  移动互联网测试
  随着智能移动设备的普及,测试范畴也从智能手机、智能平板扩展延伸至包含了运动手环、车载联网应用、共享单车、无人机等事物。移动平台也呈现多样化趋势,而每个平台的版本升级速度非常快。移动应用种类繁多,从社交到游戏、教育、办公、旅行、工具等类别。为满足用户需求,热门应用的迭代更新非常频繁。面对众多的移动设备硬件型号、多个终端平台版本、繁多的移动应用、各应用的不同版本号,测试人员不得不制定新的测试策略和方案来应对业务。即使应用没有新的特性引入,但自动化测试不得不根据新的平台进行适配工作。而多种组合的测试为测试人员、测试工程能力、自动化测试提出了更高的要求。
  目前已经出现了针对移动测试的自动化设备和 SAAS 平台。测试设备可以模拟出用户真实的终端操作的方式。在 SAAS 平台中,使用者可以将应用提交到平台中进行全量的自动化测试,来确保应用的多个版本可以适配到不同的平台和硬件中。此外,领域中的专项测试,如性能测试、功耗测试、安全测试、兼容性测试、跨地域跨时区测试、老化测试,也将产生很大的测试需求。
  写在最后
  当前很多公司已经将基本的功能测试任务交由开发团队负责,测试人员主要专注于自动化测试开发、安全测试、测试建模、精准测试、性能测试、可靠性测试等专项测试中。这部分测试任务能够很好的体现测试人员的价值。虽然“测试已死”的争论还在继续,但只要把握好软件测试发展的趋势并凭借自身的努力,相信测试人员是能够在行业中受到认可的。
End.

如果对软件测试感兴趣,想了解更多的软件测试知识,请大家关注“51Testing软件测试网”头条号。

相关热门文章

http://www.toutiao.com/i6426594521361940994/

http://www.toutiao.com/i6439201903241855490/

http://www.toutiao.com/i6439580855500276226/

http://www.toutiao.com/i6439919722615013889/
posted @ 2017-08-25 14:23 51testing 阅读(101) | 评论 (0) | 编辑 收藏
 
作为游戏测试需要具备的技能
每个游戏作品都希望呈现出最美的游戏体验,有一种职业在除了游戏设计和策划的工作之外,为玩家的游戏体验保驾护航——游戏测试。
  游戏测试仅仅是玩游戏吗?除了会玩游戏之外,作为游戏测试还需要具备哪些“技能”?
  1、良好的沟通
  相信大家都在网上看到过各种吐槽程序员不解风情的段子,开怀大笑之后深思,作为一个测试工程师又何尝不是如此?貌似沟通技能成为横亘在测试工程师与其他合作部门之间的万丈鸿沟,也成为测试工程师成长的最大瓶颈。下面的这些情况你是不是经常遇到:
  01)“这功能你测了吗?测了为什么还有bug?”
  02)“我特么刚测完,为毛又改需求?”
  03)“xx怎么又偷偷提交东西,提前告诉我测试下行不行?”
  04)”这功能策划案还用写那么详细吗?这是常识懂不懂?“
  。。。。。。
  如此种种,某测试工程师已经哭晕在角落。
  面对这些或明或暗的丛林法则,我们怎样做到适者生存呢?
  一个优秀的测试工程师要解决非常多的非测试工作本身的困难,而沟通则是首要需要解决的。遇到问题需要多沟通,多主动沟通,最忌讳的就是低头猛干,结果花费了很多时间发现干的根本不对,还得从头再来,不仅浪费了自己的时间,也使整个项目的工期发生延期的概率大大增加。
  沟通是双向的,我们不能把问题都归咎于合作部门的需求不明确或者开发人员考虑的不严谨,遇到问题我们也要多反思自己是否沟通到位。笔者曾经遇到过测试人员坐在开发旁边,遇到问题都懒的问一句,只是低头闭门造车的情况。
  遇到问题多问,不要以为你以为的就是你以为的。
  2、责任心
  测试工程师有假期么?不得不悲哀的承认,测试人员没有假期,甚至没有可以深度睡眠的夜晚。。。
  其实在这一小节我只想谈2个字:责任。
  无论多晚,无论是否在陪女朋友吃饭看电影,一个电话,我们都会义无反顾的回到电脑面前解决问题,也许有些人认为我们不正常,也许有些人问我们这么拼为什么,我也不知道,在面临家人和朋友的愧疚感和对工作的责任感面前,我们选择了后者。
  没有什么高大上的理由,没有什么感人至深的故事,没有什么个人英雄主义,只是因为我们选择了,我们就去把它做好,这是我们的责任。
  3、持续的努力
  “30多岁了,有家有孩子了,肾都虚了,你还拼的过年轻人么?” 这是我们一群老测试聚会时经常谈论的话题。是啊,测试工作有时候确实是个体力活,尤其是项目快上线的时候,几天几夜熬着都是家常便,更要命的是现在参加工作的新人都是90后了,看着这群生龙活虎的同事们,不禁各种感慨。
  然而老骥伏枥,志在千里。
  我们依旧在坚持,测试工作本身重复性劳动就比较多,当初选择了这份职业,也就同时选择了坚持。坚持把负责的工作做好,坚持拓展自己的测试深度和广度,坚持学习新的测试技术,坚持把自己的知识和经验传承下去。
  坚持,是我们做好测试工作的基石。
  很多人徘徊在放弃和继续的门口,测试太辛苦了,不过,咬咬牙,就过去了。
  回望路上的血与泪,尽是光荣与梦想的化身。
  4、积极主动
  “这不是我的活,为什么让我干?” 笔者经常听到这样的抱怨。在工作总量不变的情况下,你少干了,自然有人多干,反之亦然。任何个人都很难在互联网行业单独完成一件事,大部分需要团队合作,认清这个事实,我们就得尝试着去理解合作的事情和合作的人,以让我们整个团队都能高效的运转。
  5、对自己有信心
  “这个版本能发么?”
  “放心,没问题。”
  这是我听到的最赏心悦目的乐章,也是测试工程师最霸气侧漏的时刻,在这一刻,我仿佛看到了神的光芒。这就是一个优秀测试工程师的自信。
  这份自信来源于我们一遍又一遍的详细测试,来源于巨大压力下谨小慎微的辛勤付出。
  我们无需做到让每一个人尊重,也无需做到让每一个人理解,每当版本发布时,有这份自信就够了。
  6、淡定的心
  在效率和周全面前,我们有时候面临着两难的选择。有些测试人员一发现问题,就立刻去找开发让开发修改,这种现象不能说不好,只是觉得不够淡定从容。个人认为发现问题后,我们需要多测试几次,确保能够复现并详细的记录下复现步骤,同时尝试拓展思考一下,是否在别的模块存在同样的问题并去验证下。确保这些工作都做完之后,再去把问题跟开发讨论下,可能更合适一些。举一反三,归类处理,我想对整个项目的效率而言是非常有益的。
  7、与时俱进
  对于游戏项目,可能每个项目所应用的技术都不一样,甚至同一项目,随着项目周期的发展,也会不断加入新的技术方案。当然还有各种工作流程上的变革,可能时常会令我们感到烦恼,毕竟改变一个人的习惯时非常难的事情。我们怎样看待和适应这些可能随时发生的变革?首先,我们不应该抗拒,改变旧的习惯确实会令我们感到不适,甚至情绪上的波动,我们需要思考的是我们能阻止这些变革吗?如果不能,我们应该怎样去适应?或者我们有没有更合理的变革方案?以使整个项目变的更好一些。
  无谓的抗拒而不去思考怎样让变革更合理一些在我看来是愚蠢的。其次,我们应该敞开胸怀,与变革一起起舞。变革是永恒的,我们应该学会在变革中去不断的拓展自我,提升自我,从而让我们称为变革的受益者。
posted @ 2017-08-23 16:44 51testing 阅读(107) | 评论 (0) | 编辑 收藏
 
软件功能测试后期如何提升自己?
学习一门编程语言,比如Python、JAVA。掌握一种性能测试工具,比如JMeter、LoadRunner。
光做功能测试是不行的,个人深有体会,现在看大公司的招聘要求,大多是要求有性能测试或自动化测试的经验,因此在目前,我们可以学习一下性能测试或者自动化测试。
我自己目前在学Python3,在接触一些接口自动化方面的测试,测试http接口,我们需要掌握http协议,这里推荐一本书 http权威指南  ,看名字就比较厚,大家可以看看!
此外就是SQL,现在公司招聘,一般初级的要求是“熟练编写SQL语句”,高级点儿的要求就是“掌握一种数据库”,其实我感觉,作为测试人员,我们能熟练编写SQL语句就可以了,尤其是多表连接查询,一定要掌握,跳槽面试时,可能会用到!
我个人感觉,单纯地为了 “学” 而 “学”,作用好像没有那么大,学了半天,工作中不怎么用,过段时间也就忘了,所以我们还是 “着重学习一下工作会用到的知识” !
如果经常测试接口的话,那么我们可以学一下接口自动化测试框架。如果经常用Linux的话,可以学一下常用的命令。经过长期不间断地学习,再跳槽时,我们就可以在简历上写:“熟练使用linux命令、熟悉常用的接口自动化测试框架”关于接口测试,目前我们常见的接口是基于http协议的接口,要做好接口测试,我们需要学习http协议。
End.

如果对软件测试感兴趣,想了解更多的软件测试知识,请大家关注“51Testing软件测试网”头条号。

相关热门文章

http://www.toutiao.com/i6426594521361940994/

http://www.toutiao.com/i6439201903241855490/

http://www.toutiao.com/i6439580855500276226/

http://www.toutiao.com/i6439919722615013889/
posted @ 2017-08-23 16:43 51testing 阅读(128) | 评论 (0) | 编辑 收藏
 
实现数据安全 企业用户最爱这10款加密产品
 10年前,加密就已经是热门企业安全新闻话题,随后加密逐渐成为很多安全套件的关键功能。而现在,面对这么多勒索、欺诈和数据泄露事故,加密敏感数据显得更加至关重要。
  在选择加密产品之前有必要进行研究和产品评估,因为各种产品之间仍然存在很大差异。有些工具在某些环境中很适用,而在其他环境则很差,还可能存在兼容性问题。现在企业都有海量数据要处理,这意味着数据集必须优先考虑作为企业加密管理的部分--在某些情况下,不可能加密所有数据。
  “很多供应商的加密产品正在使用与其他供应商密钥管理器不兼容的专用接口,”Gartner分析师Brian Lowans表示,“加密产品和供应商的多样性让选择过程很困难。”
  在本文中我们将介绍10大企业加密供应商及其产品,这些都是都是经过实践考验的加密产品。主要功能包括终端加密(硬盘驱动器和可移动媒介、电子邮件加密、文件加密、企业内部以及云端)、集中管理、身份验证以及与其他安全工具的集成。
  1. IBM Guardium Data Encryption
  IBM Guardium Data Encryption以最小性能影响执行加密和解密操作,其功能包括集中式密钥和政策管理、合规性准备、对文件和文件夹的细粒度加密,每个数据卷都有自己的加密密钥。
  2. Check Point Full Disk Encryption Software Blade
  Check Point Full Disk Encryption Software Blade对终端硬盘驱动器的所有信息提供自动化安全,这些信息包括用户数据、操作系统文件以及临时和已删除文件。多因素引导身份验证可确保用户身份得以验证。
  3. Eset DESlock
  ESET公司的DESlock具有基于Web的管理控制台,允许跨网络进行多用户管理。其他功能包括远程设备擦除、简化密钥共享以及加密政策设置与执行。集中式管理可控制在世界任何地方的设备。
  4. Dell Encryption Enterprise
  Dell Encryption Enterprise提供基于软件的以数据为中心的加密方式,它可保护多个终端和操作系统所有数据类型。 它还可与现有安全平台及工具整合,让IT能够从单个管理控制台管理多个端点的加密政策。此外,该加密工具可允许IT在系统驱动器或外部介质快速部署加密政策,而不需要最终用户干预。
  5. McAfee Complete Data Protection
  McAfee Complete Data Protection包括数据丢失防护、全磁盘加密、设备控制及云存储保护,其中集中式政策管理由McAfee ePO管理控制台提供,以确保远程访问。
  6. HPE SecureData
  HPE SecureData提供了端到端以数据为中心的方法来保护企业数据,保护静态、动态和使用中的数据。它还可保护现场级的数据,保留格式和上下文,并提供细粒度政策控制。同时,它还可为大数据应用提供安全控制。
  7. Bitdefender GravityZone
  GravityZone全磁盘加密利用Windows(BitLocker)和Mac(FileVault)平台提供的加密功能,加密管理是通过加密保护使用的相同云计算或企业内部控制台来完成。
  8. Sophos SafeGuard
  Sophos加密产品包括BitLocker或FileVault恢复密钥的移动恢复,以及基于终端安全状态授权对加密文件的访问。此外,它们还提供全磁盘加密、对Windows BitLocker和macos FileVault的集中管理、服务到服务密钥恢复、基于角色的访问以及基于应用的加密。
  9. Symantec Encryption
  赛门铁克的集成加密产品系列包括终端、电子邮件和文件加密。终端加密包括完整的磁盘加密、云数据加密、政策执行整合以及对来自苹果ios和Android的消息加密。
  10. Trend Micro Endpoint Encryption
  Trend Micro Endpoint Encryption提供全磁盘加密、文件夹和文件加密以及可移动媒体。单一管理控制台让客户端可管理加密以及其他Trend Micro安全产品。
posted @ 2017-08-22 16:56 51testing 阅读(112) | 评论 (0) | 编辑 收藏
 
开发人员必备的技能——单元测试
说起软件测试四个字,想必大家脑海中浮现的有集成测试、系统测试、黑盒测试、白盒测试等,可能就是没想到会有单元测试。 对于大学是学习软件工程专业出身的同学来说可能会听过这四个字,对工作好几年的职场老鸟可能也听过但是没实际用过居多。绝大多数的开发人员都是忙于把手头的工作开发好,并不会把单元测试纳入工作范畴,他们会说,我连功能开发都忙不过来了,哪有时间去做单元测试,况且还要写测试代码,那不是重复写一篇代码功能吗?但,单元测试真的不值得花时间去做吗,那是因为可能你并不清楚单元测试的投入产出比有多高,下面就简单介绍单元测试到底能给开发人员带来多少好处。
  ●什么是单元测试
  ●为什么要做单元测试
  ●不写单元测试借口
  ●主流框架 JUnit 和 TestNG
  ●Android 中的单元测试
  ●小结
  什么是单元测试
  单元测试本质上也是代码,与普通代码的区别在于它是验证代码正确性的代码。可简单做个定义:单元测试是开发人员编写的、用于检测在特定条件下目标代码正确性的代码。
  软件开发天生就具有复杂性,没人敢打包票说自己写的代码一点问题都没有,或者不经测试就能保证代码正确运行,可能你在这个执行路径下能够执行,殊不知还有其他路径,有一一去验证过吗,因此,要保证程序的正确性就必须要对我们代码进行严格测试。
  举个简单例子:比如有个计算类,里面有个 add 方法,操作就是两个数进行相加。
  public class Calculator {
      public int add(int one, int another) {
          //只是简单的两个数相加
          return one + another;
      }
  }
  常规做法:假如你写好了这个方法,你想进行验证 add 方法的正确性,需要写个使用 add 方法的 main 函数,首先实例化 Calculator 类,然后调用 add 方法并传入两个参数,比如 1 和 2。然后你运行这个工程,看得出结果是否为 3 ,如果是 3 ,则表明我这个方法写的没有错误,可能就不测试了,就继续开发后续的功能,如果不是 3 ,则返回去看看代码中哪里出错了,重新进行调试,甚至有时候肉眼还看不出代码哪里出错,此时就引入断点去查看,在此期间,很大一部分时间就花在断点、调试、运行上。
  单元测试做法:首先会利用 JUnit 测试框架(至于这个框架后面介绍)写一段测试代码,如下:
  public class CalculatorTest {
      public void testAdd() throws Exception {
          Calculator calculator = new Calculator();
          int sum = calculator.add(1, 2);
          Assert.assertEquals(3, sum);
      }
  }
  这里的 CalculatorTest 是 Calculator 对应的测试类,这里的 testAdd 对应着 add 的测试方法,进行测试一般分为三步骤:
  ●setup。一般是 new 出你要测试的那个类,比如: Calculator calculator = new Calculator();
  ●执行操作。一般是调用你要测试的那个方法,获得运行结果: int sum = calculator.add(1, 2);
  ●验证结果。验证得到的结果跟预期中是一样的: Assert.assertEquals(3, sum);
  看到 Assert 这个关键词了吗,这里可以理解为断言或者期望值,根据入参的值,期望有个什么值输出,而不是靠肉眼去验证是不是自己想要的值,是直接通过判断值是否相等性来验证会具有更客观性。
  以上介绍的只是单元测试一点点,那它能给我们带来哪些更多好处呢?
  为什么要做单元测试
  通常我们在做任何工作会先考虑它的回报,编写代码更是如此。如果单元测试的作用不大,没有人会愿意再写一堆无用的代码,那么单元测试到底能够给我们带来什么优点呢?如下:
  ●便于后期重构。单元测试可以为代码的重构提供保障,只要重构代码之后单元测试全部运行通过,那么在很大程度上表示这次重构没有引入新的BUG,当然这是建立在完整、有效的单元测试覆盖率的基础上。
  ●优化设计。编写单元测试将使用户从调用者的角度观察、思考,特别是使用TDD驱动开发的开发方式,会让使用者把程序设计成易于调用和可测试,并且解除软件中的耦合。
  ●文档记录。单元测试就是一种无价的文档,它是展示函数或类如何使用的最佳文档,这份文档是可编译、可运行的、并且它保持最新,永远与代码同步。
  ●具有回归性。自动化的单元测试避免了代码出现回归,编写完成之后,可以随时随地地快速运行测试,而不是将代码部署到设备之后,然后再手动地覆盖各种执行路径,这样的行为效率低下,浪费时间。
  等等,讲了这么多优点,无非就是良好的接口设计、正确性、可回归、可测试、完善的调用文档、高内聚、低耦合,这些优点已经足以让我们对单元测试重视起来了,但是个人觉得还有更重要的原因。
  首先,带来自信。在接手一个新的项目,或者说是参与一个新的项目开发时,往往这种情况是你半途参加进去的,你需要对已有的代码结构进行解读和理解,对于业务的理解,对于代码个中各个模块关系的理解。如果一开始就理财出错,很可能修改后的代码会引起更多的BUG出现,到那时候又需要修复更多的BUG,改了一个地方,很有可能会莫名其妙地影响另外一个地方,这种现象是很常见的。还有一种情况,假设你修改的功能没问题,但是需要去测试验证,在测试的时候就需要考虑这个功能点它原有的测试路径有哪些,又需要一一去验证功能路径,以证明本次修改对于已存在的功能点不造成影响。这其中就存在着很大的时间成本,导致效率不高。那是否存在着这么一种方式,我需要修改我想改动的地方,不需要关心修改完之后它所造成的影响,也不需要关心它的测试回归性,有,此时就是单元测试登场的时候。写单元测试代码,可以让我自己写的代码足够自信,它是经得起考验的。
  其次,更快反馈。对于有一定编程经验的开发人员来说,当他拿到一个新需求的时候,首先想到的不是动手 Coding ,而是会先想想代码的结构,有些类,数据结构该是如何,然后才开始敲代码。如果没有单元测试,一般流程基本是这个模块功能全部写完才开始测试,比如利用 MVP 架构的功能。一般都是开始 Model 模块,然后完善 Presenter 模块,最后写 View 模块,等这几个模块都写完了,再把 APP 跑起来,验证自己写的功能模块是否符合需求,没有符合则继续回去修改代码,这中间需要花费很长的时间才能知道当下自己写的代码是否符合要求,是否正确。那有没有一种即时反馈的方式呢,有,写单元测试即可,当你写完一个函数,马上就匹配一个单元测试函数,这样即写即测的方式可以保证你当场写的代码马上进行修改,测试通过一个,就表示完成一个小的功能点,最后,把函数组装起来,就是我们想要大的功能点。
  最后,节约时间。对于 Android 开发来说,一遍一遍的运行 APP ,然后执行相应的用户操作,看界面是否正确的显示,通过这种方式来测试功能,其实是非常浪费时间,而且效率不高,而用单元测试,可以几乎不用打开 APP 来执行,当然有些需要一些资源文件的是需要 APP 运行条件,绝大部分的功能在单元测试阶段就能验证完毕,那么速度就相对快很多。此外,单元测试还能帮忙减少 BUG ,从而减少调试 BUG 的时间,一些低级犯的错误在单元测试阶段就能避免掉。
  不写单元测试借口
  很多开发人员不写单元测试,最重要的一个原因是他们并不知道单元测试能够带来什么好处,甚至根本不了解单元测试这个词,那自然就像平行线般与之毫无交集。还有一个比较重要的原因是一些开发人员的编程思想还处在一个相对初级的阶段,开发软件只管实现功能,什么高内聚、低耦合、重构、设计、可测试等认为太过专业,对于这些名词以及意义还不了解,这自然不会考虑使用了。还有一些非思想层面的理由,如下:
  ●单元测试太花时间了。软件开发工作那么忙,代码都写不完哪有时间写单元测试。这可能是开发人员用的最多的借口,从某些方面来说,这不能算借口,因为很多开发人员确实在工作上投入的时间特别多。但真的是这样的吗,你有没有想过,导致加班的原因也许就是花了太多时间在手动测试、调试程序上:或许你没有考虑到灵活性与设计,使得在需求发生变更时你需要花很多时间在复杂的代码堆中完成特定的功能,而这些修改又可能引入新的 BUG ,又将导致你需要进行耗时的手动测试、调试等等,如此反复,代码将变得越来越乱,越来越难以维护,最终导致无休止的加班。
  ●测试不是我的工作。测试确实不是开发人员的工作,但单元测试确实是开发人员的工作,测试包含很多种,而只有单元测试是开发人员的工作范畴。开发人员为应用编写代码,那么自然需要保证代码的正确性,而单元测试正是这种保证代码正确性的白盒测试,也就是在了解代码内部结构逻辑的情况下进行有目的的测试,既然说到了解代码,那么开发者自然是最权威的人。因此,编写单元测试并且为测试人员提交正确的代码进行其他测试是开发人员的职责所在。
  ●代码都编译通过了,还测什么。一般来说,这是一个不会放在嘴上但可能藏在心里的借口。代码编译通过只能说你写的代码符合语法要求,并不代表能保证正确性。
  ●代码原来就没有单元测试,并且难以测试。这个问题基本是接受和维护别人开发的代码,而原来的代码本身就没有单元测试了,再加入如果代码的耦合性较高,那么就更难以为这些代码写单元测试。此时正是你了解代码时候,首先为能够测试的部分添加单元测试,保证这些可测试的部分不会被污染,然后在对代码有足够的了解之后再对代码进行重构,降低代码的耦合性,并且慢慢补充测试用例,使得代码的耦合性、可测试性慢慢建立起来。
  主流框架 JUnit 和 TestNG
  JUnit 是一个 Java 语言的单元测试框架,它是 xUnit 单元测试架构体系的一个实例,用于编写和运行可重复的测试。它包括以下特性:
  ●用于测试期望结果的断言(Assertion)
  ●用于共享共同测试数据的测试工具
  ●用于方便的组织和运行测试的测试套件
  ●图形和文本的测试运行器
  TestNG 是一个测试框架,其灵感来自 JUnit 和 NUnit ,但引入了一些新的功能,使其功能更强大,使用更方便。TestNG 消除了大部分的旧框架的限制,使开发人员能够编写更加灵活和强大的测试。 因为它在很大程度上借鉴了Java注解( JDK5.0 引入的)来定义测试,它也可以显示如何使用这个新功能在真实的Java语言生产环境中。
  特点如下:
  ●注解
  ●TestNG 使用 Java 和面向对象的功能
  ●支持综合类测试(例如,默认情况下,不用创建一个新的测试每个测试方法的类的实例)
  ●独立的编译时测试代码和运行时配置/数据信息
  ●灵活的运行时配置
  ●主要介绍“测试组”。当编译测试,只要要求 TestNG 运行所有的“前端”的测试,或“快”,“慢”,“数据库”等
  ●支持依赖测试方法,并行测试,负载测试,局部故障
  ●灵活的插件 API
  ●支持多线程测试
  Android 中的单元测试
  因为 JUnit 测试框架是基于 Java 语言,当然 Android 开发也是基于 Java 语言,所以在 Android 中我们可以用 Junit4 单元测试框架进行回归测试,但同时,Google 也提供了一个 AndroidJUnit4 测试框架,看名字就知道它是基于 JUnit 4 框架适合在 Android 环境中做单元测试。
  那么,AndroidJUnit4 和 Junit4 有什么区别呢?很大一个区别在于:
  1,AndroidJUnit4 测试可以在真机的环境下进行。比如你要测文件读取SD卡,或者操作 SqlLite 数据库,这些条件只有在真机上才有的,此时你用 AndroidJUnit4 框架测试,可以直接跑起来用真实的环境做相应的单元测试。
  2,JUnit4 测试是运行在工程项目中,也就是在编译阶段。此时如果想要模拟 Android 环境,比如我想用 JUnit4 来测试 Activity 类,那么就需要引用第三方库来支持,引用 Mockito 和 Robolectric 框架来模拟 Android 环境进行相应的单元测试。
  所以何时用 AndroidJUnit4 和 JUnit4 不同的框架进行单元测试,就看你待测试的方法前置条件是什么,然后做不同的选择。
  小结
  总的来说,单元测试不是集成测试,单元测试只是测试一个方法单元,不是测试一整个流程。集成测试是一种End To End的系统测试,测试相关模块集成在一起是否能够按照预期工作,一般都是接口或者功能层面的测试,可能会依赖很多系统因素,测试的代码逻辑一般比较复杂,运行时间会比较长,出错之后的修复成本高。单元测试则是开发者在集成测试之前就已经进行自测过,同时呢,进行单元测试之后,对于某个方法的执行路径组合进行了一一验证,它只关注三个目标:
  ●有明确的返回值。比如对某个函数进行单元测试,验证其返回值是否符合预期结果。
  ●这个函数只改变其对象内部的一些属性或者状态,函数本身没有返回值,就验证它所改变的属性和状态。
  ●一些函数没有返回值,也没有直接改变哪个值的状态,这就需要验证其行为,比如点击事件。
posted @ 2017-08-22 16:55 51testing 阅读(97) | 评论 (0) | 编辑 收藏
 
实战丨Python黑魔法之描述符
 引言
  Descriptors(描述符)是Python语言中一个深奥但很重要的一个黑魔法,它被广泛应用于Python语言的内核,熟练掌握描述符将会为Python程序员的工具箱添加一个额外的技巧。本文我将讲述描述符的定义以及一些常见的场景,并且在文末会补充一下__getattr,__getattribute__, __getitem__这三个同样涉及到属性访问的魔术方法。
  描述符的定义
  descr__get__(self, obj, objtype=None) --> value
  descr.__set__(self, obj, value) --> None
  descr.__delete__(self, obj) --> None
  只要一个object attribute(对象属性)定义了上面三个方法中的任意一个,那么这个类就可以被称为描述符类。
  描述符基础
  下面这个例子中我们创建了一个RevealAcess类,并且实现了__get__方法,现在这个类可以被称为一个描述符类。
  class RevealAccess(object):
      def __get__(self, obj, objtype):
          print('self in RevealAccess: {}'.format(self))
          print('self: {}\nobj: {}\nobjtype: {}'.format(self, obj, objtype))
  class MyClass(object):
      x = RevealAccess()
      def test(self):
          print('self in MyClass: {}'.format(self))
  EX1实例属性
  接下来我们来看一下__get__方法的各个参数的含义,在下面这个例子中,self即RevealAccess类的实例x,obj即MyClass类的实例m,objtype顾名思义就是MyClass类自身。从输出语句可以看出,m.x访问描述符x会调用__get__方法。
  >>> m = MyClass()
  >>> m.test()
  self in MyClass: <__main__.MyClass object at 0x7f19d4e42160>
  >>> m.x
  self in RevealAccess: <__main__.RevealAccess object at 0x7f19d4e420f0>
  self: <__main__.RevealAccess object at 0x7f19d4e420f0>
  obj: <__main__.MyClass object at 0x7f19d4e42160>
  objtype: <class '__main__.MyClass'>
  EX2类属性
  如果通过类直接访问属性x,那么obj接直接为None,这还是比较好理解,因为不存在MyClass的实例。
  >>> MyClass.x
  self in RevealAccess: <__main__.RevealAccess object at 0x7f53651070f0>
  self: <__main__.RevealAccess object at 0x7f53651070f0>
  obj: None
  objtype: <class '__main__.MyClass'>
  描述符的原理
  描述符触发
  上面这个例子中,我们分别从实例属性和类属性的角度列举了描述符的用法,下面我们来仔细分析一下内部的原理:
  如果是对实例属性进行访问,实际上调用了基类object的__getattribute__方法,在这个方法中将obj.d转译成了type(obj).__dict__['d'].__get__(obj, type(obj))。
  如果是对类属性进行访问,相当于调用了元类type的__getattribute__方法,它将cls.d转译成cls.__dict__['d'].__get__(None, cls),这里__get__()的obj为的None,因为不存在实例。
  简单讲一下__getattribute__魔术方法,这个方法在我们访问一个对象的属性的时候会被无条件调用,详细的细节比如和__getattr, __getitem__的区别我会在文章的末尾做一个额外的补充,我们暂时并不深究。
  描述符优先级
  首先,描述符分为两种:
  如果一个对象同时定义了__get__()和__set__()方法,则这个描述符被称为data descriptor。
  如果一个对象只定义了__get__()方法,则这个描述符被称为non-data descriptor。
  我们对属性进行访问的时候存在下面四种情况:
  data descriptor
  instance dict
  non-data descriptor
  __getattr__()
  它们的优先级大小是:
  data descriptor > instance dict > non-data descriptor > __getattr__()
  这是什么意思呢?就是说如果实例对象obj中出现了同名的data descriptor->d 和 instance attribute->d,obj.d对属性d进行访问的时候,由于data descriptor具有更高的优先级,Python便会调用type(obj).__dict__['d'].__get__(obj, type(obj))而不是调用obj.__dict__[‘d’]。但是如果描述符是个non-data descriptor,Python则会调用obj.__dict__['d']。
  Property
  每次使用描述符的时候都定义一个描述符类,这样看起来非常繁琐。Python提供了一种简洁的方式用来向属性添加数据描述符。
  property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
  fget、fset和fdel分别是类的getter、setter和deleter方法。我们通过下面的一个示例来说明如何使用Property:
  class Account(object):
      def __init__(self):
          self._acct_num = None
      def get_acct_num(self):
          return self._acct_num
      def set_acct_num(self, value):
          self._acct_num = value
      def del_acct_num(self):
          del self._acct_num
      acct_num = property(get_acct_num, set_acct_num, del_acct_num, '_acct_num property.')
  如果acct是Account的一个实例,acct.acct_num将会调用getter,acct.acct_num = value将调用setter,del acct_num.acct_num将调用deleter。
  >>> acct = Account()
  >>> acct.acct_num = 1000
  >>> acct.acct_num
  1000
  Python也提供了@property装饰器,对于简单的应用场景可以使用它来创建属性。一个属性对象拥有getter,setter和deleter装饰器方法,可以使用它们通过对应的被装饰函数的accessor函数创建属性的拷贝。
  class Account(object):
      def __init__(self):
          self._acct_num = None
      @property
       # the _acct_num property. the decorator creates a read-only property
      def acct_num(self):
          return self._acct_num
      @acct_num.setter
      # the _acct_num property setter makes the property writeable
      def set_acct_num(self, value):
          self._acct_num = value
      @acct_num.deleter
      def del_acct_num(self):
          del self._acct_num
  如果想让属性只读,只需要去掉setter方法。
  在运行时创建描述符
  我们可以在运行时添加property属性:
  class Person(object):
      def addProperty(self, attribute):
          # create local setter and getter with a particular attribute name
          getter = lambda self: self._getProperty(attribute)
          setter = lambda self, value: self._setProperty(attribute, value)
          # construct property attribute and add it to the class
          setattr(self.__class__, attribute, property(fget=getter, \
                                                      fset=setter, \
                                                      doc="Auto-generated method"))
      def _setProperty(self, attribute, value):
          print("Setting: {} = {}".format(attribute, value))
          setattr(self, '_' + attribute, value.title())
      def _getProperty(self, attribute):
          print("Getting: {}".format(attribute))
          return getattr(self, '_' + attribute)
  >>> user = Person()
  >>> user.addProperty('name')
  >>> user.addProperty('phone')
  >>> user.name = 'john smith'
  Setting: name = john smith
  >>> user.phone = '12345'
  Setting: phone = 12345
  >>> user.name
  Getting: name
  'John Smith'
  >>> user.__dict__
  {'_phone': '12345', '_name': 'John Smith'}
  静态方法和类方法
  我们可以使用描述符来模拟Python中的@staticmethod和@classmethod的实现。我们首先来浏览一下下面这张表:
  静态方法
  对于静态方法f。c.f和C.f是等价的,都是直接查询object.__getattribute__(c, ‘f’)或者object.__getattribute__(C, ’f‘)。静态方法一个明显的特征就是没有self变量。
  静态方法有什么用呢?假设有一个处理专门数据的容器类,它提供了一些方法来求平均数,中位数等统计数据方式,这些方法都是要依赖于相应的数据的。但是类中可能还有一些方法,并不依赖这些数据,这个时候我们可以将这些方法声明为静态方法,同时这也可以提高代码的可读性。
  使用非数据描述符来模拟一下静态方法的实现:
  class StaticMethod(object):
      def __init__(self, f):
          self.f = f
      def __get__(self, obj, objtype=None):
          return self.f
  我们来应用一下:
  class MyClass(object):
      @StaticMethod
      def get_x(x):
          return x
  print(MyClass.get_x(100))  # output: 100
  类方法
  Python的@classmethod和@staticmethod的用法有些类似,但是还是有些不同,当某些方法只需要得到类的引用而不关心类中的相应的数据的时候就需要使用classmethod了。
  使用非数据描述符来模拟一下类方法的实现:
  class ClassMethod(object):
      def __init__(self, f):
          self.f = f
      def __get__(self, obj, klass=None):
          if klass is None:
              klass = type(obj)
          def newfunc(*args):
              return self.f(klass, *args)
          return newfunc
  其他的魔术方法
  首次接触Python魔术方法的时候,我也被__get__, __getattribute__, __getattr__, __getitem__之间的区别困扰到了,它们都是和属性访问相关的魔术方法,其中重写__getattr__,__getitem__来构造一个自己的集合类非常的常用,下面我们就通过一些例子来看一下它们的应用。
  __getattr__
  Python默认访问类/实例的某个属性都是通过__getattribute__来调用的,__getattribute__会被无条件调用,没有找到的话就会调用__getattr__。如果我们要定制某个类,通常情况下我们不应该重写__getattribute__,而是应该重写__getattr__,很少看见重写__getattribute__的情况。
  从下面的输出可以看出,当一个属性通过__getattribute__无法找到的时候会调用__getattr__。
  In [1]: class Test(object):
      ...:     def __getattribute__(self, item):
      ...:         print('call __getattribute__')
      ...:         return super(Test, self).__getattribute__(item)
      ...:     def __getattr__(self, item):
      ...:         return 'call __getattr__'
      ...:
  In [2]: Test().a
  call __getattribute__
  Out[2]: 'call __getattr__'
  应用
  对于默认的字典,Python只支持以obj['foo']形式来访问,不支持obj.foo的形式,我们可以通过重写__getattr__让字典也支持obj['foo']的访问形式,这是一个非常经典常用的用法:
  class Storage(dict):
      """     A Storage object is like a dictionary except `obj.foo` can be used     in addition to `obj['foo']`.     """
      def __getattr__(self, key):
          try:
              return self[key]
          except KeyError as k:
              raise AttributeError(k)
      def __setattr__(self, key, value):
          self[key] = value
      def __delattr__(self, key):
          try:
              del self[key]
          except KeyError as k:
              raise AttributeError(k)
      def __repr__(self):
          return '<Storage ' + dict.__repr__(self) + '>'!
  我们来使用一下我们自定义的加强版字典:
  >>> s = Storage(a=1)
  >>> s['a']
  1
  >>> s.a
  1
  >>> s.a = 2
  >>> s['a']
  2
  >>> del s.a
  >>> s.a
  ...
  AttributeError: 'a'
  __getitem__
  getitem用于通过下标[]的形式来获取对象中的元素,下面我们通过重写__getitem__来实现一个自己的list。
  class MyList(object):
      def __init__(self, *args):
          self.numbers = args
      def __getitem__(self, item):
          return self.numbers[item]
  my_list = MyList(1, 2, 3, 4, 6, 5, 3)
  print my_list[2]
  这个实现非常的简陋,不支持slice和step等功能,请读者自行改进,这里我就不重复了。
  应用
  下面是参考requests库中对于__getitem__的一个使用,我们定制了一个忽略属性大小写的字典类。
  程序有些复杂,我稍微解释一下:由于这里比较简单,没有使用描述符的需求,所以使用了@property装饰器来代替,lower_keys的功能是将实例字典中的键全部转换成小写并且存储在字典self._lower_keys中。重写了__getitem__方法,以后我们访问某个属性首先会将键转换为小写的方式,然后并不会直接访问实例字典,而是会访问字典self._lower_keys去查找。赋值/删除操作的时候由于实例字典会进行变更,为了保持self._lower_keys和实例字典同步,首先清除self._lower_keys的内容,以后我们重新查找键的时候再调用__getitem__的时候会重新新建一个self._lower_keys。
  class CaseInsensitiveDict(dict):
      @property
      def lower_keys(self):
          if not hasattr(self, '_lower_keys') or not self._lower_keys:
              self._lower_keys = dict((k.lower(), k) for k in self.keys())
          return self._lower_keys
      def _clear_lower_keys(self):
          if hasattr(self, '_lower_keys'):
              self._lower_keys.clear()
      def __contains__(self, key):
          return key.lower() in self.lower_keys
      def __getitem__(self, key):
          if key in self:
              return dict.__getitem__(self, self.lower_keys[key.lower()])
      def __setitem__(self, key, value):
          dict.__setitem__(self, key, value)
          self._clear_lower_keys()
      def __delitem__(self, key):
          dict.__delitem__(self, key)
          self._lower_keys.clear()
      def get(self, key, default=None):
          if key in self:
              return self[key]
          else:
              return default
  我们来调用一下这个类:
  >>> d = CaseInsensitiveDict()
  >>> d['ziwenxie'] = 'ziwenxie'
  >>> d['ZiWenXie'] = 'ZiWenXie'
  >>> print(d)
  {'ZiWenXie': 'ziwenxie', 'ziwenxie': 'ziwenxie'}
  >>> print(d['ziwenxie'])
  ziwenxie
  # d['ZiWenXie'] => d['ziwenxie']
  >>> print(d['ZiWenXie'])
  ziwenxie
posted @ 2017-08-17 15:34 51testing 阅读(139) | 评论 (0) | 编辑 收藏
 
收藏丨34个最常见的测试面试的问题!
 准备换工作吗?作为一个测试人员,今天赴面试现场,往往会被问到一系列有关敏捷测试的问题。即使是一个开发人员,同样也免不了。现在就帮忙大家做一些准备,这里列出最常见的34个敏捷测试面试的Q&A。
  1. 作为测试人员,面对需求不断变更时应该采取什么措施或方法?
  当需求不断变化时,持续敏捷测试者应该采取以下方法  :
  编写通用测试计划和测试用例,重点在于关注需求的意图,而不是其确切的细节。
  为了了解需求变更的范围,与Product Owners (PO) 或着是业务分析员进行密切合作。
  确保团队明白需求变更所涉及到的风险,特别是在迭代后期阶段。
  如果你要进行功能测试自动化,最好等待,直到功能稳定而且需求不再发生变化。
  通过协商或者实行下一个迭代的更改,可以将需求变化控制在一个很小的幅度。
  (我解决方案更简单: 探索式测试+自动化测试,见:软件测试的一个新公式引起的思考 ,或者是 本迭代新功能的探索式测试 和上一迭代稳定功能的自动化脚本开发 )
  2. 列举出探索式测试(在敏捷中使用)和基于脚本的测试的利弊
  3. 解释极限编程和Scrum的区别
  (探索式测试也可以用在传统开发模式中,只是探索式测试和敏捷开发模式是天生的一对 )
  4. 什么是叙事诗(Epic)、用户故事和任务?
  叙事诗:客户描述的、在Product Backlog中所列举的软件功能被称作为叙事诗。叙事诗被分解为许多用户故事。
  用户故事:用户故事从用户的角度来考虑问题,它定义了项目或业务功能,并按预期在特定的迭代被交付。
  任务:进一步将用户故事划分成不同的任务。
  5. 解释什么是重构?
  为了提高代码的性能和可读性,针对现有的代码进行修改,这就是重构。在重构时,代码的功能不变。
  6. 解释如何用不同的团队能力衡量迭代的速度?
  通常,当计划迭代时,迭代的速度通过基于历史数据的专业判断来进行度量。然而,用于计算迭代速度的数学公式:
  完成故事点x 团队的能力:如果你用每周40小时的百分比来衡量能力
  完成故事点/团队能力:如果你用工时来衡量能力
  对于我们的情况,第二种方法是适用的。
  7. 说一下sprint backlog和product backlog的关键区别?
  Product backlog包含一张全部需要功能的清单并且由PO编写。
  Sprint backlog是开发团队拥有的Product backlog的一部分,并且将这些承诺放在迭代中。它是在迭代计划会议(SprintPlanning Meeting)中所创建的。
  8. 在敏捷中提到的增量和迭代开发有什么不同?
  迭代:迭代方法是一个连续软件开发的过程,软件开发周期重复(迭代&发布,sprint & releases),直到最终的产品实现。
  版本1:迭代1, 2, …, n
  ......
  版本n:迭代1, 2, …, n
  增量:增量开发将系统功能划分成若干个开发或部分。在每个增量开发中,从需求到部署之间的环节,由不同部门负责不同部分的功能,能够合并在一起运行。
  (大家觉得这里解释正确吗?解释清楚吗? 今天看来,迭代开发和增量开发已难以区分,你中有我,我中有你。 每个版本就是一个迭代的交付物,而不是版本1:迭代1, 2, …, n   )
  9. 解释敏捷中的spike和第0个迭代(Zero Sprint),其目的是什么?
  迭代0:在开始第一次迭代之前,它被引入来做一些研究。通常这个迭代在项目启动时,用于开发环境的设置、准备Product backlog等。
  Spikes:Spikes被用来表示研究、探索、设计甚至原型等活动的原型(简陋而快速的实现)。在迭代之间,可以采取spikes来应对与工作相关的任何技术或者设计问题。Spikes分为技术Spikes和功能Spikes两种类型。
  (迭代0 更多的工作就是需求分析/定义:形成Product backlog,架构设计、数据库设计等   )
  10. 什么是TDD?
  TDD,测试驱动开发,也被称作为测试驱动设计。在“测试驱动开发”这种实践中,开发者首先编写一个描述新功能或者改进的自动化测试用例(测试脚本/测试代码),然后编写一些零碎的代码来运行该测试,然后重新确定新代码以满足可接受的标准。
  (注意区分TDD、ATDD)
  11. 原型和线框图(wireframes)被广泛用于什么的一部分?
  原型和线框图都是原型,被广泛用作经验设计的一部分。
  12. 解释什么是应用二进制接口?
  在不同的系统平台和环境中,以二进制形式定义应用程序可移植性要求的API规范称为应用程序二进制接口。
  13. 解释敏捷中的燃尽图,包括burn-up chart 和 burn-down chart?
  为了跟踪项目进度的开始和结束,使用这些图表。
  burn-up chart(燃起图):它显示了随着时间的推移,故事开发的进展状态。
  burn-down chart(燃尽图):显示还有多少工作要做。
  14. 解释什么是Scrum ban?
  Scrum ban是一个基于Scrum和看板的软件开发模式。它专门为需要频繁维护的项目而设计,经常会遭遇预料不到的用户故事和程序错误。使用这些方法,团队的工作流程将以每个用户故事或编程错误的最小完成时间为导向。
  15. 什么是故事点/投入/标度(points/efforts/ scales)?
  它用来讨论没有分配时间的故事的难度。最常见的标度是斐波那契序列(1, 2, 3, 5, 8,13,...,100),不过有些团队使用线性标度(1, 2, 3, 4 ...),2的次方(1, 2, 4, 8 ......)和衣服尺寸标度(XS,S,M,L,XL)
  16. 解释什么是曳光弹(Tracer Bullet)?
  曳光弹是当前架构的Spikes,是当前最好的一套实践,是当前生产质量代码的技术集合。它不是一段扔掉的代码,但可能仅仅是一个粗糙的功能实现.
  (Tracer Bullet 出自 The Pragmatic Programmer: From Journeyman to Master.程序员修炼之道:从小工到专家 )
  17. 什么是测试Stub?
  测试Stub是一个少量代码的模块,它可以替代被测系统中未开发或完全开发的组件。测试Stub被设计成通过产生特定的已知的输出并且替代实际的组件这样一种方式。
  (待续)
posted @ 2017-08-17 15:31 51testing 阅读(178) | 评论 (0) | 编辑 收藏
 
程序员都很有钱吗?他们为什么不炫富

看到这个话题,真的不知怎么回答,首先说程序员有钱吗?答:有钱,确实工资很高,而且可能花销也没那么多,因为身边的程序员朋友们不是在加班就是在加班的路上,加班是再正常不过的一件事,但是这句话可能说的也比较片面,如果是那些大佬们可能就不需要加班太多了吧!

看一个老段子,还是笑成了傻狗,哈哈哈

看看网友们都怎么说吧

北上广深一年插不上能买一个厕所了吧

还是穿裤衩+拖鞋+T恤,做电脑前撸代码最舒服

再说,也他妈不是很有钱

所以最后一个才是最想说的,

这句话还是很多人赞同的,我绝对相信

这个才是正确的炫耀的方式吧

不要瞎说大实话

是的,绝大部分程序员过得肯定比你想象中的好,而且越来越好

总之一句话,程序员是一个群体,其他工作的人也是一个群体,其实也不需要有太多的差异来看待这件事,同样是出来工作,赚钱,为什么要把人们区别开来呢?你不是程序员,不一定赚的少,炫富不炫富有什么关系,跟什么职业有什么关系,还是要地调做人,高调做事的嘛!

欢迎评论,欢迎搞事,看看朋友们都什么样的想法?

posted @ 2017-08-15 16:37 51testing 阅读(106) | 评论 (0) | 编辑 收藏
 
仅列出标题
共55页: First 24 25 26 27 28 29 30 31 32 Last