XCTest测试框架(单元测试XCTests、性能测试XCPPerformanceTests、用户界面测试XCUItests)
单元测试XCTests:测试应用中事件或逻辑是否预期工作。
用户界面测试XCUItests:测试用户与应用的UI交互(如点击按钮、滑动屏幕)。
性能测试XCPPerformanceTests:量化测试代码的性能并在代码更改后跟踪变化。
测试断言:XCTest提供断言API供验证结果(XCTAssertTrue()/XCTAssertFalse()/XCTAssertEqual() )。
集成和运行:可直接从Xcode工具的测试导航器运行(XCTest集成在Xcode中)。
测试报告:Xcode为执行的XCTest测试生成详细的测试报告。
1.创建Native项目包时伴随创建测试(环境)或通过‘测试导航’菜单>
2.测试(环境)文件夹 xxTests/xxUITests
3.环境下测试文件的在这里插入代码片
具体分析
// 自动化测试 环境
// KeepThreadAliveTests.m
// KeepThreadAliveTests
//
// Created by haijunyan on 2023/12/9.
//
#import <XCTest/XCTest.h>
@interface KeepThreadAliveTests : XCTestCase
@end
@implementation KeepThreadAliveTests
- (void)setUp {
//setUp当前测试类初始化事件(首先被调用)(资源准备)
}
- (void)tearDown {
//tearDown销毁事件(资源的清理销毁/最后被调用)
}
- (void)testExample {
//测试用例函数(功能测试用例)
//XCTAssert断言/相关函数验证结果
}
- (void)testPerformanceExample {
//性能测试函数(性能测试用例)
//量化块measureBlock的IMP被默认执行10次并输出对应的耗时报告
//IMP耗时报告
[self measureBlock:^{
}];
}
//测试函数:1.void 2.‘-’实例事件且无入参3.test开头
//自定义测试函数的执行顺序:与函数名中test后字符码大小有关(如 -(void)test001XXX先于-(void)test002XXX 执行)
//运行测试环境快捷键:CMD + U
//断言API(系统提供且可供调用)
//XCTFail(format…)生成一个失败的测试
//XCTAssertNil(a1, format...)为空判断,a1为空时通过,反之不通过
//XCTAssertNotNil(a1, format…)不为空判断,a1不为空时通过,反之不通过;
//XCTAssert(expression, format...)当`expression`求值为 `TRUE`时通过
//XCTAssertTrue(expression, format...)当`expression` 求值为`TRUE`时通过
//XCTAssertFalse(expression, format...)当`expression` 求值为`False`时通过
//XCTAssertEqualObjects(a1, a2, format...)判断相等`[a1 isEqual:a2]`值为YES时通过,其中一个不为空时,不通过
//XCTAssertNotEqualObjects(a1, a2, format...)判断不等, `[a1 isEqual:a2]`值为 `False` 时通过
//XCTAssertEqual(a1, a2, format...)判断相等(`a1 == a2`是否返回一个`YES`)(当a1和a2是 C语言标量、结构体或联合体时使用,实际测试发现 `NSString` 也可以)
//XCTAssertNotEqual(a1, a2, format...)判断不等(当a1和a2是 C语言标量、结构体或联合体时使用)
//XCTAssertEqualWithAccuracy(a1, a2, accuracy, format...) 判断相等(`double`或`float`类型)提供一个误差范围,当在误差范围(`+/-accuracy`)以内相等时通过测试
//XCTAssertNotEqualWithAccuracy(a1, a2, accuracy, format...) 判断不等(`double`或`float`类型)提供一个误差范围,当在误差范围以内不等时通过测试
//XCTAssertThrows(expression, format...) 异常测试,当 `expression`发生异常时通过;反之不通过;
//XCTAssertThrowsSpecific(expression, specificException, format...)异常测试,当`expression`发生 `specificException` 异常时通过;反之发生其他异常或不发生异常均不通过
//XCTAssertThrowsSpecificNamed(expression, specificException, exception_name, format...) 异常测试,当`expression` 发生具体异常、具体异常名称的异常时通过测试,反之不通过
//XCTAssertNoThrow(expression, format…)异常测试,当`expression`没有发生异常时通过测试
//XCTAssertNoThrowSpecific(expression, specificException, format...)异常测试,当`expression`没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
//XCTAssertNoThrowSpecificNamed(expression, specificException, exception_name, format...) 异常测试,当`expression`没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
//代码覆盖率越高说明测试环境涉及的功能越全(测试质量保障)
//点击'editscheme',对应的tagart->test->codeCoverage
- (void)testAsync {
XCTestExpectation *except = [self expectationWithDescription:@"异步请求测试用例"];
// [self.viewModel requestData:^(BOOL success) {
// XCTAssertTrue(success);
//调用fulfill后,表示异步逻辑完成
// [except fulfill];
// }];
[self waitForExpectationsWithTimeout:10 handler:^(NSError * _Nullable error) {
}];
}
//测试(逻辑部分)几点建议:
//在编码时,要尽量按照MVVM的模式进行开发,相比MVC模式,MVVM的逻辑代码都封装在VM里面,更利于进行脱离UI的测试。可以设想,如果将逻辑方法都写在View或ViewController中,则执行测试用例时就不得不引入很多额外的页面UI组件。
//编写测试用例时,有3个核心点,即输入,输出和结果判定。通过输入来设置测试用例的初始状态,通过对输出的结果判定来决定测试用例是否通过
//编写的测试函数要尽量符合下面特性:功能单一,有输入有输出。
//函数有输入参数,没有返回值时,需要对输入的参数进行修改,则这种场景编写测试用例时,要判断的是执行函数操作后的原始变量是否符合预期。
//函数没有输入参数,没有返回值时,其作用只是执行一段逻辑操作,例如存储文件,修改文件等。这时我们可以修改下功能函数,在函数内返回操作成功或失败的结果,测试用例使用此结果来作为是否通过的标准。
@end
- (void)testLaunchPerformance {
//测试 启动时长性能
if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *)) {
//衡量启动应用所耗时长
[self measureWithMetrics:@[[[XCTApplicationLaunchMetric alloc] init]] block:^{
//IMP默认多次启动执行(查看每次时长,对比结果)
[[[XCUIApplication alloc] init] launch];
}];
}
}
备注:
单元测试