IOS --Xcode6單元測試

單元測試,又稱模塊測試。是針對程序模塊(軟件設計的最小單位)來進行正確性檢驗的測試工做。面向過程編程,一個單元就是單個程序;面向對象編程,程序最小單位是方法。
html

XCTest是Xcode內置的測試框架。同時,Xcode6新增XCTestExpectation和性能測試。
算法

xcode6建立一個新的工程後,項目會自動配置兩個group:一個是「工程名稱」group;另外一個是「工程名稱Test」group。它們分別對應兩個target,一個是運行的target,另外一個是測試的target。用戶使用Command+R編譯運行的target,使用Command+U編譯測試的target。express

在測試的group中,有一個工程名稱test.m文件,這個文件裏面包含一個XCTestCase類,裏面有四個方法:setUp、tearDown、testExample、testPerformanceExample。編程

XCTestCasexcode

xcode的單元測試包含在XCTestCase的子類中,組織測試的時候儘可能須要考慮實際的應用操做流程。session

setUp & tearDownapp

setUp方法在XCTestCase的測試方法調用以前調用。當所有測試結束以後調用tearDown方法。框架

- (void)setUp {
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}

setUp方法能夠在測試以前建立一些 在test case中須要用到的一些對象等。tearDown方法則在所有的test case執行結束後清理測試現場,釋放資源、刪除不用的對象等。
異步

功能測試函數

test case中的每個方法都是以test開頭,這樣容易辨別。方法中會執行斷言Assert來判斷這個測試是否經過。

- (void)testExample {
    // This is an example of a functional test case.
    XCTAssert(YES, @"Pass");
}

經常使用的XCTest斷言

XCTest會用到不少斷言,這裏列舉一部分。

基本測試

全部的斷言都是從最基本的這個斷言演化出來的:

XCTAssert(expression,format……)

若是expression(表達式)執行結果爲true的話,這個測試經過;不然,測試失敗,並在控制檯輸出後面的format字符串。

Bool測試

對於bool型的數據,或者只是簡單的bool型表達式,使用XCTestAssertTrue或XCTestAssertFalse。

相等測試

測試兩個值是否相等使用XCTAssert[NO]Equal

XCTAssertEqual(expression1,expression2,format……)

在處理double、float類型數據的對比時使用XCTAssert[Not]EqualWithAccuracy來處理浮點精度的問題。

nil測試

使用XCTAssert[Not]Nil來判斷給定的表達式值是否爲nil。

無條件失敗斷言

使用XCTFail測試無條件斷言

XCTFail(format……)

XCTFail,無條件的都是測試失敗。這個東東有什麼用處呢?在測試裏面有這麼個狀況,咱們定義了測試方法,可是沒有給出具體的實現,那麼咱們確定不會但願這個測試能順利經過。是的,XCTFail就是這個用途。通常被用做一個佔位斷言,等咱們的測試方法完善好了以後在換成最貼近咱們測試的斷言。再或者,在某些狀況下else了以後就是不該該出現的狀況,那麼這個時候能夠將XCTFail放在這個else裏面。

性能測試

性能測試能夠幫助開發者創建一個主要功能的基本性能基線,確保這些主要功能代碼和算法能在這個性能基線內完成。

XCTestExpectation

XCTestExpectation是xcode自帶的異步測試類。即如今測試能夠等待指定長度的時間,一直到某些條件符合的時候再開始測試,而不用再寫不少的GCD代碼控制。

要使用異步測試,首先用方法expectationWithDescription建立一個expection。

let expectation = expectationWithDescription("……")

以後在方法的最後添加方法waitForExpectationsWithTimeOut,指定等待超時的時間和指定時間內條件沒法知足時執行的closure。

waitForExpectationsWithTimeOut(10) {(error) in ……}

接下來就是在異步測試剩下的回調函數中告訴expectation條件已經知足。

expectation.fulfill()

若是在測試中有多個expectation,則每一個expectation都必須fulfill,不然測試不經過。

