iOS测试总结

iOS测试

第一章 iOS测试

在编写业务代码的同时,也要编写和维护相应的测试代码。因为单元测试不仅能保证代码运行的正确性,也有助于代码结构的安排和思考,有助于自身的不断提高。

对于持续集成平台来说,测试还是非常重要的。项目中能采用自动化测试越多,平台的价值就会越大。持续集成最大的好处在于能够尽早发现问题,降低解决问题的成本。而发现问题的手段主要就在于测试。

比如输出必须在点击一系列按钮之后才能在屏幕上显示出来的东西,我们可以在代码中构建出一个类似的场景,然后在代码中调用我们之前想检查的代码,并将运行的结果与我们的设想结果在程序中进行比较,如果一致,则说明了我们的代码没有问题,是按照预期工作的。

我们做出某些条件和假设,并以其为条件使用到被测试代码中,并比较预期的结果和实际运行的结果是否相等,这就是软件开发中测试的基本方式。

测试的最低层是单元测试,即使用Xcode6.0以后的XCTest或者Kiwi等,然后是业务逻辑测试,再然后是系统测试。

Xcode的Instruments是构建Xcode持续集成不可缺少的部分。instruments中包含了很多的模版,例如leaks,alloction,automation等等,可以动态分析和跟踪内存、CPU和文件系统。

第二章 单元测试

1.概述       

单元测试作为敏捷开发实践的组成之一,其目的是提高软件开发的效率,维持代码的健康性。其目标是证明软件能够正常运行,而不是发现bug(发现bug这一目的与开发成本是正相关的,虽然发现bug是保证软件质量的一种手段,但是很显然这与降低软件开发成本这一目的背道而驰)。它是对软件质量的一种保证,例如重构之后我们需要保证软件产品的正常运行。编写单元测试没有用是认为单元测试并不能保证一定能减少bug发生的几率,而由于编写单元测试一定会花费一定的时间与精力,因而必然的会增加成本。

2.测试实践

1.每个功能类都应提供单元测试,且每一个测试类,只依赖于其要测试的受测类。使用伪造对象进行测试,避免对其他类造成影响。

eg:

 

保证一个测试类只关注一个被测类,当测试不通过时,就能迅速的定位到是谁发生了错误,而不会受到其他类的干扰。

2.测试用例(方法)名应该是自解释的且是独立的。

3.断言语句需要解释测试者的意图。

4. 运用重构的手段使方法变得易于被测试。

5.变化需要新测试的支持。

3.测试案例

1.异步测试

-(void)testHttpRequest{

// 创建期望(相当于一个NSRunLoop,因为我们不知道异步什么时候执行结束)

XCTestExpectation *expectation = [self expectationWithDescription:@"Handler called"];

myClass = [[MyClass alloc]init];

[myClass postWithUrl:@"http://baidu.com" callBackResult:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

// expection调用已完成

[expectation fulfill];

XCTAssertEqualObjects(response, @"bar");

//判断登录的时候在这里解析数据,使用断言判断登录是否成功

}];

//运行循环在处理事件,直到所有的期望都满足或超时

[self waitForExpectationsWithTimeout:5 handler:nil];

}

2.XCTest性能测试

XCTest中有 measureBlock:方法进行对算法或者某一部分的性能进行测试,如下:

-(void)testPerformance{

// 测试代码性能的一个block(如测试算法,读取内存等等)

[self measureBlock:^{

// set the initial state

[self.testVC pressView:[self.testVC.view viewWithTag:1000]];

// iterate for 100000 cycles of adding 2

for (int i=0; i<100000; i++) {

[self.testVC pressView:[self.testVC.view viewWithTag:1000]];

}

}];

}

3. 测试application创建了testVC的实例

-(void)testAppliation{

self.testVC = (ViewController*)[[UIApplication sharedApplication] delegate].window.rootViewController;

UIView *testView = self.testVC.view;

// 判断不为空的断言

XCTAssertNotNil(testView, @"Cannot find CalcView instance");

}

第三章 行为驱动测试(TDD)

1.概述

测试驱动开发的好处,它以需求为引领,通过测试的形式,来指导开发者进行软件的设计与架构,并编写出最为精炼的代码,使得测试用例运行通过。经过适当的重构之后,测试用例与产品代码可达到较为健康的状态。

它旨在解决具体问题,帮助开发人员确定应该测试些什么。此外,它鼓励开发者弄清楚他们的需求,并且它引入了一个通用语言帮助你轻易理解测试的目的。

