天天看点

基于测试驱动的iOS开发

         测试按照阶段划分为:单元测试、集成测试、系统测试和回归测试。单元测 试是对软件组成单元进行测试,其目的是检验软件基本组成单位的正确性,其测试对象是软件设计的最小单位 —— 模块。 单元测试是一种白盒测试。白盒测试是一种细粒度的测试,具体到方法、函数和异常测试,因此是由能够看 懂编程语言、了解程序结构的程序员发起的。为了验证程序的正确性,程序员需要编写测试程序,按照测试用例 测试程序是否能够有预期的结果。 1. 测试驱动的软件开发概述 1.1 测试驱动的软件开发流程      传统的开发流程如图 16-1 所示,先是程序编码,然后设计单元测试用例,编写单元测试程序,进行单元测试, 最后出具单元测试报告。如果测试没有通过,要根据测试修改程序代码,然后再重新走单元测试流程。      而极限编程的测试驱动的软件开发流程如图 16-2 所示,先是设计单元测试用例程序,编写单元测试程序,然 后编写程序代码和进行单元测试,最后出具单元测试报告。如果测试没有通过,根据测试修改程序代码,然后重 新走单元测试流程。如果通过测试,再设计其他的单元测试用例。      在测试驱动开发流程中,各个阶段都是一个可逆的反复迭代过程。用例的设计可以先是功能说明书中的一个 功能,然后针对该功能进行测试驱动的开发流程,再编写其他的功能。

基于测试驱动的iOS开发

比较这两种方式,我们可以发现测试驱动开发的优势很明显,它能够及时地发现程序中的问题,从而少犯错 误,减少资源浪费。

1.2 测试驱动的软件开发案例

基于测试驱动的iOS开发
基于测试驱动的iOS开发

  2.编写单元测试程序

iOS单元测试框架 有以下几种:  OCUnit。它是开源测试框架,与 Xcode 工具集成在一起使用非常方便。测试报告以文本形式输出到输出窗 口中。  GHUnit。它是开源测试框架,可以将测试报告以应用的形式可视化输出到设备或模拟器上,也可以以文 本的形式输出到输出窗口中。使用GHUnit,可以测试用OCUnit编写的测试用例。  OCMock。它是开源测试框架,主要为测试提供 mock 对象(伪对象)。 在接下来的内容中,我们会展开介绍这3个框架。

2.1  使用OCUnit 测试框架  2.1.1  添加OCUnit到工程中 添加 OCUnit 到工程中,有两种方法:一种是在创建工程时添加,选中 Include Unit Tests 复选框;另一种是在 现有工程中添加Cocoa Touch Unit Testing Bundle Target来实现。下面我们详细介绍这两种添加过程。 1. 创建工程时添加

基于测试驱动的iOS开发
基于测试驱动的iOS开发

但是打开 Scheme 列表时,还是只有一个 PITax ,这是我们需要注意的。若要运行测试程序,可以选择 Product → Test 菜单,或者点击工具栏中的 Test 按钮(下拉 Run 按钮选择),或使用快捷键 command+u 等几种方式。 如果打开Frameworks组,会发现其中添加了SenTestingKit.framework,这就是OCUnit框架。

2. 在现有工程中添加Target实现 选择 File → New → Target… 菜单项, 从中选择 iOS → Other 中的 Cocoa Touch Unit Testing Bundle 模板.

基于测试驱动的iOS开发
基于测试驱动的iOS开发
基于测试驱动的iOS开发

在 .m 文件中,需要重新调用 setUp 和 tearDown 方法。 setUp 方法是初始化方法, tearDown 方法是释放资源的方法,它们在每次调用测试方法之前和之后调用。因此,在测试类运行的生命周期中,这两个 方法可能多次运行,它们的时序图

基于测试驱动的iOS开发

2.1.2 编写 XCTest 测试方法 XCTest的前身是OCUnit,它是一个集成在Xcode中的测试框架。它的使用比较简单,现在Xcode6默认建立的工程就带有XCTest。当然如果是旧的工程没有这个测试,或者不小心删了也没有关系,可以重新添加以下。 每一个单元测试用例对应于测试类中的一个方法,因此测试类分为逻辑测试类和应用测试类。在设计测试用 例时,逻辑测试和应用测试也是不同的。编写 XCTest 测试方法时,也分逻辑测试和应用测试。 1.逻辑测试用例

基于测试驱动的iOS开发

2.应用测试用例 应用测试主要用于测试应用程序的一些功能,这些功能具体到点击一个按钮触发一个事件,因此,它主要测 试表示层。

