码迷,mamicode.com
首页 > 移动开发 > 详细

iOS测试总结

时间:2015-09-09 13:04:33      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:

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

 

iOS测试总结

标签:

原文地址:http://www.cnblogs.com/shushulele/p/4794096.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!