方式二:
// 获取实例变量的Ivar值
Ivar class_getClassVariable(Class cls, const char *name)
// 获取对象实例变量的值
id object_getIvar ( id obj, Ivar ivar );
// 修改对象实例变量的值
void object_setIvar ( id obj, Ivar ivar, id value );
b、私有方法的访问和修改
对私有方法的访问同样有两种方法:
3、mock的使用
对于一些不容易构造或不容易获取的对象,可以创建一个虚拟的对象(mock object)来完成测试。实现思想就是根据要mock的对象的class来创建一个对应的对象,并且设置好该对象的属性和调用预定方法后的动作(例如返回一个值,执行其他方法,设置参数中的返回值和返回异常等等),然后将其记录到一个数组中,接下来开发者主动调用该方法,最后做一个verify(验证),从而判断该方法是否被调用,或者调用过程中是否抛出异常等。
在iOS手机管家的逻辑接口测试中选用通用的开源OCMock,配置和OCMock的使用参看如下连接文档:http://ocmock.org/
a、mock返回一个值;
举例:在iOS手机管家的加密相册功能中,手机硬件是否支持3Dtouch会影响其登录流程。如下使用了OCMock来mock isTouchIDSupported 接口,使得其返回设定值YES。
Ps:如下中,通过调用stopMocking可以返回真实的状态,如果在测试结束前需要保存一个实际情况的数据这个方法是比较合适使用的。StopMocking后mock的方法就不能再继续使用了。
b、mock执行其他方法;
举例:如下的mock对象调用isTouchIDSupported方法时,将会调用checkbox对象的isChecked方法。本例中,在mock之前已经将checkbox的isChecked属性值设置为YES,所以调用[checkbox isChecked]返回的值是YES。注:mock执行其他方法需要保证返回值与mock对象调用方法的返回值类型一致。
OCMStub([classMock isTouchIDSupported]).andCall(checkbox,@selector(isChecked));
c、mock设置参数中的返回值;
对于函数返回值放在参数中的情况,即参数传递的是一个指针的指针,直接不执行mock函数,而是将返回值直接设置给返回值参数。举例如下:
d、mock一个异常返回。
在单元测试中,也常常需要mock一个异常返回,从而去保证异常路径得到覆盖。如下为一个简单示例:
4、模拟后台数据返回
对于黑盒测试,如果要后台返回特定的数据需要配单,且还难以模拟一些后台。
返回异常数据情况。有了单元测试后,我们可以在不配单情况下指定后台返回数据,检查客户端对于后台的正常和异常返回处理是否得当。在集成测试前,做验证模块内部的逻辑正确性,避免在联调时花费过多的时间来解决小问题,提高联调的效率。
举例:iOS手机管家问问中一次更新拉取,如果后台有超过20篇以上的文章,那么仅返回前20条。黑盒测试方案,我们必须在后台配置至少20篇以上文章。在接口自动化测试中,先模拟后台有超过20篇文章,检查是否有做好仅显示前20篇文章客户端逻辑。
在做接口测试时,常会碰到返回值为viod的方法,并不总是构造输入参数,得到返回值。对于没有返回值的方法,一定有一些可以被观测的地方,比如说一个对象的状态被改变,所以必须找到合适的断点。如果找不到,说明这个方法无用,不需要做测试。
举例:iOS手机管家的游戏中心的icon图标下载,没有返回值,但在本地有存入图标文件,那么就可以在测试用例中check这个文件是否存在,继而判断是否成功下载。
- (void)downloadIconForUrl:(NSString *)url { ... }
四、小结
在实际工作中尝试逻辑自动化测试在帮助被测产品发现问题的时候,也能提高测试人员自身的代码能力,一举两得。
协助产品提升质量主要在于:
1、输出自动化用例,让代码重构和优化更放心;
2、在集成测试前,有机会做验证模块内部的逻辑正确性,避免在联调时花费过多的时间来解决小问题,提高联调的效率;
3、其他产出为:产品bug,code review问题,测试分析框架图,根因分析,可测性分析等。
提升测试人员自身代码能力主要在于:
1、掌握代码,积累代码编写和调试经验,分析问题与解决问题的经验;
2、辅助问题分析,遇到问题时,可以借助分析单元测试代码来了解模块的一般行为。