军规十九 进行自动化和探索性测试
在测试设计时最主要依据的就是测试金字塔的测试结构。如果在项目临近发布才开始测试并发现缺陷,这样修复缺陷的成本就会很高,项目的进度也会很不确定。所以,就开发阶段来说,如果把测试分层,在不同的开发阶段都进行测试,能很大程度上缓解这些问题。
测试分层的优势有以下几点:
1,测试的成本
单元测试的开发成本要远低于用户界面测试,如果在用户界面的测试中发现缺陷,修复缺陷的成本也是远高于通过单元测试和组件测试的成本。
这里的成本不单纯是开发人员修复缺陷所需要的资源和时间,还包括缺陷修复后测试人员进行回归测试所需要的资源和时间,以及项目延期等其他项目成本。
2,测试的效率
单元测试能很快地验证很小的功能或者方法,且运行时间短,反馈更为及时。
3,缺陷定位的难易
单元测试失败后,测试人员能够很容易知道是被测试的特定功能或者方法不正确;而如果是用户界面的缺陷,测试人员就需要花费更多的时间来进行排查,确定出现问题的功能模块,最后再进一步发现需要修复的功能和方法。
4,反映真实的业务需求
单元测试无法从全局观的角度了解系统模块之间的交互,也无法通过方法的组合帮助用户完成业务目的;而由于用户界面的测试描述的是从用户角度出发的用户使用场景,因此可以更容易地阐述用户的行为和业务需求。
5,更加接近业务
用户界面测试描述测试的层级更高,所以更接近业务;单元测试描述测试的层级更具体,所以更接近于实现。
从测试金字塔分层来看,不同层级的测试都很有必要,而我们也需要根据不同测试所处的层级及其特点来设计测试。
另外,实际测试设计时采用的测试金字塔具有更多更细节的分层。高层级的测试和低级别的测试相比,抽象程度更高,测试运行的时间更长,与更多的系统和模块有交互。反馈的周期更长,接近缺陷的成本也更高。
单元和组件测试的测试驱动开发TDD的基本循环步骤是:
1,测试失败;
2,测试通过;
3,重构;
由于测试驱动开发是针对单元和组件测试所使用的开发技术,所以在进行单元和组件测试时,测试人员只需要了解并评审开发人员在单元和组件测试中覆盖了哪些场景,并不需要完成其实现。
在单元测试和组件测试之上的是Mobile Service的API测试,这一类测试通常需要自动化实现,且通常需要开发人员和测试人员一起讨论并实施,因为开发人员更了解Mobile Service的API细节,而测试人员能够更好地从用户角度拍定API的优先级和重要程度,从而优化API测试的投入产出比。
测试金字塔中自动化部分的最高层级是用户界面的自动化测试,它需要准备的测试环境和测试数据更加复杂,运行时间更长。在编写用户界面的自动化测试时,编写的原则是尽可能编写用户旅程级别的测试用例,而不是针对某一特定的小功能和模块进行测试,而是重点测试的是正向测试路径(Happy Path);对于反向测试路径(Sad Path),尽可能使用低层级的测试来进行覆盖。
用户旅程是一个用户体验设计的术语,指的是为达到某种特定目的,用户所执行的一系列操作的集合。
可以帮助实现App上用户界面的自动化测试的常见工具有Appium,Calabash,Frank,MonkeyTalk,iOS UIAutomation,Robotium,Android UIAutomator,iOS-driver,KeepItFunctional,Selendroid,Zucchini等。
在测试金字塔的最高层级,是对于App的“探索性测试”(Exploratory Testing)。
1,探索性测试是针对于脚本测试提出的,但是两者并不是针锋相对的,而是相辅相成的。探索性测试,脚本测试和自动化测试之间可以相互转化,相辅相成。
2,探索性测试要求测试人员在执行测试时,如同用户旅程一样,首先设定好测试目标,然后规划出一段时间,使用启发式测试策略模型(Heuristic Test Strategy Model,HTSM),通过测试人员的创造性思维,采取不同的测试路径,来达到测试目标的测试方法。
启发性测试策略模型的主要内容是:测试人员使用质量标准,项目环境,产品元素,指导测试技术的选择与应用,并产生观察到的质量。
3,在探索性测试执行中,为了提高探索性测试的效率,并且能够重现所发现的问题,可以采用基于测程的测试管理(Session-Based Test Management,SBTM)。在App测试中也可以使用SBTM技巧进行探索性测试。
4,针对App的探索性测试,测试人员需要测试在低层级测试中不能覆盖的对于页面跳转和不同页面间数据流动和展示等需要涉及到多个页面的流程操作。
5,当进行App的探索性测试时,选择在真实设备上运行可以提高测试的真实性和加深对于用户使用场景的理解,从而不断促进探索性测试的发展和深入。
军规二十 进行性能和安全性测试
如何让用户感觉App运行速度更快呢,这需要对App进行性能测试。限制App性能的因素按照App的系统结构分为App自身和App需要用到的后台服务。
1,测试App连接网络的速度
一般采用在模拟Mock环境下进行测试,测试方法更多使用的是在App的log中添加时间戳的方式计算时间,例如使用Apple公司提供的iPhone Configuration Utility中Devices的Console查看App的log。
2,测试App在不同网络速度下操作的流程程度
测试可以使用在App的log中添加时间戳方法验证,也可以通过使用App的直观感受来验证App性能带给用户的体验。
3,测试App对于前台页面渲染的性能
测试可以使用在App的log中添加时间戳方法验证,也可以通过使用App的直观感受来验证App性能带给用户的体验。特殊的是,当App中使用WebView,测试人员可以快速地刷新当前页面或者在使用WebView的页面间进行切换,来验证App是否有性能问题甚至发生崩溃。
4,测试App操作数据库的性能
iOS操作系统在设备本地存储App数据时使用的是CoreData或者SQLite数据库;Android操作系统在设备本地存储App数据时使用SQLite数据库。如果操作的数据量很大,便有可能出现App的性能问题,因此需要对数据库操作的功能进行大数据量的测试。测试人员也可以和开发人员一起,遵照Web端数据库优化的一些原则,如数据库启用事务,使用索引,数据的批量操作等优化方法,提高数据库的性能。
5,测试App用到的后台服务Mobile Service的性能
举例一些测试人员可以用来测试Web性能的测试工具,如Apache Jmeter,Gatling,LoadRunner,LoadUI和NewRelic等。
6,测试App是否保存了临时数据或者已删除的数据
可以通过文件管理App等第三方App来查看App是否保存了不该保存的文件,如cookie文件。
7,测试App的会话session是否有过期设置
对于App的会话session是否有过期设置的测试,可以在App运行中切换到别的App或者桌面一段时间,然后再次进入App,看App是否需要输入密码等验证信息。值得注意的是不同App的合理session过期时间不一样,测试人员需要和产品经理、开发人员等确认之后制定出合理的测试用例。
8,测试App请求中是否包含了明文的用户信息
包含了明文的信息,如同App中标示用户应该使用UUID或GUID等转码后的信息,而不是直接的用户电话号码或账户信息,当然更不应该明文传送这些信息。测试人员可以使用Apple的iPhone Configuration Utility,Android SDK自带的DDMS,Charles和Fiddler这些工具来监控App发送的请求。
9,测试App的请求是否加密
一般App请求可以使用HTTP,但是关系到用户敏感信息的请求,需要使用HTTPS等加密传输。
10,测试SQLite数据库的存储是否安全
测试人员可以通过ADB连接到root的Android蛇别,并使用SQLite来查看具体的数据库保存的信息。显然,把用户实际的登录信息明文存储在数据库文件中是不安全的,最好不要存储,如果必须存储,最好对这些信息加密后再存储。
11,测试App使用WebView的安全性
由于WebView的请求和在Web端请求数据是一样的,所以任何适用于Web端的攻击方式和漏洞对于WebView来说都是通用的。
12,测试App的后台服务Mobile Service
测试人员可以采用与Web安全性测试通用的一些工具,如Zed Attack Proxy(ZAP),Burp Suite,Websecurify,Wapiti和WebScarab等。
军规二十一 使用log定位问题
测试人员发现一个App缺陷时,通常会需要log文件来定位缺陷问题,尤其是在难以复现缺陷的时候。使用log收集工具可以在测试中记录和报告缺陷,给测试人员带来很多便利。常用的获取App崩溃log的工具有Crashlytics,Splunk MINT Express(之前称之为Bugsense),TestFlight和HockeyApp。
军规二十二 充分使用持续集成和持续部署
一方面为了解决App的稳定性问题,防止修复缺陷时引入新的缺陷,一方面为了让测试人员不再怀疑自动化测试的覆盖,我们可以把在模拟器上运行的App各级自动化测试加入持续集成(Continuous Lntegration,CI)的流程中。
持续部署比持续集成更进一步,不仅覆盖了App的开发阶段,还包括App的自动部署。这里的自动部署,不止包括App在测试环境中的自动部署,还包括了App部署到生产环境;不仅需要部署App本事,还需要对App依赖的各种后台服务和系统进行测试环境以及生产环境的部署。另外,持续部署还包括了生产环境中的监控和分析,以及对App的反馈及改进整个流程。