func testAsynchronousURLConnection(){
        let URL = NSURL(string: "http://www.baidu.com")!
        let expectation = expectationWithDescription("GET \(URL)")
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(URL, completionHandler: {(data, response, error) in
            expectation.fulfill()   // 告訴expectation知足測試了
            XCTAssertNotNil(data, "返回數據不該該爲空")
            XCTAssertNil(error, "error應該爲nil")
            if response != nil {
                var httpResponse: NSHTTPURLResponse = response as NSHTTPURLResponse
                XCTAssertEqual(httpResponse.URL!.absoluteString!, URL, "HTTPResponse的URL應該和請求URL一致")
                XCTAssertEqual(httpResponse.statusCode, 200, "HTTPResponse狀態碼應該是200")
                XCTAssertEqual(httpResponse.MIMEType as String, "text/html", "HTTPResponse內容應該是text/html")
            }
            else{
                XCTFail("返回內容不是NSHTTPURLResponse類型")
            }
        })
        task.resume()
        waitForExpectationsWithTimeout(task.originalRequest.timeoutInterval, handler: {error in
            task.cancel()
        })
    }

總結

xcode內置工具已經很好了,即便很大的app也沒有必要爲了單元測試的代碼覆蓋率而排斥xcode內置工具。即不管怎麼樣的測試,XCTest的各類斷言、expectation和性能測試都足以應付。

若是在測試IOS或者OS X的APP,開始爲自動添加的測試類添加一些斷言並按下Command+U。咱們就會發現xocde自帶的工具讓咱們測試很方便。


斷言測試

  1. 測試方法的要求:1>必須無返回值;2>以test開頭

  2. 測試方法執行的順序:以方法名中test後面的字符大小有關,例如:

    -(void)test001XXX會優於-(void)test002XXX執行

  3. 運行單元測試快捷鍵:Command+U

下面一共有18個斷言(SDK中也是18個)

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時,測試經過

XCTAssertEqual(a1,a2,format……)判斷相等,相等時測試經過

XCTAssertNotEqual(a1,a2,format……)判斷不等,不等時測試經過

XCTAssertEqualObjescts(a1,a2,format……)判斷相等,[a1 isEqual:a2]值爲True時經過,其中一個爲空時不經過。

XCTAssertNotEqualObjescts(a1,a2,format……)判斷不等,[a1 isEqual:a2]值爲False時經過

XCTAssertEqualWithAccuracy(a1,a2,accuracy,format……)判斷相等,(double或float類型)提供一個偏差範圍,在偏差範圍(+/-accuracy)之內相等時測試經過。

XCTAssertNotEqualWithAccuracy(a1,a2,accuracy,format……)判斷不等,(double或float類型)提供一個偏差範圍,在偏差範圍(+/-accuracy)之內不等時測試經過。

XCTAssertThrows(expression,format……)異常測試,當expression發生異常時經過,反之不經過

XCTAssertNotThrows(expression,format……)異常測試,當expression沒有發生異常時經過,反之不經過

XCTAssertThrowsSpecific(expression, specificException, format...) 異常測試,當expression發生specificException異常時經過;反之發生其餘異常或不發生異常均不經過

XCTAssertNoThrowSpecific(expression, specificException, format...)異常測試,當expression沒有發生具體異常、具體異常名稱的異常時經過測試,反之不經過

XCTAssertThrowsSpecificNamed(expression, specificException, exception_name, format...)異常測試,當expression發生具體異常、具體異常名稱的異常時經過測試,反之不經過

XCTAssertNoThrowSpecificNamed(expression, specificException, exception_name, format...)異常測試,當expression沒有發生具體異常、具體異常名稱的異常時經過測試,反之不經過

舉例子應用

//1.比較基本數據類型

XCTAssertEqual(1,2,@"a1 = a2 shoud be true");//測試沒經過

XCTAssertEqual(1,1,@"a1 = a2 shoud be true");//測試經過

//2.若是a1,a2是指針,則當他們指向同一個對象時纔會返回YES,以下:

NSArray *array1 = @[@1];

NSArray *array2 = @[@1];

NSArray *array3 = array1;

XCTAssertEqual(array1,array2,@"a1 and a2 shoulid point to the same object");//測試不經過

XCTAssertEqual(array1,array3,@"a1 and a2 shoulid point to the same object");//測試經過

//3.要注意使用NSString

NSString *str1 = @"1";

NSString *str2 = @"2";

NSString *str3 = str1;

XCTAssertEqual(str1,str2,@"a1 and a2 shoulid point to the same object");//測試經過

XCTAssertEqual(str1,str3,@"a1 and a2 shoulid point to the same object");//測試經過

儘管str1與str2指向不一樣的對象,可是兩者的指針比較依然經過了測試。因爲str1與str2指向同一個常量,常量在data段中地址是固定的,因此兩者地址相同。

相關文章
相關標籤/搜索