xcodebuild unit test怎么让文字布满整个testview

Xcode7 UI自动化测试详解 带demo UITests - 简书
Xcode7 UI自动化测试详解 带demo UITests
UI Tests是什么?
UI Tests是一个自动测试UI与交互的Testing组件
UI Tests有什么用?
它可以通过编写代码、或者是记录开发者的操作过程并代码化,来实现自动点击某个按钮、视图,或者自动输入文字等功能。
UI Tests的重要性
在实际的开发过程中,随着项目越做越大,功能越来越多,仅仅靠人工操作的方式来覆盖所有测试用例是非常困难的,尤其是加入新功能以后,旧的功能也要重新测试一遍,这导致了测试需要花非常多的时间来进行回归测试,这里产生了大量重复的工作,而这些重复的工作有些是可以自动完成的,这时候UI Tests就可以帮助解决这个问题了
第一步:添加UI Tests
如果是新项目,则创建工程的时候可以直接勾选选项,如下图
如果是已有的项目,可以通过添加target的方式添加一个UI Tests,点击xcode的菜单,找到target栏
添加target
在Test选项中选择Cocoa Touch UI Testing Bundle
添加target_2
这时候test组件添加成功,它在项目中的位置如下图所示
第二步:创建测试代码
手动创建测试代码打开测试文件,在testExample()方法中添加测试代码
这里写图片描述
如果不知道如何写测试代码,则可以参考自动生成的代码样式
自动生成测试步骤选择测试文件后,点击录制按钮
这里写图片描述
这时候开始进行操作,它会记录你的操作步骤,并生成测试代码下图就是在一些操作后自动生成的测试代码
这里写图片描述
这时候可以分析测试代码的语法,以便你自己手动修改或者手写测试代码
开始测试点击testExample方法旁边的播放按钮,它就开始进行自动测试了,这时候你会看到app在自动操作
这里写图片描述
下面介绍一下测试元素的语法
XCUIApplication:继承XCUIElement,这个类掌管应用程序的生命周期,里面包含两个主要方法launch():启动程序terminate():终止程序
XCUIElement: 继承NSObject,实现协议XCUIElementAttributes, XCUIElementTypeQueryProvider可以表示系统的各种UI元素exist:可以让你判断当前的UI元素是否存在,如果对一个不存在的元素进行操作,会导致测试组件抛出异常并中断测试descendantsMatchingType(type:XCUIElementType)-&XCUIElementQuery:取某种类型的元素以及它的子类集合childrenMatchingType(type:XCUIElementType)-&XCUIElementQuery: 取某种类型的元素集合,不包含它的子类
这两个方法的区别在于,你仅使用系统的UIButton时,用childrenMatchingType就可以了,如果你还希望查询自己定义的子Button,就要用descendantsMatchingType
另外UI元素还有一些交互方法tap():点击doubleTap():双击pressForDuration(duration: NSTimeInterval):长按一段时间,在你需要进行延时操作时,这个就派上用场了swipeUp():这个响应不了pan手势,暂时没发现能用在什么地方,也可能是beta版的bug,先不解释typeText(text: String):用于textField和textView输入文本时使用,使用前要确保文本框获得输入焦点,可以使用tap()函数使其获得焦点
XCUIElementAttributes协议里面包含了UIAccessibility中的部分属性如下图
这里写图片描述
可以方便你查看当前元素的特征,其中identifier属性可用于直接读取元素,不过该属性在UITextField中有bug,暂时不清楚原因
XCUIElementTypeQueryProvider协议里面包含了系统中大部分UI控件的类型,可通过读属性的方式取得某种类型的UI集合部分属性截图如下
这里写图片描述
首先创建一个登录页面
这里写图片描述
点击login按钮进行登录验证,点击clear按钮会清除文本登录成功后可以去到个人信息页面
个人信息页面如下
这里写图片描述
点击modify按钮可以修改个人信息,点击Message按钮可以查看个人消息
最后是消息界面
这里写图片描述
登录页面的测试
输入一个错误的账号
关闭警告窗
清除输入记录
输入一个正确的账号
进入个人信息页面测试代码如下:
func testLoginView() {
let app = XCUIApplication()
// 由于UITextField的id有问题,所以只能通过label的方式遍历元素来读取
let nameField = self.getFieldWithLbl("nameField")
if self.canOperateElement(nameField) {
nameField!.tap()
nameField!.typeText("xiaoming")
let psdField = self.getFieldWithLbl("psdField")
if self.canOperateElement(psdField) {
psdField!.tap()
psdField!.typeText("1234321")
// 通过UIButton的预设id来读取对应的按钮
let loginBtn = app.buttons["Login"]
if self.canOperateElement(loginBtn) {
loginBtn.tap()
// 开始一段延时,由于真实的登录是联网请求,所以不能直接获得结果,demo通过延时的方式来模拟联网请求
let window = app.windows.elementAtIndex(0)
if self.canOperateElement(window) {
// 延时3秒, 3秒后如果登录成功,则自动进入信息页面,如果登录失败,则弹出警告窗
window.pressForDuration(3)
// alert的id和labe都用不了,估计还是bug,所以只能通过数量判断
if app.alerts.count & 0 {
// 登录失败
app.alerts.collectionViews.buttons["确定"].tap()
let clear = app.buttons["Clear"]
if self.canOperateElement(clear) {
clear.tap()
if self.canOperateElement(nameField) {
nameField!.tap()
nameField!.typeText("sun")
if self.canOperateElement(psdField) {
psdField!.tap()
psdField!.typeText("111111")
if self.canOperateElement(loginBtn) {
loginBtn.tap()
if self.canOperateElement(window) {
// 延时3秒, 3秒后如果登录成功,则自动进入信息页面,如果登录失败,则弹出警告窗
window.pressForDuration(3)
self.loginSuccess()
// 登录成功
self.loginSuccess()
这里有几个需要特别注意的点:
当你的元素不存在时,它仍然可能返回一个元素对象,但这时候不能对其进行操作
当你要点击的元素被键盘或者UIAlertView遮挡时,执行tap方法会抛异常详细实现可参照demo:
个人信息页测试
保存修改测试代码如下:
func testInfo() {
let app = XCUIApplication()
let window = app.windows.elementAtIndex(0)
if self.canOperateElement(window) {
// 延时2秒, 加载数据需要时间
window.pressForDuration(2)
let modifyBtn = app.buttons["modify"];
modifyBtn.tap()
let sexSwitch = app.switches["sex"]
sexSwitch.tap()
let incrementButton = app.buttons["Increment"]
incrementButton.tap()
incrementButton.tap()
incrementButton.tap()
app.buttons["Decrement"].tap()
let textView = app.textViews["feeling"]
textView.tap()
app.keys["Delete"].tap()
app.keys["Delete"].tap()
textView.typeText(" abc ")
// 点击空白区域
let clearBtn = app.buttons["clearBtn"]
clearBtn.tap()
// 保存数据
modifyBtn.tap()
window.pressForDuration(2)
let messageBtn = app.buttons["message"]
messageBtn.tap();
// 延时1秒, push view需要时间
window.pressForDuration(1)
self.testMessage()
这里需要特别注意以下两点:
textview获取焦点时无法选择焦点的位置
tap事件的触发位置是view的中心,所以当view的中心被遮挡时,要考虑使用其他view来代替
个人消息界面测试
单元格的点击测试代码如下:
func testMessage() {
let app = XCUIApplication()
let window = app.windows.elementAtIndex(0)
if self.canOperateElement(window) {
// 延时2秒, 加载数据需要时间
window.pressForDuration(2)
let table = app.tables
table.childrenMatchingType(.Cell).elementAtIndex(8).tap()
table.childrenMatchingType(.Cell).elementAtIndex(1).tap()
这里需要注意一点:
暂时无法获取到tableView的元素指针
总的来说,UI Tests只能用于一些基础功能的测试,验证app的功能是否可以正常使用,是否存在崩溃问题。但它也有很多不足之处,编写测试用例的过程非常繁琐,自动生成的代码几乎无法运行,功能单一,很多用例无法覆盖,而且bug很多,大大地限制了UI Tests在实际开发中的应用。希望正式版出来的时候能够修复这些问题,并开放更多的功能。
demo地址:
欢迎各位提出改进建议,感谢!
CSDN博客: http://blog.csdn.net/zhao18933
Github: /sunljz2013年4月 总版技术专家分月排行榜第一2013年3月 总版技术专家分月排行榜第一
2013年4月 .NET技术大版内专家分月排行榜第一2013年3月 .NET技术大版内专家分月排行榜第一
2013年4月 总版技术专家分月排行榜第一2013年3月 总版技术专家分月排行榜第一
2013年4月 .NET技术大版内专家分月排行榜第一2013年3月 .NET技术大版内专家分月排行榜第一
本帖子已过去太久远了,不再提供回复功能。XCode7如何使用UI Test - 博客频道 - CSDN.NET
分类:总结
看了WWDC15中what’s new in XCode后,忍不住想试试XCode中UITest,先上图说一下简单流程。
1、下载XCode7 beta版,创建一个工程,然后选中”工程名+UITests.m”文件,然后会看到底部Debu区域的红点,此时红点不可点击。例如我创建的是Xcode7TestDemo,则选中Xcode7TestDemoUITests.m文件,如下图:
2、光标点击代码中的某一处,此时红点可点击,而光标停留的地方将是代码录制的起点。点击红点,然后操作界面,代码录制在此处。如下图:
3、运行测试,可以选择test运行,但最好的方式是直接点击testExample方法左边的勾勾运行,简单易用。
4、运行成功,模拟器随着你的启动自动跑起来,享受UITest吧!相比于Automation的自动化测试,UITest使用的OC/Swift语言的自动化测试,而前者使用的是JS代码,UITest对我们iOS开发人员更友好。而且,UITest嵌套在每个应用当中,使用起来就和我们调试一样简单易用,所以尽情的享受UITest吧!
Demo地址:
排名:千里之外
(2)(2)(1)(2)(3)(1)(1)(1)(1)(1)(1)(1)(1)(9)(3)(24)(1)(6)(3)(1)今天看啥 热点:
最近在看电驴上down下来的ipad开发视频教程。为加深记忆,特在此做笔记。
前两集视频主要讲的是UIAlertView相当于windows里面的MessageBox)
在interface builder里面添加了控件之后,要想使得控件响应事件必须做如下处理:
1:在XXXViewController.h里面添加事件响应函数声明如:
-(IBAction)btnOnclick:(id)&
2:在相应的.m文件中实现这个函数
3:回到interface builder中鼠标右键从需要使用这个事件相应函数的控件拖拽到File's Owner上并在弹出的选项中选中步骤1中的函数名,使之关联起来。
注意:这个视频里面提到了一个特别的控件就是UIAlertView,因为这个控件没有在interface builder中提供出来编辑。所以如果这个要使这个控件的事件得到相应需要在XXXViewController.h文件里面声明类的时候使用协议(类似C++里面的抽象基类的多重继承)。样子如下:
#import&/UIKit.h&@interface&AlertViewTestViewController&:&UIViewController&{ &} &@end&
然后在实现文件里面实现对应的事件处理函数。对UIAlertView来说。要使用的协议是UIAlertViewDelegate,要实现的事件响应函数是 - (void)alertView:(UIAlertView* )alertView clickedButtonAtIndex:(NSInteger)buttonIndex。实际上,使用了协议之后,可以根据协议名字在帮助里面很快的找到这个协议需要实现哪些函数。
控件还有另外一个比较重要的东西就是数据绑定。在xcode里面要实现这么一个东西步骤基本和上面的类似
1:在XXXViewController.h文件里面声明之,下面声明了一个文本数据
@interface&OutletAndActionViewController&:&UIViewController&{ &&&&&IBOutlet&UITextField&*txtN &} &@property(nonatomic,&retain)&UITextField&*txtN &@end&
2:实现文件里面给出set和get函数。如果使用了属性,你懂的。。。
@synthesize&txtN&
3:回到interface builder中鼠标右键从File's Owner中拖拽到需要绑定这个数据的控件上并在弹出的选项中选中,使之关联起来。拖拽方向和上面相反。写到这里。我在想IBAction和IBOutlet到底是个啥?
在头文件中找到了他们的定义:
#ifndef&IBOutlet& &#define&IBOutlet& &#endif &&#ifndef&IBAction& &#define&IBAction&void& &#endif&
几乎啥都没干。最后在cocoachina上找到了答案。
原帖:/bbs/read.php?tid-18829.html
内容如下:
These two keywords do absolutely nothing as far as the compiler is concerned. IBOutlet gets entirely removed from the code before the compiler ever sees it. IBAction resolves to a void return type, which just means that action methods do not return a value. So, what&s going on here?
The answer is simple, really: IBOutlet and IBAction are not used by the compiler. They are used by Interface Builder. Interface Builder uses these keywords to parse out the outlets and actions available to it. Interface Builder can only see methods that are prefaced with IBAction and can only see variables or properties that are prefaced with IBOutlet. Also, the presence of these keywords tells other programmers, looking at your code in the future, that the variables and methods in question aren&t dealt with entirely in code. They&ll need to delve into the relevant nib file to see how things are hooked up and used.
敢情这两关键字完全是给interface builder看的。
小结:Xcode 学习之路 Interface Builder使用技巧 的内容介绍完了希望本文对你有所帮助!
相关搜索:
相关阅读:
相关频道:
IOS教程最近更新

我要回帖

更多关于 xcodebuild unit test 的文章

 

随机推荐