參考鏈接
兩部分:
單元測試XCTest+OCMock+斷言;
UITests UI測試自動腳本錄制蜕依;
OCMock三方框架使用及下載
OCMock三方框架引入注意事項:iOS 添加OCMock.xcframework
靜態(tài)庫都即可
添加測試工程文件或假如三方庫文件時,必須先 運行啟動相應(yīng)的測試用例罗洗。
測試用例
1棺克、測試一個工具類
例如一個工具類,有3個功能朝抖,分別是將后臺返回的分為單位轉(zhuǎn)化成元糊闽、將本地元單位轉(zhuǎn)化成分梳玫,以及人民幣運算--加減乘除。測試用例如下:
#import <XCTest/XCTest.h>
#import "BFDecimalCalculator.h"
@interface BFDecimalCalculatorTests : XCTestCase
@property (nonatomic, strong)BFDecimalCalculator *decimalCalculator;
@end
// XCTest提倡一條測試用例盡量只模擬一種情況
// 單元測試不影響程序代碼(私有方法的測試 不建議右犹;建議建立一個分類 暴露給測試類)
// 優(yōu)點:跳過冗長的工程運行及手動點擊
@implementation BFDecimalCalculatorTests
- (void)setUp {
[super setUp];
self.decimalCalculator = [BFDecimalCalculator shareInstance];
}
- (void)tearDown {
[super tearDown];
}
- (void)testFunc_convertCentsIntoYuan {
XCTAssertEqualObjects([self.decimalCalculator convertCentsIntoYuan:@"756"], @"7.56");
}
- (void)testFunc_convertYuanIntoCents {
XCTAssertEqualObjects([self.decimalCalculator convertYuanIntoCents:@"235.35"], @"23535");
}
// 加法測試用例
- (void)testDecimalCalculateAddingCase {
NSString *result = [self.decimalCalculator calculateNumOne:@"100" numTwo:@"150" calculationType:BFDecimalCalculatorCalculationTypeAdding scale:2 roundingMode:BFDecimalCalculatorRoundingModeTypeRoundDown];
XCTAssertEqualObjects(result, @"2.00");
}
// 減法測試用例
- (void)testDecimalCalculateSubtractingCase {
}
// 乘法測試用例
- (void)testDecimalCalculateMultiplyingCase {
}
// 除法測試用例
- (void)testDecimalCalculateDividingingCase {
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
@end
2提澎、OCMock測試
當(dāng)被測試的對象涉及到外界多重依賴時,就需要mock相應(yīng)的數(shù)據(jù)念链。例如統(tǒng)計兩個學(xué)生的分數(shù)盼忌,需要傳入兩個學(xué)生model积糯,這個時候就要依賴student這個模型。詳細查看如下測試用例碴犬,里面也包含了異步測試和性能測試 具體如何使用絮宁。
#import <XCTest/XCTest.h>
#import "Teacher.h"
#import "Teacher+Test.h"
#import <OCMock/OCMock.h>
/* 測試框架
方案一:XCTest + OCMock(mock對象、樁程序)+ OCHamcrest(斷言擴展服协,非必要)
方案二:Kiwi
*/
/* 主要測試對象
網(wǎng)絡(luò)請求或數(shù)據(jù)重構(gòu)方法
工具類公共方法绍昂;
部分可測試視圖邏輯;
私有方法(若有測試必要可創(chuàng)建類拓展進行測試)
*/
@interface TeacherTests : XCTestCase
@property (nonatomic, strong)Teacher *teacher;
@end
@implementation TeacherTests
- (void)setUp {
[super setUp];
Teacher *tt = [[Teacher alloc] init];
self.teacher = tt;
}
// 公共方法測試
- (void)testFunc_sumStudentsGrade {
float sumGrade = [self.teacher sumStudentsGrade:80 gradeTwo:90];
XCTAssertEqual(sumGrade, 170);
}
// OCMock 依賴外部對象的單元測試 TODO: OCMock進一步深入研究
- (void)testFunc_sumStudentsModelGrade {
// mock Student對象偿荷,當(dāng)調(diào)用grade的get方法時窘游,我們指定返回結(jié)果
Student *mockStu1 = OCMClassMock([Student class]);
OCMStub([mockStu1 grade])._andReturn(OCMOCK_VALUE(90));
Student *mockStu2 = OCMClassMock([Student class]);
OCMStub([mockStu2 grade])._andReturn(OCMOCK_VALUE(100));
// 調(diào)用被測方法
float sumGrade = [self.teacher sumStudentsModelGrade:mockStu1 gradeTwo:mockStu2];
// 使用斷言判斷結(jié)果
XCTAssertEqual(sumGrade, 190);
}
// 私有方法測試
- (void)testFunc_privateMethodAndReturnTrue {
BOOL testBool = [self.teacher privateMethodAndReturnTrue];
XCTAssertEqual(testBool, YES);
}
// 異步測試
- (void)testExpectation {
// 參數(shù) |description| 超時錯誤提示,異步操作時間超過了預(yù)設(shè)時間時才會在Log中打印出來跳纳。
XCTestExpectation *expect = [self expectationWithDescription:@"timeout!"];
// 這里我們用一個異步執(zhí)行來模擬網(wǎng)絡(luò)請求回調(diào)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(2); //延遲兩秒向下執(zhí)行
XCTAssertTrue(YES); //通過測試
// 該方法用于表示這個異步測試結(jié)束了忍饰,每一個XCTestExpectation對象都需要對應(yīng)一個fulfill,否則將會導(dǎo)致測試失敗
[expect fulfill]; //告知異步測試結(jié)束
});
[self waitForExpectationsWithTimeout:10 handler:^(NSError *error) {
// 等待10秒寺庄,若該測試未結(jié)束(未收到 fulfill方法)則測試結(jié)果為失敗
// Do something when time out
}];
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
// 性能測試 被測試代碼放入block中即可
- (void)testPerformance_sumStudentsGrade {
// This is an example of a performance test case.
[self measureBlock:^{
float sum = [self.teacher sumStudentsGrade:80 gradeTwo:90];
XCTAssertEqual(sum, 170);
}];
}
@end
UITests UI測試自動腳本錄制
如下圖艾蓝,定位到某個測試方法里,可以看到底部小紅圈斗塘,點擊即可開始錄制赢织。再一次點擊紅圈 或停止運行結(jié)束腳本錄制。
如下操作開始測試馍盟,一般會自動測試10次
總結(jié)點
注意點
- 測試用例文件命名規(guī)則為 XXXTests
- 測試用例里面 具體測試方法命名規(guī)則為 test類_方法
- XCTest提倡一條測試用例盡量只模擬一種情況
- 單元測試不影響程序代碼(私有方法的測試 不建議于置;建議建立一個分類 暴露給測試類)
優(yōu)點
- 跳過冗長的工程運行及手動點擊
缺點
- 編寫測試用例時間 工期會稍微變長
- 項目源碼增加 (只是項目源碼,不會影響ipa包)