关于iOS的UI自动化测试,是从Xcode7之后才支持的比较好,使用XCTest.framework,Xcode可以自动录制UI测试的动作流,还有就是可以使用XCTest UI testing API。
本文主要讲的是如何进行自动化测试的开发,即XCTest UI testing API的使用
首先建立工程的时候,选择如下:
Unit Tests选项,顾名思义,就是测试业务逻辑等单元测试
UI Tests选项,才是我们要重点讲的UI 自动化测试
在创建项目的时候,这两个建议都勾选上。
项目的基本构成如图所示:
Xcode自动生成的一个测试文件,也可以自己创建测试实现文件,如图所示:
接下来就要说如何进行开发工作:
1.认识核心的三个类
- XCUIApplication
- XCUIElement
- XCUIElementQuery
1.1 XCUIApplication类是Application的代理,就像我们项目工程中的AppDelegate,这个对象用来启动或者是终止UI测试程序,还可以在启动的时候设置一些启动参数,在获取程序中的UI元素的时候,就是通过这个类的实例。这个类继承自XCUIElement类
1.2 XCUIElement类是XCTest.framework对应用中的所有UI 控件的抽象,在UI测试中,没有UIKit中的UI类型,只是用这个类的实例表示所有的UI 控件,以及相应的交互方法,例如:执行手势(tap,press,swipe),滑动控件交互,拾取器交互,这个类采取了 XCUIElementAttributes协议(描述UI元素的属性:Identity,Value,Interaction State,Size),XCUIElementTypeQueryProvider协议(为指定类型的子代元素提供ready-made查询, 子代元素查询包含button,具体实现是:@property(readonly, copy) XCUIElementQuery *buttons; 等一系列对UIKit中元素的映射)
1.3 XCUIElementQuery类是定位UI 元素的查询,这个类使用类似key-value的机制得到XCUIElement的实例,使用Type(XCUIElementType枚举),Predicate, Identifier创建query,使用elementAtIndex:, elementMatchingPredicate,elementMatchingType: identifier:方法访问匹配到的UI元素,此类采用XCUIElementTypeQueryProvider协议
2.实际测试需要完成的工作
在Interface Builder中的设置如下图:
代码手动设置控件,如下:
subViewButton1.accessibilityIdentifier = @"Button111";
subViewButton1.accessibilityLabel = @"Button11";
[subViewButton1 setTitle:@"Button1" forState:UIControlStateNormal];
录制UI测试流的操作是在指定的某个测试case类文件中,先定义好测试方法名,然后操作如下图:
当你在与UI元素交互的时候,这个方法会边生成自动测试的代码
如果进行手动编码的话,使用XCTest框架查询UI元素的操作方法的代码如下:
// if element property isAccessibilityElement is YES, identifier previllage is top then the label, then the staticText, last is MatchingType:,otherwise title staticText is top,then ccessablitityIdentifier, then accessablitityLabel, then matchType:
[[[XCUIApplication alloc] init].buttons[@"Button111"] tap]; // 方法一
XCUIElement *button11Button = [[XCUIApplication alloc] init].buttons[@"Button11"]; // 方法二
[button11Button tap];
[[[XCUIApplication alloc] init].buttons[@"Button1"] tap]; // 方法三
XCUIApplication *app = [[XCUIApplication alloc] init];
[[[[[[[[app.otherElements containingType:XCUIElementTypeNavigationBar identifier:@"Login"] childrenMatchingType:XCUIElementTypeOther].element childrenMatchingType:XCUIElementTypeOther].element childrenMatchingType:XCUIElementTypeOther].element childrenMatchingType:XCUIElementTypeOther].element childrenMatchingType:XCUIElementTypeButton] elementBoundByIndex:1] tap]; // 方法四(注意,这个地方的调用层数跟元素嵌套是有关系的,具体可以看代码)
以上就完成了一个UI测试Case类的自动化工作。接下来就是根据项目测试的需要创建更多的测试case类。
具体的Demo工程在:https://github.com/forwardto9/XCTDemo,关于XCtest.framework其他的API的使用也在其中。
问题一,在实际开发中,UI变化之后,之前自动生成的测试代码就可能失效了,需要再一次录制或者是手动开发,自动化还需要能更加节省成本。