驱动测试主要是对行为测试。即如设计的 app 中的一个对象。它有一个接口定义了其方法和依赖关系。这些方法和依赖,声明了对象的约定。它们定义了如何与应用的其他部分交互,以及它的功能是什么。

2.使用

1.配置Kiwi框架

使用cocoapods导入Kiwi框架(Kiwi导入到testtarget下) eg:

target :"TestXcodeTestTests",:exclusive => true do

platform:ios,‘7.0‘

pod ‘Kiwi‘, ‘~> 2.3.1‘

end

2.创建一个空的类,继承XctestCase。删除所有代码后导入Kiwi框架

3.具体测试使用代码如下:

// describe 描述测试对象的内容(一般一个测试文件只描述一个类)

describe(@"SimpleString", ^{

// context描述测试的上下文

context(@"when assigned to ‘Hello world‘", ^{

NSString *greeting = @"Hello world";

// it描述测试的本体

it(@"should exist", ^{

// 这里封装了类似Xctest中断言的方法

[[greeting shouldNot] beNil];

});

it(@"should equal to ‘Hello world‘", ^{

[[greeting should] equal:@"Hello world"];

});

});

});

使用Kiwi测试tableView的datasource的方法:

SPEC_BEGIN(ArrayDataSourceSpec)

describe(@"ArrayDataSource", ^{

context(@"Initializing", ^{

it(@"should not be allowed using init", ^{

[[[[ArrayDataSource alloc] init] should] beNil];

});

});

context(@"Configuration", ^{

__block DetialTableViewCell *configuredCell = nil;

__block id configuredObject = nil;

TableViewCellConfigureBlock block = ^(DetialTableViewCell *a, id b){

configuredCell = a;

configuredObject = b;

};

ArrayDataSource *dataSource = [[ArrayDataSource alloc] initWithItems:@[@"a", @"b"] cellIdentifier:@"foo" configureCellBlock:block];

id mockTableView = [UITableView mock];

DetialTableViewCell *cell = [[DetialTableViewCell alloc] init];

__block id result = nil;

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];

it(@"should receive cell request", ^{

[[mockTableView should] receive:@selector(dequeueReusableCellWithIdentifier:forIndexPath:) andReturn:cell withArguments:@"foo",indexPath];

result = [dataSource tableView:mockTableView cellForRowAtIndexPath:indexPath];

});

it(@"should return the dummy cell", ^{

[[result should] equal:cell];

});

it(@"should have benn passed to the block", ^{

[[configuredCell should] equal:cell];

});

it(@"should have the same configured object", ^{

[[configuredObject should] equal:@"a"];

});

});

context(@"number of rows", ^{

id mockTableView = [UITableView mock];

ArrayDataSource *dataSource = [[ArrayDataSource alloc] initWithItems:@[@"a", @"b"] cellIdentifier:@"foo" configureCellBlock:nil];

it(@"should be 2 items", ^{

NSInteger count = [dataSource tableView:mockTableView numberOfRowsInSection:0];

[[theValue(count) should] equal:theValue(2)];

});

});

});

SPEC_END

第四章 Xcode中Instruments

instruments是一款Xcode自带的自动化测试工具。里面包含了很多的模块,可以对iOS APP进行不同方面的测试,但是常用的就有下面几种:

1.Leaks

Leaks可以检测内存泄漏点,Allocations跟踪模板可以查看内存的使用情况。在Instruments中,虽然选择了Leaks模板,但默认情况下也会添加Allocations模板。基本上凡是分析内存都会使用Allocations模板,它可以监控内存分布情况。双击错误位置会直接找到错误代码位置。

使用方法参考:http://cn.cocos2d-x.org/tutorial/show?id=1837

2.Automation

测试UI的工具,UI测试即使用代码的形式来模拟事件触发,并让它们就好像真的是由用户的行为所触发的那样。如果测试中遇到错误,双击错误,到代码错误位置进行查看。

简单的JS登录脚本:

var target = UIATarget.localTarget();

var app = target.frontMostApp();

var mainWindow = app.mainWindow();

target.logElementTree();

var userTextField = mainWindow.textFields()[0];

userTextField.setValue("admin");

mainWindow.secureTextFields()[0].setValue("admin");

var button = mainWindow.buttons()["登 录"];

button.tap(); //点击button

