赞
踩
一、相关知识及使用框架
在Xcode8.1之前我们还能用UIAutomation 之类的工具进行自动化测试,然后再Xcode8.x之后我们无法用其进行 自动化测试。
框架可以分为两大类:XCode内置的和三方库。
选择框架的时候有几个方面要考虑
测试代码编写的成本
是否可调式
框架的稳定性
测试报告(截图,代码覆盖率,…)
WebView的支持(很多App都用到了H5)
自定义控件的测试
是否需要源代码
能否需要连着电脑
是否支持CI(持续集成)
….
我们首先来看看XCode内置的框架:XCTest。XCTest又可以分为两部分:Unit Test 和 UI Test,分别对应单元测试和UI测试。有一些三方的测试库也是基于XCTest框架的,这个在后文会讲到。由于是Apple官方提供的,所以这个框架会不断完善。
成熟的三方框架通常提供了很多封装好的有好的接口,笔者综合对比了一些,推荐以下框架:
单元测试:
以下三个框架都是BDD(Behavior-driven development) - 行为驱动开发。行为驱动开发简单来说就是先定义行为,然后定义测试用例,接着再编写代码。 实践中发现,通常没有那么多时间来先定义行为,不过BDD中的domain-specific language (DSL)能够很好的描述用例的行为。
UI测试
KIF 基于XCTest的测试框架,调用私有API来控制UI,测试用例用Objective C或Swift编写。
appium 基于Client - Server的测试框架。App相当于一个Server,测试代码相当于Client,通过发送JSON来操作APP,测试语言可以是任意的,支持android和iOS。
篇幅有限,本文会先介绍XCtest,接着三方的Unit框架会以Quick为例,UI Test框架侧重分析KIF,appium仅仅做原理讲解。
XCTest
对于XCTest来说,最后生成的是一个bundle。bundle是不能直接执行的,必须依赖于一个宿主进程。关于XCTest进行单元测试的基础(XCode的使用,异步测试,性能测试,代码覆盖率等),我在这篇文章里讲解过,这里不再详细讲解。
单元测试用例
比如,我有以下一个函数:
1
2
3
|
//验证一段Text是否有效。(不能以空字符开头,不能为空)
- (BOOL)validText:(NSString *)text error:(NSError *__autoreleasing *)error{
}
|
那么,我该如何为这个函数编写单元测试的代码?通常,需要考虑以下用例:
输入以空白字符或者换行符开头的,error不为空,返回 NO
输入正确的内容,error为空,返回YES
输入为nil,error不为空,返回 NO (边界条件)
输入为非NSString类型,验证不通过,返回NO (错误输入)
特殊输入字符(标点符号,非英文等等)
UI测试
UI测试是模拟用户操作,进而从业务处层面测试。关于XCTest的UI测试,建议看看WWDC 2015的这个视频:
关于UI测试,有几个核心类需要掌握
XCUIApplication 测试应用的代理
XCUIElement 一个UI上可见的视图对象
XCUIElementQuery 查找XCUIElement
UI测试还有一个核心功能是UI Recording。选中一个UI测试用例,然后点击图中的小红点既可以开始UI Recoding。你会发现:
随着点击模拟器,自动合成了测试代码。(通常自动合成代码后,还需要手动的去调整)
在写UI测试用例的时候要注意:测试行为而不是测试代码。比如,我们测试这样一个case
进入Todo首页,点击add,进入添加页面,输入文字,点击save。
测试效果如下:
对应测试代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
- (void)testAddNewItems{
//获取app代理
XCUIApplication *app = [[XCUIApplication alloc] init];
//找到第一个tabeview,就是我们想要的tableview
XCUIElement * table = [app.tables elementBoundByIndex:0];
//记录下来添加之前的数量
NSInteger oldCount = table.cells.count;
//点击Add
[app.navigationBars[@
"ToDo"
].buttons[@
"Add"
] tap];
//找到Textfield
XCUIElement *inputWhatYouWantTodoTextField = app.textFields[@
"Input what you want todo"
];
//点击Textfield
[inputWhatYouWantTodoTextField tap];
//输入字符
[inputWhatYouWantTodoTextField typeText:@
"somethingtodo"
];
//点击保存
[app.navigationBars[@
"Add"
].buttons[@
"Save"
] tap];
//获取当前的数量
NSInteger newCount = table.cells.count;
//如果cells的数量加一,则认为测试成功
XCTAssert(newCount == oldCount + 1);
}
|
这里是通过前后tableview的row数量来断言成功或者失败。
等待
通常,在视图切换的时候有转场动画,我们需要等待动画结束,然后才能继续,否则query的时候很可能找不到我们想要的控件。
比如,如下代码等待VC转场结束,当query只有一个table的时候,才继续执行后续的代码。
1
2
3
4
5
|
[self expectationForPredicate:[NSPredicate predicateWithFormat:@
"self.count = 1"
]
evaluatedWithObject:app.tables
handler:nil];
[self waitForExpectationsWithTimeout:2.0 handler:nil];
//后续代码....
|
Tips: 当你的UI结构比较复杂的时候,比如各种嵌套childViewController,使用XCUIElementQuery的代码会很长,也不好维护。
另外,UI测试还会在每一步操作的时候截图,方便对测试报告进行验证。
查看测试结果
使用基于XCTest的框架,可以在XCode的report navigator中查看测试结果。
其中:
Tests 用来查看详细的测试过程
Coverage 用来查看代码覆盖率
Logs 用来查看测试的日志
点击图中的红色框指向的图标可以看到每一步UI操作的截图
除了利用XCode的GUI,还可以通过后文提到的命令行工具来测试,查看结果。
选择完了使用的工具和框架后,我们需要进行需求进行分析,对每次自动化测试所需要涉及的场景进行分析后,在XCUITest.m实现文件中进行编码,进行对应的自动化操作。另外由于涉及到项目需要获取应用性能数据,例如 当前应用占用内存或CPU 的数据,可以用一个单例类在应用启动的时候启动写入数据,设置对应写入的时间间隔。经多次调试与Xcode原生Profile 工具获取的数据对比后得出:当间隔为1s一次写入时,对于应用的数据干扰性最小(cpu)。此处写入数据的方式,最好用c 的FILE 文件流操作,提高写入的效率和稳定性。文件操作相关知识:http://note.youdao.com/noteshare?id=689106273e83933f568fe8ee7b9ea3a6
除了需要掌握原生的测试工具以外,我们还需要一些可执行脚本工具来帮助我们进行自动化测试。
二、工具安装及环境配置
xcodebuild -project ./code/xxx().xcodeproj -list
// 进行Test
#应用文件下载到本地
rm -rf ./aaa
ios-deploy -1 com.xxx.xxx -w-2 aaa(目标路径)
如此就在aaa 目录下得到了手机中保存的应用数据。后续操作就不在一一赘述了。
三、总结
通过性能测试,提高测试的效率,节省了人工的时间,并且,通过性能测试分析前后版本的相关数据差异,分析新版本的稳定性和相关页面的代码性能的可优化性。起到了很重要的作用。
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。