iOS逻辑自动化测试实践

一、怎么界定自动化测试范围

白盒测试主要测试APP的内部结构或运作,以代码实现的角度来设计测试案例。白盒测试优点在于要求测试人员去学习软件的实现,可以检测代码中的每条分支和路径,揭示隐藏在代码中的错误,对代码的测试比较彻底。

单元测试属于白盒测试的一种手段,是一种提高软件质量非常有效的方法。对于多次的迭代开发和重构,团队需要通过单元测试来看是否新的迭代对于原有的功能是否有影响。但是,单元测试在现实实践中存在的一个不可忽视的问题是:测试用例的维护成本比较高,往往对其维护的工作量并不比被测代码的开发量小。所以,本文引入了逻辑自动化测试概念,希望能在高价值和维护成本中找到平衡。

逻辑自动化测试:考虑到手机APP的UI的多变性,仅对非UI相关的逻辑业务类进行自动化测试,优先对外接口。在本文中,以iOS手机管家为例子,逻辑自动化测试的范围选定为ObjectController文件夹中的类,此文件夹中的类文件均为与UI无关的业务逻辑类。

二、IOS单元测试框架使用和代码覆盖率查看

XCTest是Xcode5中新引入的一个测试框架,它非常简单并且与 Xcode 的 IDE 直接集成,并且其单元测试的代码不会打包到开发的项目工程里面,隔离性比较好。

1、如何新建测试用例

打开项目工程,file -》new-》target-》iOS-》iOS Unit testing bundle(输入名字和选择language),之后在此文件夹下new file新建测试用例类。

Ps:测试类继承XCTestCase类,并且测试用例必须以test开头。

2、如何执行

有两种方式:一种是UI执行,一种是命令执行。

1)UI执行方式如下:

a、直接点击每个test example 前面的菱形可单独执行特定用例;

b、在“show the test navigator”下可以点击播放按钮制定测试用例类下的全部测试用例;

c、使用command+U执行全部测试用例。

2)使用命令执行测试用例:

xcodebuild 测试target名 -scheme 工程scheme名 -destination 'platform=iOS Simulator,name=iPhone 6s Plus'

命令执行测试

Ps: 如果执行报错为:No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=armv7),那么需要修改testtarget 的属性(包括:修改testtarget中build settings下的build active architecture only改为no,同时valid architects添加 armv7 和arm64(与工程保持一致,$(ARCHS_STANDARD)))。 

3、如何收集代码覆盖率

a、首先在product->scheme->Edit Scheme里面,选中test工程,将Code Coverage模式打开;

Code Coverage

b、执行测试用例;

c、打开Xcode左边窗口的Report Navigator(图标类似微信聊天气泡),找到 Project Log,选择这个Log实例,并选择coverage能看到代码覆盖率汇总数据;

代码覆盖率汇总

d、双击你想要查看的类,可以查看代码执行次数。对于未执行代码,可根据具体的情况增加测试用例;

代码执行次数

e、实现持续交付中的代码覆盖率数据收集,关注类似如下路径的代码覆盖率数据文件:

/Users/root/Library/Developer/Xcode/DerivedData/GTFreeWifi-ewrjegavxhprvpfjdppzjkiuytaa/Logs/Test/D23E533C-7C7D-123E-911F-B096C72C602A.xccoverage。

此文件可以使用xcov-core进行解析为json文件,以文本记录了每个文件的代码覆盖率数据,便于进一步加工:

xcov-core -s test.xccoverage -o report.json

Json文件内容举例如下:

Json内容

Ps:代码覆盖率仅供参考,单纯追求覆盖率是不可行的,覆盖率只是衡量测试投入的指标,和代码质量并没有直接的关联,另外当覆盖率达到一定程序之后,继续提升覆盖率时投入和产出可能不成正比,效益可能会下降。所以,代码覆盖率数据要进行一定的平衡,即做到保证一定的质量,又做到对于人力资源的合理使用。

三、典型的测试场景

1、异步测试场景

异步测试场景

在接口测试时,我们常常会碰到异步测试场景,比如iOS手机管家中与后台请。

求相关的接口(小资讯请求、诈骗短信云查杀等),都需要等待后台返回结果数据到客户端。在等待子线程完成任务时候,我们继续主线程其他代码执行,同时,异步等待子线程返回的结果数据,并用回调函数来处理即将接收的结果数据。

在XCode6以上版本中,苹果添加了用于异步回调测试的api,因此不用像旧版本那样,发起异步调用后通过循环查询标志位,来检查异步回调函数的调用了。在新版本中直接使用XCTestExpectation的API即可实现这一功能。

a、Block方式回调;

在单测开始位置声明需要使用的Expectation对象,在回调中触发fulfill函数,单测的末尾调用api进行等待,举例如下:

block方式回调

b、代理Delegate方式回调;

与block方式回调类似,不过由于回调函数在单测函数外侧,需要把变量声明到类中,举例如下:

Delegate方式回调

Ps:如果希望保持测试用例与被测工程代码的独立性,回调函数需要在测试类中进行重写;否则,被测工程代码需要做些调整(例如:直接在工程代码中增加宏,在当前模式为测试模式时,在对应的回调函数中进行fulfill调用)。

2、如何访问private私有变量和私有方法

a、私有变量的访问和修改;

在做iOS接口测试时,会需要check私有变量是否有预期变化的情况或者修改。

私有变量的值,共有如下两种方式。

方式一:

// 获取对象实例变量的值

Ivar object_getInstanceVariable ( id obj, const char *name, void **outValue );

// 修改类实例的实例变量的值

Ivar object_setInstanceVariable ( id obj, const char *name, void *value );

上一页12下一页


留言