摘要:返回到并把應用停下來測試前操作在項目瀏覽器中,展開項目。如果在這段時間內預期的東西沒有顯示,測試就宣告失敗。點擊或者運行測試。但是作為其他測試的一部分更有效。測試運行器是不會自動運行它的。
用戶期待iOS應用的高水準用戶體驗,因而你需要設計、開發和測試你的應用來滿足這一不斷上升的期望。為了達成這個目標,你會投入多少時間進行原始人工的用戶界面測試?你知道這活兒怎么干…從Xcode啟動你的應用,并不斷的用手指點擊同一些按鈕來確保你的設計中沒有退步。相比這些,你當然更愿意做其它一些事情?
考慮下使用Xcode 5中增強的UI測試,還有?OS X Server中支持的持續集成?這篇文章展示了蘋果公司為開發者貢獻的最好的工具。
你也許會說,這很棒,但是如何讓那些簡單的用戶動作測試變得自動化呢,例如確保一個在合適區域的雙擊或觸摸后會進入正確的視圖?即使是測試腳本和機器人也不會有能在屏幕上滑動的電容式觸摸手指…呃…它們有手指么?
在這篇教程中,你將會學習到一些有關?KIF?的東西(Keep it Functional), 它是一個開源的用戶界面測試框架. 使用 KIF, 并利用?iOS中的輔助功能?API, 你將能夠編寫模擬用戶輸入(例如點擊、觸摸和文本輸入)的測試。
它提供自動化的、真實的用戶界面操作, 幫助放松你的心情,因而你就可以只去關注自己的殺手級應用了,而不是在UI測試上耗費你職業生涯的一半時間。
讓我們開始測試工作吧!
入門我們以一個叫做茄薯Solanum(一個馬鈴薯品種的名字)的計時器應用為例。這是一個基于番茄工作法的應用。
它是這么運作的:
按照設定好的時間工作,接著休息一下,然后重復工作和休息.
經過這樣若干個循環之后, 你就會休息一段更長的時間.
這個應用就是一個能夠持續跟蹤時間區段的簡單計時器。
這款應用之后能使你的開發工作變得更加高效!
從?這里?下載并解壓縮入門項目.注意?KIF 是一個獨立的項目,它是為茄薯應用構建一個用于測試目標的庫。因此你需要雙擊?solanum.xcworkspace?以便在Xcode中打開項目,而不是?solanum.xcodeproj。在項目導航視窗中找到這兩個項目,如下圖所示:
將應用的目標設置到solanum,然后選擇3.5或者4英寸的iPhone模擬器目標。不要使用64位,因為KIF在64位模擬器上有一些問題。構建并運行這個應用。四處瞧瞧,了解一下,然后切換到Settings。
應用有一個能夠加速時間流逝的調試模式。因此你可以設置一個20分鐘的計時器,測試時花10秒完成這個過程。這只是為了幫助你測試應用,你應該不會想花20分鐘等著看它運行吧。
開啟調試模式來加速計時器,接著點擊Clear History按鈕,然后在確認彈出視圖上點擊Clear。這幾步確保了你是在一個干凈的環境中開始測試作業。返回到Xcode并把應用停下來.
測試前操作在項目瀏覽器中,展開solanum項目。 右擊UI測試文件夾并點擊New File…來加入你的新測試用例。
選擇?iOSCocoa TouchObjective-C class?并點擊?Next, 將類命名為?UITests?并使其成為?KIFTestCase 的子類。
點擊Next并確保文件已經被添加到UI Tests目標中, 而不是 solanum 目標。 然后點擊接下來Create保存文件.
KIFTestCase是SenTestCase的一個子類. 那意味著你擁有了大部分的標準 OCUnit 測試方法和機制可以使用,如果你已經很熟悉單元測試的話。
打開UITests.m,并在@implementation?一行添加如下的方法:
- (void)beforeAll { [tester tapViewWithAccessibilityLabel:@"Settings"]; [tester setOn:YES forSwitchWithAccessibilityLabel:@"Debug Mode"]; [tester tapViewWithAccessibilityLabel:@"Clear History"]; [tester tapViewWithAccessibilityLabel:@"Clear"]; }
beforeAll?是一個在所有測試運行之前被調用一次的特殊方法。你可以為你這里運行的測試設置任何實體變量和初始化條件.
tester?對象是指定的KIFUITestActor?類的一個縮略名稱。這個類包含了模擬用戶動作的方法,包括觸摸和滑動.
tapViewWithAccessibilityLabel 這也許是最常被用到的測試動作方法。正如其名稱所顯示的,它可以在給定的輔助標簽模擬在視圖上的觸擊。在大多數情況下,輔助標簽和可視的文本標簽(例如按鈕組件)是配套的。否則你就需要手動設置輔助標簽.
一些控件,諸如?UISwitch,更加復雜,需要比簡單的觸擊更復雜的步驟來觸發。 KIF 提供了一個特殊的?setOn:forSwitchWithAccessibilityLabel:?方法來改變一個切換的狀態.
總之,這個方法對測試動作進行了四步操作:
觸擊“Settings” 選項卡按鈕條.
將 “調試模式Debug Mode” 切換到它的“開啟”狀態.
觸擊 “Clear History” 按鈕.
在UIAlertView上觸擊“Clear”按鈕.
這步看起來很眼熟? 應該是熟悉的! 它們就是之前章節中你手動進行的操作!
點擊Product Test菜單或者使用Command-U運行測試。應用開始運行,然后KIF接手,自動開啟調試模式并清除歷史記錄.
如果你啟用了通知,Xcode將告知你測試的狀態:
有時候測試運行器或者說KIF可能會有一點挑剔,拒絕運行測試,你只能看到一個空白的模擬器屏幕。如果遇到這樣的情況,那么:
清理一下項目(ProductClean)
構建并運行
等待應用啟動
在Xcode中終止應用的運行
這一過程確保了模擬器正在運行,并且你正在最新的構建上進行操作。經過上面的幾步之后,試試再一次運行測試。問題應該會消失
如果問題依然存在, 你可以參考?KIF 故障排除步驟。
現在你已經在?beforeAll 中有了一個測試前置動作, 是時候加入你的第一個測試了!
一個簡單的測試:隨處點擊該應用程序有一個標準的選項卡界面,三個選項卡中,每一個都使用了UINavigationController。先做個熱身吧,測試一下:
故事版被適當地連接起來
選項卡展示正確的視圖
選項欄按鈕自動地設置成類似文本標簽這樣的輔助標簽,所以KIF可以通過設置選項欄中的“歷史”、“定時器”、“設置”標簽找到歷史、計時器和設置。
歷史選項卡有一個顯示所有定時器執行任務的表視圖。從solanum組里打開HistoryViewController.m,在viewDidLoad末尾處添加以下幾行:
[self.tableView setAccessibilityLabel:@"History List"]; [self.tableView setIsAccessibilityElement:YES];
這樣,表視圖的輔助標簽就設置好了,KIF能夠找到它。通常情況下,一個表視圖僅在空的情況下才能被訪問。表視圖的單元格有可能被當做是一個目 標,所以表視圖它本身會被藏在輔助功能的API之下。基本上,輔助功能的API在默認情況下假定表視圖是不重要的。就輔助本身而言,這是合理的。不過如果你可能想在KIF中引用表視圖,那么可以使用setIsAccessibilityElement:,它確保表視圖始終是可訪問的,不管其是否有內容。
對于使用輔助功能的用戶來說,非空的表格視圖可以訪問會使操作復雜化。在你的應用中,你可以把相應的代碼包裹在#ifdef DEBUG和#endif指令之間,這樣這些代碼就只會被編譯到調試構建中。DEBUG預處理器宏已經在Xcode項目模板中被提前定義好了。
Timer 選項卡有一些控件,而“任務名稱”文本框放在了視圖的頂部,以方便用戶使用。你無需通過代碼來設定標簽,只需可以打開?Main.storyboard?并找到Timer View Controller視圖. 選擇task name text field#。
打開Utilities,選擇Identity Inspector。提示:從左邊數第三個圖標, 或者使用快捷鍵``? ? 3`。
在inspector的Accessibility下,Label一欄中輸入Task Name。小心,這是大小寫敏感的。確保輸入了大寫的 T 和 N!
Settings 面板已經設置好了視圖的輔助標簽,你可以進行下一步操作了!
在你自己的項目中,你將需要繼續填寫輔助標簽,你可以通過代碼,也可以通過上述 Interface Builder的方式。為了方便,示例應用余下來的選項已經設置好了。
回到?UITests.m, 在beforeAll之后加入這個方法:
- (void)test00TabBarButtons { // 1 [tester tapViewWithAccessibilityLabel:@"History"]; [tester waitForViewWithAccessibilityLabel:@"History List"]; // 2 [tester tapViewWithAccessibilityLabel:@"Timer"]; [tester waitForViewWithAccessibilityLabel:@"Task Name"]; // 3 [tester tapViewWithAccessibilityLabel:@"Settings"]; [tester waitForViewWithAccessibilityLabel:@"Debug Mode"]; }
測試運行器會在運行時尋找所有以test開頭的方法, 然后按字母順序運行它們。這個方法以test00開頭,因此它會在你之后加入的方法之前運行,那些是以諸如test10、test20這樣的名字開頭的。
這些方法會進行類似一些動作: 觸擊標簽欄,檢查期望的視圖是否被顯示在屏幕上。waitForViewWithAccessibilityLabel:默認的超時時間是10秒。如果在這段時間內預期的東西沒有顯示,測試就宣告失敗。
點擊?ProductTest?或者 Command-U 運行測試。你會注意到beforeAll中的步驟會清除掉歷史記錄,接著test00TabBarButtons會接管并按順序切換到歷史、定時器和設置標簽。
哈哈,你看到了嗎?你只是編寫并運行了一個接口測試, 就會看到你的小應用自己在“啟動”了!恭喜了! 你正在掌握自動化UI測試的旅途上。
用戶輸入當然,切換標簽很棒,不過我們也該關注一下更加真實的動作:輸入文本,觸發模式對話框,以及選中表視圖中的一行。
測試應用中內置了更改工作時間、休息時間、推薦的重復次數的預設功能。如果你很好奇,想查看他們的定義,那么可以瀏覽一下PresetsViewController.m中的presetItems。
每個預設本身就可以成為一個測試。但是作為其他測試的一部分更有效。因此我們把它獨立出來成為一個輔助方法。
把以下的方法添加到UITests.m的實現模塊中去:
- (void)test00TabBarButtons { // 1 [tester tapViewWithAccessibilityLabel:@"History"]; [tester waitForViewWithAccessibilityLabel:@"History List"]; // 2 [tester tapViewWithAccessibilityLabel:@"Timer"]; [tester waitForViewWithAccessibilityLabel:@"Task Name"]; // 3 [tester tapViewWithAccessibilityLabel:@"Settings"]; [tester waitForViewWithAccessibilityLabel:@"Debug Mode"]; }
這里的第一步是切換到計時器標簽,然后觸擊導航欄中的預設按鈕。當“預設列表”表視圖出現的時候,觸擊指定的一行。
觸擊行會導致視圖控制器會消失,所以要用waitForAbsenceOfViewWithAccessibilityLabel:來保證它在你繼續下一步之前已經消失了。
你注意到了嗎?這個方法不是以test為開頭的。測試運行器是不會自動運行它的。你需要在測試中手動調用這個方法。
現在,添加以下測試方法到UITests.m:
- (void)test10PresetTimer { // 1 [tester tapViewWithAccessibilityLabel:@"Timer"]; // 2 [tester enterText:@"Set up a test" intoViewWithAccessibilityLabel:@"Task Name"]; [tester tapViewWithAccessibilityLabel:@"done"]; // 3 [self selectPresetAtIndex:1]; // 4 UISlider *slider = (UISlider *)[tester waitForViewWithAccessibilityLabel:@"Work Time Slider"]; STAssertEqualsWithAccuracy([slider value], 15.0f, 0.1, @"Work time slider was not set!"); }
KIF測試操作有可讀性很好的名字,看看你能不能發現接下來會發生什么?把它看成是一個……測試!沒錯,我故意用了雙關語。
好的,這就是實際發生的步驟:
切換到計時器標簽。
?在“任務名”輔助標簽的文本框中輸入“Set up a test”(記住,你之前添加了這個標簽到面板中)。觸擊“Done”按鈕來關閉鍵盤。
請求輔助方法來選擇第二個預設。
選擇預設會改變滑動器的值,所以要確保它確實更改為正確的值。
在代碼最后一部分,你會發現一個有用的技巧:waitForViewWithAccessibilityLabel:。它不僅僅可以等待視圖出現,還可以返回一個指針到視圖中去。這樣,你可以將返回值類型轉換成UISlider,以便匹配適當的類型。
由于KIF測試用例也是常規的OCUnit測試用例,因此你可以調用標準的STAssert斷言宏。斷言是運行時的檢查項,如果某些條件不滿足,斷言會導致測試失敗。最簡單的斷言是STAssertTrue,用來判斷傳入參數是否為true。
STAssertEquals會檢查傳入的前兩個參數是否相等。滾動條的值是float類型,所以要注意匹配他們的類型。因此,在斷言里我們使用15.0f。此外,你還需要注意浮點數的誤差,這是因為浮點數的值不可能是100%精確的。比如說,15.0實際上可能被存儲為 15.000000000000001。所以STAssertEqualsWithAccuracy是一個更好的選擇,它的第三個參數指定偏差范圍。在這種情況下,如果該值的誤差在-0.1到+0.1之間,斷言仍然能通過。
用Command-U運行測試。你會看到這三個序列:beforeAll清除歷史記錄,test00TabBarButtons在每個標簽間切換,最后的是test10PresetTimer,輸入一個任務名并選擇一個預設。
這是另一個成功的測試用例!此時,你的測試模仿用戶的觸擊,甚至鍵盤輸入,但是還有更多驚喜在后頭!
啟動定時器下面給出一個例子,定時循環跑一個應用程序,應用的用戶可能選擇:工作8分鐘,休息2分鐘,工作8分鐘,休息2分鐘,最后工作8分鐘。接下來是一個較長的休息。然后再重新啟動應用程序。
以上例子的參數是:
工作時間:8分鐘
休息時間:2分鐘
重復次數:3
接下來的KIF測試需要輸入這些參數,然后點擊“開始工作”按鈕來啟動定時器。添加以下的方法到UITests.m,直接加在你之前添加的測試之后:
- (void)test20StartTimerAndWaitForFinish { [tester tapViewWithAccessibilityLabel:@"Timer"]; [tester clearTextFromAndThenEnterText:@"Test the timer" intoViewWithAccessibilityLabel:@"Task Name"]; [tester tapViewWithAccessibilityLabel:@"done"]; [tester setValue:1 forSliderWithAccessibilityLabel:@"Work Time Slider"]; [tester setValue:50 forSliderWithAccessibilityLabel:@"Work Time Slider"]; [tester setValue:1 forSliderWithAccessibilityLabel:@"Work Time Slider"]; [tester setValue:8 forSliderWithAccessibilityLabel:@"Work Time Slider"]; [tester setValue:1 forSliderWithAccessibilityLabel:@"Break Time Slider"]; [tester setValue:25 forSliderWithAccessibilityLabel:@"Break Time Slider"]; [tester setValue:2 forSliderWithAccessibilityLabel:@"Break Time Slider"]; }
因為這個測試會在test10PresetTimer(這個測試會設置任務名)后立刻運行,你可以使用clearTextFromAndThenEnterText:intoViewWithAccessibilityLabel:,而不是使用enterText:intoViewWithAccessibilityLabel:清除任何現存的文本。
最后,這里有幾個setValue:forSliderWithAccessibilityLabel:調用。這是UISlider指定的給新變量賦值的方法。注意,并不總是很精確。KIF實際上是模擬觸擊事件去設置新的值,有時候像素的計算會有所偏差。不過這沒什么大問題,因為我們的手指也不是特別精確!
你僅需要設置每個滾動條的值一次。多次的調用僅僅是為了反復,所以你會看到KIF不停地更改值。
使用Command-U運行測試。
剩下的UI測試是在UIStepper控制器中設置重復的次數,還有“開始工作”按鈕。“開始工作”按鈕很簡單——你可以使用tapViewWithAccessibilityLabel:模擬觸擊。但對于UIStepper來說,我們需要采用一些迂回策略。
定制觸擊如下圖所示,UIStepper控制器分為兩部分,因此,如果你僅僅調用tapViewWithAccessibilityLabel:,很難確定會發生什么。
KIF會開始嘗試觸擊控制器的中心。如果它是一個不可觸擊的區域,它會接下來嘗試點擊左上角、右上角、左下角、右下角。結果顯示,觸擊+、-之前的分界線會觸發+,所以它會不斷地增加重復次數。
但是如果你想減少次數呢?有一些變通的方法的,例如深入子視圖找到減號的按鈕,另一種方法則是使用KIF的tapScreenAtPoint:測試操作,可以模擬觸擊屏幕上的任意點。
你對CGGeometry了解得如何?如何計算出+/-按鈕在窗口中的坐標?準備好來證明你的實力沒?為什么不接受這個挑戰呢?這完全是可選的, 你可以直接跳到下面去查看代碼和計算。但是,如果想測驗一下你的技能,可以嘗試在偷看答案之前先自己寫一下代碼。
請注意,你很快需要將下面的代碼添加到測試中,這個任務只是測試你的數學和CGGeometry能力。
首先,你需要引用UIStepper:
UIStepper *repsStepper = (UIStepper*)[tester waitForViewWithAccessibilityLabel:@"Reps Stepper"];
然后你可以找到中心點:
CGPoint stepperCenter = [repsStepper.window convertPoint:repsStepper.center fromView:repsStepper.superview];
UIStepper可以是在嵌套視圖內,而你真正想要的是UIStepper的中心點相對于整個窗口的坐標,因此需要調用convertPoint:fromView:。
現在,你得到了中心點相對于窗口的位置,你可以減少x軸的值來獲取到減號的按鈕,或者增加x軸來獲取加號的按鈕。
CGPoint minusButton = stepperCenter; minusButton.x -= CGRectGetWidth(repsStepper.frame) / 4; CGPoint plusButton = stepperCenter; plusButton.x += CGRectGetWidth(repsStepper.frame) / 4;
如果增加或者減少UIStepper寬度的1/4,就會正好到達加號、減號按鈕的中間位置。
瞧!這兩個點,相當于UIStepper控制器中的加號/減號按鈕的中心點。
觸擊屏幕的指定點是萬不得已的方法,但有時它是測試UI的唯一的方法。例如,你也許會有一個自行定制的控制器沒有實現UIAccessibility Protocol。
定時器收官好的,你已經到了定時器測試的最后一步了。你開始意識到用KIF做UI測試的潛力了么?很好!
最后的步驟是設置重復次數,然后啟動定時器。添加以下代碼到UITests.m中的test20StartTimerAndWaitForFinish的結尾:
// 1 UIStepper *repsStepper = (UIStepper*)[tester waitForViewWithAccessibilityLabel:@"Reps Stepper"]; CGPoint stepperCenter = [repsStepper.window convertPoint:repsStepper.center fromView:repsStepper.superview]; CGPoint minusButton = stepperCenter; minusButton.x -= CGRectGetWidth(repsStepper.frame) / 4; CGPoint plusButton = stepperCenter; plusButton.x += CGRectGetWidth(repsStepper.frame) / 4; // 2 [tester waitForTimeInterval:1]; // 3 for (int i = 0; i < 20; i++) { [tester tapScreenAtPoint:minusButton]; } [tester waitForTimeInterval:1]; [tester tapScreenAtPoint:plusButton]; [tester waitForTimeInterval:1]; [tester tapScreenAtPoint:plusButton]; [tester waitForTimeInterval:1]; // 4 [KIFUITestActor setDefaultTimeout:60]; // 5 [tester tapViewWithAccessibilityLabel:@"Start Working"]; // the timer is ticking away in the modal view... [tester waitForViewWithAccessibilityLabel:@"Start Working"]; // 6 [KIFUITestActor setDefaultTimeout:10]
這里介紹在最后階段中即將會發生什么:
上面的代碼尋找UIStepper的加號和減號按鈕的坐標。
waitForTimeInterval:調用增加了延時,這樣你可以看到步數值的變化——否則的話,對于肉眼而言,它的變化太快了。
這個步數的最大值是20,所以觸擊減號按鈕20次會把值恢復到1。然后觸擊加號按鈕2次(以最小的延時交替)把重復數字變為期望的值 3。
每個測試步驟默認的超時時間是10秒。即使在加速調試模式下,有可能20多分鐘長度的“工作”也需要超過10秒鐘時間完成,所以需要設置一個比較寬松的超時時間——60秒。
觸擊“開始工作”按鈕,它會彈出模式視圖控制器。當重復都結束后,模式視圖控制器會消失。這意味著你將返回定時器視圖控制器上,所以 等待“開始工作”按鈕再次出現其實是在等待模式視圖控制器消失。
重設超時時間為10秒。
一旦你保存文件,你會發現有方法聲明一側會出現一個小的棱形圖標:
這是一個運行單個測試的按鈕。因此,你可以在測試環境下只運行這個方法,而不需要運行整套測試用例。優雅!點擊菱形按鈕來運行這個測試,你會看到模擬器啟動,并運行測試用例。只要坐在一旁觀看它輸入任務名,滑動滾動條,以及定時器的時間流動就可以了。不用動一根手指,你就能測試UI了。
成功了!現在你可以成功設置測試,幫助你完成一系列UI控制器的操作。
如果你通過菱形按鈕跑單個測試,它只跑一個簡單的方法而不會在開頭調用beforeAll。如果你的測試是依賴于beforeAll的,你仍然需要跑整套完整的測試。
提前結束“去工作!”模式視圖控制器中有一個放棄按鈕可以讓用戶取消一個時間周期。你仍可以測量已經工作的分鐘,即使很早就結束了測試。這個數據仍然會被記錄到歷史上,但會被標記為整個周期沒有跑完。
你不用相信我的話,可以自己嘗試一下。只需做一些類似上述測試的東西。設置定時器的參數,觸擊*開始工作按鈕,然后觸擊放棄按鈕。
不要馬上觸擊“放棄”按鈕——定時器需要運作一段時間,應用程序才開始創建歷史記錄。所以,你可以將鼠標移動到測試上,手動停止測試。或者,你可以編程設定它在你選定的時間和位置。如果你生性猶豫,你可以跳過這個挑戰。然而,如果你喜歡編寫應用去幫你處理各種雜事,就試一下吧!你知道如何在“開始工作”和“放棄工作”之間增加一點延時么?
你可以調用waitForTimeInterval:在你的測試里增加延時。
在UITests.m中添加下列的測試方法,加在其他測試的下面:
- (void)test30StartTimerAndGiveUp { [tester tapViewWithAccessibilityLabel:@"Timer"]; [tester clearTextFromAndThenEnterText:@"Give Up" intoViewWithAccessibilityLabel:@"Task Name"]; [tester tapViewWithAccessibilityLabel:@"done"]; [self selectPresetAtIndex:2]; [tester tapViewWithAccessibilityLabel:@"Start Working"]; [tester waitForTimeInterval:3]; [tester tapViewWithAccessibilityLabel:@"Give Up"]; [[tester usingTimeout:1] waitForViewWithAccessibilityLabel:@"Start Working"]; }
在確保你位于正確的選項卡之后,設置任務名然后選擇好預設。然后啟動定時器,在放棄之前等待3秒。
方法的最后一行等待模式視圖控制器消失,返回主界面。記住,默認的超時時間是10秒,但是實際上不需要這么長時間——觸擊“放棄”按鈕,模式視圖控制器會立即消失。
在之前的測試中,你使用了類方法setDefaultTimeout:為所有測試操作設置全局的超時時間。在這里,你可以調用usingTimeout:為某一步定制的超時時間。
保存文件并點擊菱形按鈕運行單個測試。當定時器開始的時候,你可以發現它在放棄、返回主界面之前會等待3秒。
歷史和拖動之前我們沒有怎么關注歷史選項卡,現在該輪到它出一下風頭了。如果你按照練習一步一步來進行操作的話,那么你至少會有一條歷史記錄。構建并運行該應用,然后切換到歷史選項卡。
歷史表視圖實現了最新的iOS7刪除手勢——當你把整行往左邊拖動,然后觸擊出現的“刪除”按鈕。這是你的下一個測試!這要求歷史中至少有一條記錄,所以你跑單個測試的時候要小心。你必須保證歷史記錄中有內容,否則就沒什么可以測的!安全起見,你需要完整地運行整套測試,因為前面的測試會創建一些歷史記錄供你使用。記住,測試的運行順序是根據字母順序排列的,所以你可以很放心,前面的測試會創建一些歷史記錄的。
如果你看一下HistoryViewController.m中的tableView:cellForRowAtIndexPath:,你會發現每一格都能得到一個輔助標簽,比如“第3行第0個”之類的。這有助于KIF找到這一行。但在真實環境下這種標簽很糟,所以不要在真正的應用中使用。在示例工程中,我們使用#ifdef來確保這些只出現在調試構建中。你應該在你自己的應用中做類似的事情。請確保在發布構建的時候,將輔助標簽設為一些有用的內容,切實為用戶提供輔助功能。
現在,打開UITests.m并添加如下的測試方法:
- (void)test30StartTimerAndGiveUp { [tester tapViewWithAccessibilityLabel:@"Timer"]; [tester clearTextFromAndThenEnterText:@"Give Up" intoViewWithAccessibilityLabel:@"Task Name"]; [tester tapViewWithAccessibilityLabel:@"done"]; [self selectPresetAtIndex:2]; [tester tapViewWithAccessibilityLabel:@"Start Working"]; [tester waitForTimeInterval:3]; [tester tapViewWithAccessibilityLabel:@"Give Up"]; [[tester usingTimeout:1] waitForViewWithAccessibilityLabel:@"Start Working"]; }
現在介紹上面方法的作用:
切換到“歷史”選項卡。
引用表視圖并追蹤總共存在多少行。如果一行數據有沒有,測試就會失敗。
往左拖動表視圖的單元格。當刪除按鈕出現后,觸擊它。
刪除一個單元格的時候,表視圖會有一個動畫效果,所以在進行下一步前添加一個短暫的延時。再次檢查表視圖的行數,應當比之前的行數少一行。
用Command-U運行整套測試,所有的測試會順序執行。
現在,你的測試覆蓋了整個應用的基本流程了——從數據重置到多次運行定時器,再到驗證和刪除歷史記錄。
如果你要繼續開發這個應用程序,這些測試會是一個很好的基礎,確保界面沒有退步。這意味著在主界面變化的時候你需要更新你的測試——測試就像是你應用的規格說明,需要及時更新才能發揮作用。
進一步到目前為止,你應該對KIF的可能性有很好的了解,腦子里也應該有不少主意,如何利用這個高效的功能測試工具來測試你自己的應用程序。添加KIF到你自己的項目的時候,你可以查看這個文檔。你可以手動添加KIF或者使用非常方便的CocoaPods依賴管理。
KIF是一個開源項目,且有許多新功能還在不斷開發之中。例如,在寫這篇教程的時候,下一個KIF的發布版將會包含截屏的功能。這意味著可以在跑測試的時候通過屏幕截圖來查看全過程中的關鍵點。聽起來這不是比用肉眼觀察KIF點擊和拖動整個過程好上千萬倍么?KIF正變得越來越好了,所以學習如何使用它,是一個很好的自我投資。
最后,由于KIF測試用例是OCUnit的子類,并在標準的Xcode5測試框架下運行,你可以使用持續集成來跑這些測試。當你干別的事情的時候,你擁有了一個能夠像人的手指一樣觸控的機器人去測試你的應用程序。太棒了!
你可以在這里下載整個示例項目的代碼。測試快樂!
原文 iOS UI Testing with KIF
翻譯 SegmentFault
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/8703.html
Abstract There is an article shows demo code for making XMLSignature by using Java XML Digital Signature API, where it actually uses org.jcp.xml.dsig.internal.dom.XMLDSigRI to do DOM formation, and th...
閱讀 3250·2023-04-25 22:47
閱讀 3765·2021-10-11 10:59
閱讀 2300·2021-09-07 10:12
閱讀 4243·2021-08-11 11:15
閱讀 3432·2019-08-30 13:15
閱讀 1750·2019-08-30 13:00
閱讀 968·2019-08-29 14:02
閱讀 1680·2019-08-26 13:57