code

2017年11月15日 星期三

iOS test 1 - XCTest 概論

XCTest

XCTest是Xcode內建的Testing framework,有提供UITest / Unit Test,UI Test只能使用在ios 9以上的simulator/devices。

Unit test

最好用來測試MVC這三個components,或是你寫一個library也適合用unit test。

UI test

XCTest提供了recording功能,可以記錄測試者的動作來形成test cases。這聽起來是相當好的功能(不過試過了才知道好不好)。


Test Classes

test classes算是用來設定測試大分類,所有的test classes都是XCTestCase的subclasses。

一個xcode default產出的test class長這樣:
#import 

@interface MyMOMOTests : XCTestCase

@end

@implementation MyMOMOTests

- (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];
}

- (void)testExample {
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
}

- (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

其中setup() 和 tearDown()相當於 willTest() 和 didTest(),用ios viewcontroller的術語來說。

Serial Test Execution Flow

Test class中的每一個 test method測試時都會重新initialize 這個test class instance,所以setup() 和 tearDown() 都會重新跑一次。跑完所有的 setup -> method -> teardown triplets之後,這個Test class就算測試完畢,接著再跑下一個test class。

所以test flow是serial的

所以setup / tearDown 可以當作shared init/deinit function,對所有的methods來說。


寫測試methods

test class中的test method的function prototype是 不回傳值,也不接受參數的function,例如:


Async Operation Tests

前面說過test execution flow是serial的,所以遇到async operation test的話,XCTest framework會等待此async operation returns或是timeout,這邊要用到的是XCTestExpectation class

例如以下的code中,最後的waitForExpectationsWithTimeout 會被block住,直到前一行openWithCompletionHandler async operation結束。



這適合用來測試某個網頁或是API是否respond了


Performance Tests

這個會把你丟入的block (closure)跑十次,取mean 和 standard deviation,然後跟某個baseline profile 比較。

例如以下測試加法10次 (但是每次有個loop跑10000次加法):



所謂的baseline是記錄在device configuration,因為每個device的能力都不一樣。


XCTest Assertions

assertion的形式大概長這樣:




Code Coverage

XCode內建code coverage功能,應該是statement code coverage,不過一launch就會發現有些file已經有一點code coverage,即便沒寫任何的test cases,為何?因為宣告static variables等於在run test的時候一定會執行到,所以就會被記錄在有被cover到。


XCode會紀錄在test過程中被呼叫到的statement次數:



Test Automation

XCode有自己的CI server,之後用到再來筆記筆記


User Interface Testing

這是模擬user怎麼使用你的app 的過程,這是一個blackbox test。

UI Test依賴兩個framework:
1. XCTest
2. Accessibility

因為這是最近才加入的功能,所以需要較新的軟體環境:


主要用到以下三個XCTest中的classes:


UITest最好是用recording的方式(最下面toolbar的紅色錄影按鈕),這樣不用自己寫code之外,也可以知道怎麼使用UITest相關的classes:



當然UI Test也是可以做performance test。

不過這邊有個XCode 9 default打開的Main thread checker,會讓test crash,因為test是跑在non-main thread上,所以有用到UIKit的code都會被此checker擋住,丟出exception,這邊有詳細解釋所以在不改動code的前提下,可以先disable Main Thread Checker,這應該只影響到Test Scheme



疑難雜症1: 關於unicode

在UI Test recording的時候,會發生中文側錄的問題 (”UITest incompatible universal character"),只要手動把抓到的unicode @"\U..."改成@"\u..\u..." 即可,我不求甚解囉,不想管原因是啥,請看這篇blog解釋

其實如果沒有多國語言的問題的話(單一語言),直接在test case裡面寫中文就好。

1 則留言:

  1. XCTest is a framework provided by Apple for writing and running tests in Swift or Objective-C for iOS, macOS, watchOS, and tvOS applications. The Best Mouse It is tool for ensuring the reliability and correctness of software during development.

    回覆刪除