Automation具有录制功能,点击录制后打开模拟器进行操作,Automation会自动生成JS代码,我们只需要在我们需要测试的模块加上For循环或者其他你想要的实现测试的方式即可。

使用方法参考:http://www.th7.cn/Program/IOS/201404/192097.shtml

时间: 2024-10-09 01:57:42

iOS测试总结的相关文章

蓝懿iOS培训日志14 测试日及测试总结

昨天考试了,上午老师给出题目,我们做.下午讲解了一下每道题.真的有种查漏补缺的感觉,有一些细节地方被自己忽略掉的都暴露了出来. 首先是考试题目,如下: 在TableViewController里面显示出10行 每一行显示,第1题  第2题 第3题 第4题.... 1.界面中添加一个文本输入框 和一个Label 还有一个按钮 文本框中只能输入数字  而且限制用户不能输入8,点击按钮的时候把文本框中的内容显示到label中. 2.界面中添加一个ScrollView,里面全屏显示5张图片,运行起来显示

互联网App应用程序测试流程及测试总结

近年来随着移动互联网发展迅猛,APP也进行了爆发式的增长,相应的APP的测试检测就摆在每家企业眼前,以下是由国内应用安全检测团队-爱内测(www.ineice.com)的CTO为我们介绍App应用程序测试流程及测试总结: 1. APP测试基本流程 1.1流程图 仍然为测试环境 Pass 1.2测试周期 测试周期可按项目的开发周期来确定测试时间,一般测试时间为两三周(即15个工作日),根据项目情况以及版本质量可适当缩短或延长测试时间.正式测试前先向主管确认项目排期. 1.3测试资源 测试任务开始前

iOS 测试在应用发布前后的痛点探索以及解决方案

作者-芈 峮 前言 iOS 开发从 2010 年开始在国内不断地升温,开发和测试相关的问题不绝于耳.iOS 测试主要涉及哪些内容?又有哪些挑战呢?带着疑问我们开始第一个大问题的讨论. iOS 测试的范围和可能遇到的挑战 iOS 测试范围 一般来说,每一个 iOS 应用的背后都会有一些后台服务.后台服务会给 iOS 应用提供丰富的数据和精彩的内容,后台服务的测试必须要包含在 iOS 测试中.当然,本文主要讨论一些 iOS 测试领域的内容,后台服务的测试在此就直接掠过.因此,下文提到的 iOS 测试

iOS -- SKSpriteNode类

SKSpriteNode类 继承自 SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKSpriteNode.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开发技术

使用fruitstrap实现命令行将IPA包安装到iOS设备上

Requirements Mac OS X. Tested on Snow Leopard only. You need to have a valid iPhone development certificate installed. Xcode must be installed, along with the SDK for your iOS version. Usage fruitstrap [-d] -b <app> [device_id] Optional -d flag laun

iOS -- SKScene类

SKScene类 继承自 SKEffectNode:SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKScene.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开

iOS -- SKPhysicsWorld类

SKPhysicsWorld类 继承自 NSObject 符合 NSCodingNSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKPhysicsWorld.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开发技术文档.虽然已经审阅了本文档的技术准确性,但是它不是最终的版本.本机密信息仅适用于

iOS证书说明和发布

1.首先通过钥匙串访问——证书助理——从证书颁发机构请求证书——填写证书信息(邮箱,常用名称,存储到磁盘)——存储为(自定义名称.certSigningReuqest,简称CSR文件,只是为了提交到苹果开发者账号中,然后就没用了)到本地 2.苹果开发者账号中,创建证书(Development和Production)——上传CSR文件——下载证书运行 ( xxx.cer文件) 注意:只有在当前电脑中生成本地生成证书,上传到苹果开发账号,然后下载cer文件运行后,钥匙串中才有证书以及对应的秘钥 如果

iOS开发——项目实战总结&amp;UITableView性能优化与卡顿问题

UITableView性能优化与卡顿问题 1.最常用的就是cell的重用, 注册重用标识符 如果不重用cell时,每当一个cell显示到屏幕上时,就会重新创建一个新的cell 如果有很多数据的时候,就会堆积很多cell.如果重用cell,为cell创建一个ID 每当需要显示cell 的时候,都会先去缓冲池中寻找可循环利用的cell,如果没有再重新创建cell 2.避免cell的重新布局 cell的布局填充等操作 比较耗时,一般创建时就布局好 如可以将cell单独放到一个自定义类,初始化时就布局好