Unit Test -- 初步了解

什么是单元测试

在计算机编程中,单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。 —— [ 维基百科 ]

为什么要使用单元测试

  • 单元测试能保证在加入新功能或修改旧功能时代码的正确性
  • 单元测试保证在整个开发流程中代码都会被测试,更容易及早发现问题,降低风险。

单元测试集成

  • 方法一
    创建新的工程时,勾选”Include Unit Tests”,如下图
    创建工程

  • 方法二
    如果在新建工程的时候没有勾选,咱们还可以有另一种方式:
    这里写图片描述

至此,我们就集成了XCTest,可以发现工程内多了一个文件夹,以及一个Target

这里写图片描述

setUp与tearDown

在默认生成的.m文件中有几个默认生成的方法

这里写图片描述

扫描二维码关注公众号,回复: 2578173 查看本文章
  • setUp:在所有的测试方法调用之前会调用该方法,一般在该方法中初始化一些必要的对象。
  • tearDown:该方法与setUp方法相对应,在所有测试方法调用完成后会调用该方法,一般在setUp方法中初始化的对象在该方法中销毁。

使用

要为你的工程添加测试,首先你需要为待测试的类创建一个XCTestCase的子类作为测试类,然后添加一个或多个测试方法。

1.创建测试类

我们可以为每个功能类添加一个测试类,所有测试类都是继承于XCTestCase:
这里写图片描述

2.创建测试方法

  • 所有测试方法都是以test开头、无返回值、无参数的实例方法。
  • 每一个测试方法的写法有三个步骤:
    1. Mock对象,准备测试数据。
    2. 调用要测试的目标API。
    3. 验证输出和行为是否正确。
- (void)setUp {
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
    // 初始化必要的数据
    self.carMetter = [[BWCarMetter alloc] init];
    self.carMetter.startingPrice = 8;
    self.carMetter.milePrice = 1.2;
    self.carMetter.timePrice = 0.5;
}

- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    // 回收内存
    self.carMetter = nil;
    [super tearDown];
}

// 测试费用计算
- (void)testCountingFee {
    // 1. 模拟数据
    CGFloat distance = 20;
    CGFloat duration = 30; // 30分

    // 2.调用接口
    CGFloat result = [self.carMetter feeWithDuration:duration distance:distance];

    // 3.验证结果
    CGFloat actualFee = self.carMetter.startingPrice + self.carMetter.timePrice * duration + self.carMetter.milePrice * distance;
    XCTAssertEqual(result, actualFee);
}

断言

XCTest中使用断言(XCTAssert)来检验输出,常用的断言有

XCTAssert(expression, ...) 当表达式为真,测试通过
XCTAssertTrue(expression, ...) 表达式为真,测试通过
XCTAssertFalse(<#expression, ...#>) 表达式为假,测试通过
XCTAssertNil(expression, ...) 表达式为空,测试通过
XCTAssertNotNil(expression, ...) 表达式不为空,测试通过
XCTAssertEqual(expression1, expression2, ...) 表达式1与表达式2相等,测试通过
XCTAssertEqualObjects(expression1, expression2, ...) 两个对象相等,测试通过
XCTAssertEqualWithAccuracy(expression1, expression2, accuracy, ...) 两个表达式(通常为float或则double)的值在一定误差范围内相等,测试通过
XCTAssertNotEqual(expression1, expression2, ...) 
XCTAssertNotEqualObjects(expression1, expression2, ...)
XCTAssertEqualWithAccuracy(expression1, expression2, accuracy, ...)
XCTFail(<#...#>) 生成一个失败的测试

运行测试方法

我们可以使用快捷键command + U来运行工程中的所有测试方法。
有时候我们可能需要单独运行测试方法,这时候,将鼠标放在需要运行的测试方法上,可以发现该方法的左边有一个播放按钮,点击这个播放按钮就可以运行该方法:
这里写图片描述
你也可以在工程面板中浏览工程中的所有测试类以及该类中所有的测试方法,将鼠标放在对应的测试类上、或则对应的测试方法上,可以发现其右边有一个播放按钮,点击该按钮可以运行该类中的所有测试方法或则某个测试方法:
这里写图片描述
运行后的结果如下

性能测试

性能测试可直接使用 - (void)measureBlock:(void (^)(void))block; 进行,传递参数即为要执行任务组成的一个block。 如:

注意:一个性能测试case中只能执行一次measureBlock,在while,for等循环中是不能使用measureBlock的,否则会出错。

异步测试

我们通常会将一些耗时的操作放在线程中异步执行,例如:网络请求。XCTest提供了XCTestExpectation来进行异步测试。如:

 - (void)testAsynchronousExample {
    XCTestExpectation *expectation = [self expectationWithDescription:@"testAsynchronousExample"];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // 睡眠2s
        sleep(3);
        // 测试通过
        NSAssert(1, @"time out");
        // 告知测试完成
        [expectation fulfill];
    });

    //等待5s,若该测试未结束(未收到 fulfill方法)则测试结果为失败
    [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) {
    }];
}

-fulfill 告知测试已完成,每个XCTestExpectation对象都必须在测试完成后调用fulfill。
-waitForExpectationsWithTimeout:handler: 该方法阻塞线程等待测试完成通知(即:所有创建的XCTestExpectation对象都调用了fullfill方法),如果等待超时,则测试不通过,可以将上一个例子中的5s改为2s看看测试结果。

访问待测试类的私有变量或则私有方法

如何访问某个待测类的私有变量或则私有方法呢,创建该待测类的类别并暴露需要访问的私有属性或则私有方法即可,如:

#import <XCTest/XCTest.h>
#import "BWCarMetter.h"

@interface BWCarMetter (UnitTest)
// 某个私有属性
@property (nonatomic, copy) NSString *aPrivateProperty;
// 某个私有方法
- (void)pricateMethod;

@end

@interface BWCarMetterTest : XCTestCase

@property (nonatomic, strong) BWCarMetter *carMetter;

@end

@implementation BWCarMetterTest
xxx
@end

猜你喜欢

转载自blog.csdn.net/u011656331/article/details/77980166