iOS开发中的测试框架
转载作者:@crespoxiao
我们为什么要用测试框架呢?当然对项目开发有帮助了,但是业内现状是经常赶进度,所以TDD还是算了吧,BDD就测测数据存取和重要环节,这很重要,一次性跑完测试单元检查接口或模块的可用性,这比打断点调试强多了吧,至于UI测试就算了吧(xcode7集成了),呵呵。
首先了解一下BDD与TDD的概念:
BDD(Behavior Driven Development),也就是行为驱动开发,它旨在解决具体问题,帮助开发人员确定应该测试些什么。
TDD(Test-Driven Development),就是测试驱动开发,通过测试来推动整个开发的进行。
github上搜TDD或BDD,语言选择objective-c,star最多的就是这2个:
https://github.com/kiwi-bdd/Kiwi/wiki
https://github.com/specta/specta
还有一个测试框架用的比较少,叫Cedar https://github.com/pivotal/cedar
此外,还找到2个Swift的测试框架,以后用Swift开发可以考虑使用:
https://github.com/railsware/Sleipnir
https://github.com/Quick/Quick
Cedar,Specta和Kiwi这3个框架就是目前Objc最流行的BDD测试框架了,其中Kiwi最受欢迎(根据github上的star数来推断,行为描述和期望写起来也比较易懂,至少我是这么认为的)。
不 过,Specta是 RAC 那帮人维护的,用于测试的黑魔法更多,我担心这帮人精力太分散顾及不上这个测试框架。但是有些使用测试框架经验丰富的人选择用回了XCTest,主要是因 为它跟Xcode集成的比较好,而且嫌BDD框架hold不住业务的发展,cmd+u可以一次性跑完所有的测试(试过3个框架目前都可以这样的)。
XCTest 与Xcode深度集成,而且可以享受Apple后续对XCTest升级的福利。XCTest 的优势和缺点都是由于它太简单了。你只需要创建一个类,使用 “test” 作为测试方法名的前缀,只需要这样就可以了,不需要再做其他的。不幸的是,这已经是 XCTest 的全部优点了。BDD 框架的附加功能的重要性是取决于项目的大小。我的结论是,XCTest 对中小型的工程来说是一个很好的选择,但是对于更大型的工程,就有必要参考一下像 Kiwi 或者 Specta 这样的 BDD 框架。Specta和Kiwi的区别就是Kiwi包含了Specta和OCmock以及Expeata所有的功能。换句话说Specta就是没有mock 和验证功能Kiwi。经测试,Kiwi与Specta是不能同时在项目中使用的,会Crash,不信你试试,不过各自可以与XCTest混合使用因为它们 是基于XCTest封装的。
Cedar,Kiwi,以及 Specta 提供类似语法,我不能说其中一个框架要比其他所有都好,它们各有利弊,选择 BDD 框架归根结底来自个人偏好。我选择Kiwi是因为只需要在podfile导入一个Kiwi就行了,Specta则需要依赖别的第三方库,虽然灵活,但灵活 有灵活的坏处,当然也有好处,你喜欢就好,反正用得不爽别怨我。
如果使用Specta,还要引入OCmock/OCMockito以及Expeata/OCHamcrest一起配合使用。
OCMock Or OCMockito
这两个都是用来mock对象,Stub方法的,他们之间的区别在于使用OCMock的库比OCMockito的库多,而且文档和教程更加丰富。
Expecta Or OCHamcrest
这两个都是断言的扩展框架,Expecta不成熟,框架还有一些的问题。OCHamcrest更加成熟,而且可扩展性高,可以自定义自己的断言,更灵活。
BDD的理念是你不是在写代码,而是在讲故事。而整个故事是由Given…When…Then组成。我们可以来看看BDD框架Kiwi的一段测试代码:
describe(@"Team", ^{
context(@"when newly created", ^{
it(@"has a name", ^{
id team = [Team team]; [[team.name should] equal:@"Black Hawks"];
});
it(@"has 11 players", ^{
id team = [Team team]; [[[team should] have:] players];
});
});
});
这个测试用例就是在说Given a Team,When newly created,it should have a name, and should have 11 players,基本上不需要注释就能知道在干嘛。
参考:http://onevcat.com/2014/05/kiwi-mock-stub-test/
不同类型的模拟对象的基本定义:
double 可以理解为置换,它是所有模拟测试对象的统称,我们也可以称它为替身。一般来说,当你创建任意一种测试置换对象时,它将被用来替代某个指定类的对象。
stub 可以理解为测试桩,它能实现当特定的方法被调用时,返回一个指定的模拟值。如果你的测试用例需要一个伴生对象来提供一些数据,可以使用 stub 来取代数据源,在测试设置时可以指定返回每次一致的模拟数据。
spy 可以理解为侦查,它负责汇报情况,持续追踪什么方法被调用了,以及调用过程中传递了哪些参数。你能用它来实现测试断言,比如一个特定的方法是否被调用或者是否使用正确的参数调用。当你需要测试两个对象间的某些协议或者关系时会非常有用。
mock 与 spy 类似,但在使用上有些许不同。spy 追踪所有的方法调用,并在事后让你写断言,而 mock 通常需要你事先设定期望。你告诉它你期望发生什么,然后执行测试代码并验证最后的结果与事先定义的期望是否一致。
fake 是一个具备完整功能实现和行为的对象,行为上来说它和这个类型的真实对象上一样,但不同于它所模拟的类,它使测试变得更加容易。一个典型的例子是使用内存中的数据库来生成一个数据持久化对象,而不是去访问一个真正的生产环境的数据库。
实践中,这些术语常常用起来不同于它们的定义,甚至可以互换。它们自认为自己是 "mock 对象框架",但是其实它们也提供 stub 的功能,不要太过于陷入这些词汇的细节。
下面讲讲Kiwi的使用,尽量简单,以便快速上手,当然详情还是得看官方文档,链接奉上:
https://github.com/kiwi-bdd/Kiwi/wiki
http://onevcat.com/2014/02/ios-test-with-kiwi/
1.Kiwi的安装
podfile中写入
target 'OneTravelTests', :exclusive => true do
pod 'Kiwi'
end
然后pod install或pod update就可以了。
可以安装一个xcode插件http://alcatraz.io,里面有Kiwi的template,安装一下,然后就可以使用Kiwi了。然而有人说插件用不了,怪我咯?懒得解释了,看这里吧:
https://github.com/cikelengfeng/RPAXU
2.Kiwi的基本语法解释
上3张图,一切尽在不言中。
kiwi基本语法解释
mock与stub解释
测试数据请求
3.我们应该/不应该测试什么
BDD 的第一个单词就表明了这一点,你不应该关注于测试,而是应该关注行为。这个看似毫无意义的变化提供了应该测试什么的准确答案:你应该测试行为。
例如你设计的一个对象,它有一个接口定义了其方法和依赖关系。这些方法和依赖,声明了你对象的约定,它们定义了如何与应用的其他部分交互,以及它的功能是什么。它们定义了对象的行为。同时这也应该是你的目标:测试你对象的行为方式。
不应该测试什么呢?
不要测试私有方法:私有方法意味着私有,如果你感到有必要测试一个私有方法,那么那个私有方法一定含有概念性错误,通常是作为私有方法,它做的太多了, 从而违背了单一职责原则。
不要 Stub 私有方法:Stub 私有方法和测试私有方法具有相同的危害,更重要的是,Stub 私有方法将会使程序难以调试。通常来说,用于Stub的库会依赖于一些不寻常的技巧来完成工作,这使得发现一个测试为什么会失败变的困难。
不要测试构造函数:构造函数定义的是实现细节,你不应该测试构造函数,这是因为我们认同测试应该与实现细节解耦这一观点。
不要 Stub 外部库:第三方代码不应该在你的测试中直接出现。
4.测试的目的
使重构更简单 —— 你可以自信的修改实现细节,而不用去触及公有 API。
避免代码恶化—— 恶化在什么时候发生?在你修改代码的时候。
提供了可执行的说明和文档 —— 你在什么时候更想知道软件实际上是如何工作的?在你想修改它们的时候。
减少了创建软件的时间 —— 怎么减少时间的?是通过更快速地修改你的代码,出错时测试会自信地告诉你哪里出错了。
降低了创建软件的代价 —— 时间就是金钱,朋友。
测试应该:
很快速(Fast) —— 测试应该能够被经常执行。
能隔离(Isolated) —— 测试本身不能依赖于外部因素或者其他测试的结果。
可重复(Repeatable) —— 每次运行测试都应该产生相同的结果。
带自检(Self-verifying) —— 测试应该包括断言,不需要人为干预。
够及时(Timely) —— 测试应该和生产代码一同书写。
5.UI测试
关于UI测试,需要测试的是用户的交互,而不是应用的外观,Xcode7中新增了UI Testing,具体可以看wwdc 2015 session :406_hd_ui_testing_in_xcode。
好了,没了,我有严重的拖延症,哎。
更多请参考:http://www.objc.io
iOS开发中的测试框架的更多相关文章
- iOS开发中的测试框架 (转载)
作者:CrespoXiao授权 地址:http://www.jianshu.com/p/7e3f197504c1 我们为什么要用测试框架呢?当然对项目开发有帮助了,但是业内现状是经常赶进度,所以T ...
- 简述 Ruby 与 DSL 在 iOS 开发中的运用
阅读本文不需要预先掌握 Ruby 与 DSL 相关的知识 何为 DSL DSL(Domain Specific Language) 翻译成中文就是:"领域特定语言".首先,从定义就 ...
- 白话 Ruby 与 DSL 以及在 iOS 开发中的运用
每日一篇优秀博文 2017年10月7日 周六 白话 Ruby 与 DSL 以及在 iOS 开发中的运用 阅读本文不需要预先掌握 Ruby 与 DSL 相关的知识 何为 DSL DSL(Domain S ...
- iOS开发中静态库之".framework静态库"的制作及使用篇
iOS开发中静态库之".framework静态库"的制作及使用篇 .framework静态库支持OC和swift .a静态库如何制作可参照上一篇: iOS开发中静态库之" ...
- iOS开发中打电话发短信等功能的实现
在APP开发中,可能会涉及到打电话.发短信.发邮件等功能.比如说,通常一个产品的"关于"页面,会有开发者的联系方式,理想情况下,当用户点击该电话号码时,能够自动的帮用户拨出去,就涉 ...
- iOS开发之常用第三方框架(下载地址,使用方法,总结)
iOS开发之常用第三方框架(下载地址,使用方法,总结) 说句实话,自学了这么久iOS,如果说我不知道的但是又基本上都摸遍了iOS相关知识,但是每次做项目的时候,遇到难一点的地方或者没试过的东西就闷了. ...
- iOS开发-常用第三方开源框架介绍
iOS开发-常用第三方开源框架介绍 图像: 1.图片浏览控件MWPhotoBrowser 实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网 ...
- iOS开发中的单元测试(三)——URLManager中的测试用例解析
本文转载至 http://www.cocoachina.com/cms/plus/view.php?aid=8088 此前,我们在<iOS开发中的单元测试(一)&(二)>中介绍 ...
- iOS开发中静态库制作 之.a静态库制作及使用篇
iOS开发中静态库之".a静态库"的制作及使用篇 一.库的简介 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的类型? 根据源代码的公开情况,库可以分为2种类 ...
随机推荐
- 转:整理一下Entity Framework的查询
Entity Framework是个好东西,虽然没有Hibernate功能强大,但使用更简便.今天整理一下常见SQL如何用EF来表达,Func形式和Linq形式都会列出来(本人更喜欢Func形式). ...
- 抛出自定义异常,spring AOP事务不回滚的解决方案
spring AOP 默认对RuntimeException()异常或是其子类进行事务回滚,也就是说 事务回滚:throw new RuntimeException("xxxxxxxxxxx ...
- Write operations are not allowed in read-only mode错误
(转+作者个人理解) 最近在配置 Structs, Spring 和Hibernate整合的问题: 开启OpenSessionInViewFilter来阻止延迟加载的错误的时候抛出了这个异常: org ...
- 关于jsp利用EL和struts2标签来遍历ValueStack的东东 ------> List<Map<K,V>> 以及 Map<K,<List<xxx>>> 的结构遍历
//第一种结构Map<K,<List<xxx>>> <body> <% //显示map<String,List<Object>& ...
- aspose输出表格
利用aspose在word中输出表格 序号 姓名 性别 <<TableStart:T>><<Index>> <<Name>> ...
- Android手机部分名词浅谈
1.什么是Radio? Radio是无线通信模块的驱动程序,ROM是系统程序,radio负责网络通信,ROM和Radio可以分开刷,互不影响.如果您的手机刷新了ROM后有通讯方面的问题可以刷新radi ...
- ssh-keygen的用法
一.概述 1.就是为了让两个linux机器之间使用ssh不需要用户名和密码.采用了数字签名RSA或者DSA来完成这个操作 2.模型分析 假设 A (192.168.20.59)为客户机器,B(192. ...
- 【转】Ubuntu搭建Eclipse+JDK+SDK的Android
原文网址:http://blog.csdn.net/ithomer/article/details/6960989 今晚重装Ubuntu系统,重新安装了一套eclipse+jdk+SDK的Androi ...
- vs2012 Silverlight项目签名报错异常的处理方式
项目刚生成为vs2012,原先的Silverlight项目,点击签名,竟然有问题,给上个截图 悲剧了,没有签名证书,就无法实现自动更新,想着vs2012可能几个更新没有安装吧,但是自己手动下载竟然一两 ...
- 高新服务平台在SUSE系统上重新部署笔录
安装步骤 ./shutdown.sh 停止tomcat (1) 删除 zjgx 目录下 除bbs 和Demos所有目录和文件 (2)上传zjgx0519.zip 到zjgx目录下 (3)unz ...