基于测试驱动的iOS开发

2.1.3  分析测试报告

基于测试驱动的iOS开发
基于测试驱动的iOS开发
基于测试驱动的iOS开发

绿色部分表示测试通过,红色部分标示测试未通过。点击小黑三角可以重新测试。command+U测试快捷键/ Product->Test 测试用例代码:

#import <XCTest/XCTest.h>

#import "ViewController0.h"

#import "AppDelegate.h"

@interface PITaxTests : XCTestCase

@property (nonatomic,strong) ViewController0 *vc;

@end

@implementation PITaxTests

- (void)setUp {

    [supersetUp];

    // Put setup code here. This method is called before the invocation of each test method in the class.

    self.vc = [[ViewController0alloc] init];

}

- (void)tearDown {

    // Put teardown code here. This method is called after the invocation of each test method in the class.

    self.vc =nil;

    [supertearDown];

}

- (void)testExample {

    // This is an example of a functional test case.

    // Use XCTAssert and related functions to verify your tests produce the correct results.

}

- (void)testPerformanceExample {

    // This is an example of a performance test case.

    [selfmeasureBlock:^{

        // Put the code you want to measure the time of here.

    }];

}

// 测试不输入直接点击“计算”按钮的情况

- (void)testButtonClickInputBlank

{

    // 设定输入值

    self.vc.textField.text = @"";

    // 调用ButtonClick

    [self.vcbuttonClick:nil];

    // 取得输出结果

    XCTAssertEqual(self.vc.myTax,0.00,@"期望值是:0.00实际值是:%f",self.vc.myTax);

}

// 测试整数

- (void)testButtonClickInputIntegerNumber

{

    XCTAssertNotNil(self.vc,@"ViewController没有赋值");

    // 设定输入值

    self.vc.textField.text = @"8000";

    // 调用ButtonClick

    [self.vcbuttonClick:nil];

    // 取得输出结果

    XCTAssertEqual(self.vc.myTax,345.00,@"期望值是:345.00实际值是:%f",self.vc.myTax);

}

// 测试小数

- (void)testButtonClickInputOneDot

{

    XCTAssertNotNil(self.vc,@"ViewController没有赋值");

    // 设定输入值

    self.vc.textField.text = @"8000.59";

    // 调用ButtonClick

    [self.vcbuttonClick:nil];

    // 取得输出结果

    XCTAssertEqual(self.vc.myTax,345.12,@"期望值是:345.12实际值是:%f",self.vc.myTax);

}

// 测试输入两个小数点的情况

- (void)testButtonClickInputTwoDot

{

    XCTAssertNotNil(self.vc,@"ViewController没有赋值");

    // 设定输入值

    self.vc.textField.text = @"40000.50.56";

    // 调用ButtonClick

    [self.vcbuttonClick:nil];

    // 取得输出结果

    XCTAssertEqual(self.vc.myTax,8195.15,@"期望值是:8195.15实际值是:%f",self.vc.myTax);

}

// 测试有前导0的数据

- (void)testButtonClickInputfixZero

{

    XCTAssertNotNil(self.vc,@"ViewController没有赋值");

    // 设定输入值

    self.vc.textField.text = @"08000.59";

    // 调用ButtonClick

    [self.vcbuttonClick:nil];

    // 取得输出结果

    XCTAssertEqual(self.vc.myTax,345.12,@"期望值是:345.12实际值是:%f",self.vc.myTax);

}

// 测试连在一起的两个小数点的情况

- (void)testButtonClickInputLinkDot

{

    XCTAssertNotNil(self.vc,@"ViewController没有赋值");

    // 设定输入值

    self.vc.textField.text = @"40000.50..56";

    // 调用ButtonClick

    [self.vcbuttonClick:nil];

    // 取得输出结果

    XCTAssertEqual(self.vc.myTax,8195.15,@"期望值是:8195.15实际值是:%f",self.vc.myTax);

}

@end

2.2  使用GHUnit 测试框架

GHUnit 测试框架是一个基于 Objective-C 的测试框架,支持 Mac OS X 10.5 和 iOS 3.0 以上版本。它也是其他一 些框架的基础框架,比如 OCUnit和 GTM( Google Toolkit Mac)。一般用于逻辑测试,不用于应用测试。它能够在设备和模拟器上测试,还支持异步测试。使用 GHUnit测试框架后,输出的日志信息更加详细。 GHUnit 是第三方框架,需要从 https://github.com/gabriel/gh-unit/downloads 上下载