iOS 單元測試

參考鏈接
兩部分:
單元測試XCTest+OCMock+斷言;
UITests UI測試自動腳本錄制蜕依;

OCMock三方框架使用及下載
OCMock三方框架引入注意事項:iOS 添加OCMock.xcframework 靜態(tài)庫都即可

添加測試工程文件或假如三方庫文件時,必須先 運行啟動相應(yīng)的測試用例罗洗。

查看測試代碼覆蓋率
打開查看開關(guān)
測試用例創(chuà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包)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贞岭,一起剝皮案震驚了整個濱河市八毯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瞄桨,老刑警劉巖话速,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異讲婚,居然都是意外死亡尿孔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門筹麸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人雏婶,你說我怎么就攤上這事物赶。” “怎么了留晚?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵酵紫,是天一觀的道長告嘲。 經(jīng)常有香客問我,道長奖地,這世上最難降的妖魔是什么橄唬? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮参歹,結(jié)果婚禮上仰楚,老公的妹妹穿的比我還像新娘。我一直安慰自己犬庇,他們只是感情好僧界,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著臭挽,像睡著了一般捂襟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上欢峰,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天葬荷,我揣著相機與錄音,去河邊找鬼纽帖。 笑死宠漩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抛计。 我是一名探鬼主播哄孤,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吹截!你這毒婦竟也來了瘦陈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤波俄,失蹤者是張志新(化名)和其女友劉穎晨逝,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體懦铺,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡捉貌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了冬念。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趁窃。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖急前,靈堂內(nèi)的尸體忽然破棺而出醒陆,到底是詐尸還是另有隱情,我是刑警寧澤裆针,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布刨摩,位于F島的核電站寺晌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏澡刹。R本人自食惡果不足惜呻征,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罢浇。 院中可真熱鬧陆赋,春花似錦、人聲如沸己莺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凌受。三九已至阵子,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胜蛉,已是汗流浹背挠进。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留誊册,地道東北人领突。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像案怯,于是被迫代替她去往敵國和親君旦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 引言:因為之前工作中經(jīng)歷過幾次大的項目重構(gòu)和組件化嘲碱,所以陸陸續(xù)續(xù)學(xué)習(xí)了一些iOS單元測試相關(guān)的一些知識金砍,以下內(nèi)容是...
    RyanYuan閱讀 11,505評論 4 68
  • 前言: 對于單元測試來說,我想大部分同行麦锯,在項目中恕稠,很少會用到,也有一大部分扶欣,知道單元測試這個東西鹅巍,但是確切的說沒...
    麥穗0615閱讀 3,213評論 4 44
  • 由于只是一些簡單實用的東西,學(xué)學(xué)還是挺不錯的料祠。其實單元測試用的好骆捧,開發(fā)起來也會快很多。單元測試對于我目前來說髓绽,就是...
    iOS大咖閱讀 342評論 0 2
  • 由于只是一些簡單實用的東西凑懂,學(xué)學(xué)還是挺不錯的。其實單元測試用的好梧宫,開發(fā)起來也會快很多接谨。單元測試對于我目前來說,就是...
    閑云清煙閱讀 168評論 0 0
  • 由于只是一些簡單實用的東西塘匣,學(xué)學(xué)還是挺不錯的脓豪。其實單元測試用的好,開發(fā)起來也會快很多忌卤。單元測試對于我目前來說扫夜,就是...
    RasonWu閱讀 62,245評論 38 565