使用背景
1.為了更快、更高效的開發, 開發過程中經常要寫一些測試用例。 2.在開發過程中,有些很深的介面,需要滿足很多條件、造很多假資料才可以進入的,但是前面那些介面我們根本就沒有涉及修改,只是想進入最後這個介面;比如:訂單支付完成介面。 這時候我們可以寫測試用例,直接讓其進入到想要進入的介面。
測試用例分為:單元測試和UI測試。 Xcode自帶了測試用例檔案。一般大的專案以及優秀的開源庫都有測試用例的,比如:AFNetworking。 不會寫的可以到這下載AFNetworking原始碼參考。
建立測試用例
1.新建工程檔案,勾選測試用例
如果忘記勾選了, 也可以通過新建來建立。 和新建檔案一樣。2.新建完的工程 測試用例和其他工程檔案,分別屬於不同的target。
3.測試用例檔案 新的的測試用例檔案,都是這個結構和基本的四個方法。
#import <XCTest/XCTest.h>
@interface XcodeTestsTests : XCTestCase
@end
@implementation XcodeTestsTests
/*!
* @brief 初始化方法。
* 初始化、程式碼複用、準備測試條件
*/
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
/*!
* @brief 銷燬方法
* 每次測試用例跑完,都會跑這個方法,釋放物件、回收資源、避免干擾
*/
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
/*!
* @brief 測試用例方法
* 注意: 這裡方法必須以test開頭,不然識別不了。
* 開始測試用例方法,cmd+u 或者直接點選右側這個小框箭頭即可
*/
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
/*!
* @brief 效能測試方法
* 可以測試某一段方法的效能、耗時情況
*/
- (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
複製程式碼
寫測試用例基本都在testExample
方法裡完成。
注意:問題點
寫了一個最簡單的測試用例,執行不起來, 執行報錯:-[UIApplication applicationState] must be used from main thread only
。控制檯報錯資訊:Main Thread Checker: UI API called on a background thread: -[UIApplication applicationState]
解決辦法: 開啟Xcode的Edit Scheme, 找到Test選項,去掉Runtime Api 檢測選項即可。
以上正常情況下就可以執行了。 下面我們開始寫一個簡答的測試用例。
寫測試用例
測試用例的過程一般分三步,這裡以測試ViewController的一個加方法為例:
- 在VC裡暴露介面:
/*!
* @brief 暴露介面
* 暴露介面這裡很重要,很有技術含量。
* 儘可能的暴露少的資訊來完成測試用例
*/
- (NSInteger)addFunction:(NSInteger)a andB:(NSInteger)b;
複製程式碼
然後實現方法:
- (NSInteger)addFunction:(NSInteger)a andB:(NSInteger)b {
return a + b;
}
複製程式碼
2.在測試用例裡匯入標頭檔案#import "ViewController.h"
以及初始化物件,準備測試條件。
3.開始測試方法
- (void)testAddFunction {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
//1.建立測試條件
NSInteger a = 1, b = 2;
//2.進行測試,直接呼叫測試方法
NSInteger sam = [self.VC addFunction:a andB:b];
//3.斷言。斷言方法有N多種,詳細見下面。 測試最核心。
XCTAssertEqual(sam, 3); //前面這個是測試條件,後面的值是我們期望的值。 如果是正確的就測試通過,否則直接掛掉。
}
複製程式碼
斷言一覽表:
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]值為TRUE時通過,其中一個不為空時,不通過;
XCTAssertNotEqualObjects(a1, a2, format...)判斷不等,[a1 isEqual:a2]值為False時通過;
XCTAssertEqual(a1, a2, format...)判斷相等(當a1和a2是 C語言標量、結構體或聯合體時使用, 判斷的是變數的地址,如果地址相同則返回TRUE,否則返回NO);
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沒有發生具體異常、具體異常名稱的異常時通過測試,反之不通過
複製程式碼
非同步測試
舉一個最簡答的例子:進入到具體介面裡的的方法:
//這裡就直接定義一個字串,假如出現異常,就直接丟擲這個字串
XCTestExpectation *ex = [self expectationWithDescription:@"這裡應該得進到訂單完成介面"];
OrderPayDoneViewController *controller = [[OrderPayDoneViewController alloc] initWithNibName:nil
bundle:nil];
//這裡就是訂單完成介面需要的屬性,可以隨便造假資料
controller.orderId = @"這是訂單 ID";
controller.isPaidSuccess = YES;
controller.orderAmount = @"23456";
controller.payMethod = @"Paypal";
controller.displayAmount = @"$11.8.0";
[CurrentViewController().navigationController pushViewController:controller
animated:YES];
//下面這兩個方法就是XCTestExpectation的API
[ex fulfill]; //這個方法不懂, 不寫也可以呼叫
[self waitForExpectations:@[ex] timeout:1000000];//這個不呼叫不能跳轉
複製程式碼
單元測試
單元測試內容很多,還需要更多的研究,測試也很重要,對於開發對於測試都很重要,多多學習下單元測試吧。
後續
UI測試,可以自動進行測試。最基本的註冊登入流程等常規,可以跑UI測試。。 內容比較多, 後續繼續研究補充。