Xcode測試蘋果官方文檔翻譯(上)

Xcode測試

前言

????總算在今天把單元測試的官方文檔翻譯寫成了一片博客悲关。首先感謝黨胆绊,感謝人民间影,感謝我的父母欲低。也必須感謝下我們部門的領(lǐng)導(dǎo)給了我一個(gè)這樣的時(shí)間來做這件事情辕宏。翻譯的不算太好,很多地方都還只是一個(gè)概念砾莱,在翻譯的時(shí)候存在一些困難瑞筐。而且單元測試也不止于翻譯了這篇官方的文檔,它應(yīng)該是一系列的文檔和說明腊瑟。我會在今年的時(shí)間里聚假,努力去寫出來一個(gè)雛形。希望更多的人可以通過這些介紹認(rèn)識到測試闰非。

介紹

使用Xcode測試

Xcode提供的一個(gè)功能膘格,可以進(jìn)行廣泛的軟件測試。主要測試你的項(xiàng)目的健壯性财松,減少BUG瘪贱,讓你的產(chǎn)品更快的分發(fā)和銷售。按照預(yù)期的功能測試辆毡,提高用戶的滿意度菜秦。測試可以幫助你更快開發(fā)、少做無用功舶掖。


目錄結(jié)構(gòu)

在這份文件中球昨,你將學(xué)習(xí)如何使用Xcode包含的測試功能。XCTest框架添加測試的時(shí)候自動(dòng)鏈接上去的眨攘。

  • 1.快速啟動(dòng)主慰,在Xcode5引進(jìn)XCTest框架開始,配置項(xiàng)目測試的過程已經(jīng)簡化可以在導(dǎo)航欄自動(dòng)的測試和運(yùn)行鲫售。
  • 2.性能測試共螺,Xcode6以及更高的版本讓你能夠跟蹤和衡量基本單位的性能變化。
  • 3.UI測試情竹,Xcode7增加了對用戶界面的測試能力藐不。
  • 4.持續(xù)集成和Xcode服務(wù)器,Xcode測試可以使用命令腳本來執(zhí)行或配置在Mac上的漫游器自動(dòng)運(yùn)行Xcode服務(wù)器上執(zhí)行鲤妥。
  • 5.現(xiàn)代化佳吞,Xcode中包含轉(zhuǎn)換一測試的OCUnit測試項(xiàng)目遷移。

前提

你應(yīng)該熟悉應(yīng)用程序的設(shè)計(jì)和編程的概念棉安。

快速啟動(dòng)

快速啟動(dòng)其實(shí)就是介紹了測試的組成部分你可以對測試有一個(gè)簡單的理解底扳。

介紹測試的導(dǎo)航欄

當(dāng)你準(zhǔn)備做測試工作的時(shí)候,你會經(jīng)常使用測試的導(dǎo)航欄贡耽。
測試的導(dǎo)航欄目的是緩解你測試代碼的編寫衷模、管理鹊汛、運(yùn)行、審查測試的操作阱冶。你可以點(diǎn)擊導(dǎo)航欄中的圖標(biāo)刁憋,位于show the issue導(dǎo)航和show the debug導(dǎo)航之間。當(dāng)你創(chuàng)建了一些測試的項(xiàng)目你可以在這里看到一個(gè)導(dǎo)航視圖木蹬。



圖中的測試導(dǎo)航現(xiàn)實(shí)測試包至耻、類和包含在測試項(xiàng)目方法的分層列表。圖中的項(xiàng)目是一個(gè)簡單的計(jì)算器項(xiàng)目镊叁。計(jì)算器使用一個(gè)框架實(shí)現(xiàn)尘颓,你可以在最高層的SampleCalcTests測試包里看到測試的代碼。

注意:Xcode的測試目標(biāo)產(chǎn)生后顯示在測試導(dǎo)航里晦譬。如果你的測試使用數(shù)據(jù)文件疤苹、圖像等等,他們可以被添加到所述的測試包敛腌,并且可以在運(yùn)行的時(shí)候訪問一個(gè)NSBundle的API卧土。使用+[NSBundle bundleForClass:]確定你獲得正確的包來進(jìn)行測試盈匾。Xcode的方案控制構(gòu)建了什么娄昆。方案還控制哪個(gè)可用的測試方法用于測試操作需要去執(zhí)行。你可以啟用和控制通過點(diǎn)擊該項(xiàng)目在測試導(dǎo)航的列表中损肛,選擇啟用或者從快捷菜單中禁用凶硅。從而啟用或禁用測試包缝裁、類和方法扫皱。

此視圖中的主要測試包是SampleCalcTests足绅。SampleCalcTests包括一個(gè)測試類,后面包含九個(gè)測試方法韩脑。運(yùn)行按鈕在測試項(xiàng)目名稱的右側(cè)氢妈。這是一個(gè)非常方便的方法,所有的測試項(xiàng)目都集中到了這里(如果使用了一些第三方的測試可能有一些不會出現(xiàn)在這里列表當(dāng)中)段多。運(yùn)行以后紅色的X代表測試不通過首量,綠色的對勾代表測試通過。運(yùn)行的測試項(xiàng)目是使用斷言來檢測通過或者故障进苍。



單擊列表中的任何測試類或者測試方法打開測試類加缘。測試類和測試方法在gutter都會顯示一個(gè)可點(diǎn)擊的測試的標(biāo)志(可進(jìn)行單獨(dú)的測試)。
在測試導(dǎo)航的底部你可以添加一個(gè)測試觉啊,也可以通過一些字符串縮小你的查找范圍拣宏。

為你的App添加測試

在Xcode5或者更高的版本你創(chuàng)建應(yīng)用的時(shí)候可以通過勾選測試的按鈕來為項(xiàng)目添加一個(gè)測試。當(dāng)你創(chuàng)建好以后你可以在你的項(xiàng)目里看到一個(gè)測試包杠人、測試和模版測試的方法勋乾。但是你的項(xiàng)目可能是由比較早的Xcode版本生成的宋下。這里介紹的就是當(dāng)你項(xiàng)目里預(yù)先沒有測試的時(shí)候的一些操作。

創(chuàng)建一個(gè)測試Target

打開測試導(dǎo)航辑莫,單擊左下角的加號按鈕学歧,new unit test target。



在彈出框中選擇OS X或者iOS單元測試各吨,然后單擊下一步枝笨,設(shè)置相關(guān)的信息。



點(diǎn)擊finish揭蜒,完成以后點(diǎn)開伺帘。包含一個(gè)模版測試類和兩個(gè)測試方法的模版。

運(yùn)行測試忌锯,查看結(jié)果

現(xiàn)在你為你的項(xiàng)目添加了一個(gè)測試伪嫁,然后去開發(fā)測試一些有意義的東西。首先按住鼠標(biāo)指針移動(dòng)到SampleCalcTests在測試導(dǎo)航測試類偶垮,然后點(diǎn)擊運(yùn)行按鈕運(yùn)行該類中的所有測試方法张咳。結(jié)果在方法名稱的右邊,編輯區(qū)方法名的左邊似舵。



因?yàn)槟K測試和性能測試都是空的脚猾,所以測試成功了。并沒有失敗的斷言砚哗。measureBlock:處單擊左側(cè)的“鉆石”會顯示性能測試的結(jié)果龙助。



這個(gè)面板允許設(shè)置性能基線以及編輯基線和最大STDDREV參數(shù)。

編輯測試和重新運(yùn)行

這個(gè)實(shí)例項(xiàng)目是一個(gè)計(jì)算器應(yīng)用程序蛛芥,你需要檢查加提鸟、減、乘仅淑、除算法的正確性称勋,以及測試其他計(jì)算器功能的操作。測試是在項(xiàng)目中添加和編寫的涯竟,你可以測試任何你想要的測試赡鲜。(這就要求你有一個(gè)很好的代碼結(jié)構(gòu)來提供測試)
eg:你可以在SampleCalcTests.m中添加實(shí)例聲明和引入類。
<pre><code>

import <XCTest/XCTest.h>

//

// Import the application specific header files

import "CalcViewController.h"

import "CalcAppDelegate.h"

@interface CalcTests : XCTestCase {

// add instance variables to the CalcTests class

@private

  • NSApplication *app;
  • CalcAppDelegate *appDelegate;
  • CalcViewController *calcViewController;
  • NSView *calcView;

}

*@end
</code></pre>
然后給測試方法的起一個(gè)描述性的名稱庐船,如testAddition并添加要實(shí)施的方法银酬。
<pre><code>
*- (void) testAddition

*{

*//obtain the app variables for test access

*App = [NSApplication sharedApplication];

calcViewController = (CalcViewController)[[NSApplicationsharedApplication] delegate];

*calcView = calcViewController.view;

*//perform two addition tests

*[calcViewController press:[calcView viewWithTag: 6]]; // 6

*[calcViewController press:[calcView viewWithTag:13]]; // +

*[calcViewController press:[calcView viewWithTag: 2]]; // 2

*[calcViewController press:[calcView viewWithTag:12]]; // =

*XCTAssertEqualObjects([calcViewController.displayField stringValue],@"8", @"Part 1 failed.");

*[calcViewController press:[calcView viewWithTag:13]]; // +

*[calcViewController press:[calcView viewWithTag: 2]]; // 2

*[calcViewController press:[calcView viewWithTag:12]]; // =

*XCTAssertEqualObjects([calcViewController.displayField stringValue],@"10", @"Part 2 failed.");

}
</code></pre>
如果你改變了測試的方法,測試導(dǎo)航列表也會做相應(yīng)的改變筐钟。


編輯完以后可以使用測試導(dǎo)航(或者gutter)來運(yùn)行testAddition方法揩瞪。

當(dāng)一個(gè)斷言失敗,在測試導(dǎo)航和gutter會突出顯示盗棵。根據(jù)提示信息你可以非常輕易的找到這個(gè)錯(cuò)誤壮韭。進(jìn)行修改之后就能夠運(yùn)行成功北发。

使用setUp()和tearDown()方法
Xcode運(yùn)行一個(gè)測試包的時(shí)候會走這個(gè)測試類中的所有方法。那這個(gè)測試類中如果都需要一個(gè)初始化對象喷屋,你就要在每一個(gè)方法中對這個(gè)對象進(jìn)行初始化琳拨,這樣就會造成很多重復(fù)的代碼。但是XCTest框架提供了兩個(gè)實(shí)例方法用于測試類的初始化和釋放屯曹。你可以用這兩個(gè)實(shí)例方法將這些共同調(diào)用的方法寫進(jìn)去狱庇。
使用setup和teardown方法非常簡單。
<code><pre>
*- (void)setup

{

  • [super setUp];
  • *// Put setup code here. This method iscalled before the invocation of each test method in the class.
  • *// obtain the app variables for test access
  • *app = [NSApplication sharedApplication];
  • calcViewController = (CalcViewController)[[NSApplicationsharedApplication] delegate];
  • *calcView = calcViewController.view;

}
</code></pre>
Setup方法會在測試方法之前調(diào)用恶耽,所以測試方法可以直接試用初始化過的屬性密任。

概要

從這個(gè)簡短的快速入門可以看出來,為一個(gè)項(xiàng)目添加測試是很簡單的偷俭。但是還是有一些注意事項(xiàng):

  1. Xcode中設(shè)置了大部分的基本測試配置浪讳。當(dāng)你添加一個(gè)新的測試的時(shí)候,Xcode會自動(dòng)為你添加這些測試方法涌萤。使用一個(gè)單獨(dú)的方法進(jìn)行測試淹遵,可以在測試導(dǎo)航中找到。
  2. 測試導(dǎo)航可以讓你輕松的找到編輯測試的方法负溪,你可以運(yùn)行透揣,在導(dǎo)航測試或者gutter。測試失敗的時(shí)候你可以在gutter中看到失敗的標(biāo)志川抡。
  3. 單個(gè)測試方法可以包括多個(gè)斷言辐真,從而導(dǎo)致單一的合格或者不合格的測試結(jié)果。你可以根據(jù)需求來做簡單或者復(fù)雜的測試崖堤。setup和teardown實(shí)例方法可以讓你將通用的代碼寫在里邊侍咱。

基礎(chǔ)測試

測試是指檢驗(yàn)?zāi)愕膽?yīng)用程序代碼和庫代碼能否成功運(yùn)行的過程,用于衡量預(yù)期結(jié)果倘感。通過執(zhí)行一些操作放坏,測試可在執(zhí)行一些操作后檢查一個(gè)對象的實(shí)例變量的狀態(tài)咙咽,以確定你的代碼在受到邊界條件變化時(shí)是否會拋出一個(gè)特定的異常等老玛。

定義測試范圍

所有的軟件都是通過很多的單元組合起來的,也就是說钧敞,小的組件合在一起形成較大的蜡豹、功能更強(qiáng)的高級組件,直到符合項(xiàng)目的需求溉苛。良好的測試需要涵蓋該組合的所有功能镜廉。其中單元測試通常處理該項(xiàng)目功能級的小組件。而XCTest允許你為任何層次結(jié)構(gòu)的各個(gè)級別的組件編寫相應(yīng)的測試愚战。
測試組件由什么構(gòu)成完全取決于你自己娇唯,可以是一個(gè)類中的一個(gè)方法齐遵,也可以是完成一個(gè)基本目的的一組方法。例如塔插,一個(gè)算術(shù)運(yùn)算梗摇,參見蘋果的官方demo。處理tableView的內(nèi)容間和代碼數(shù)據(jù)結(jié)構(gòu)中持有列表名稱間的交互有不同的方法想许。每個(gè)方法的操作都意味著應(yīng)用程序功能的組成部分對它的測試伶授。一個(gè)測試組件的行為應(yīng)該是完全確定的,無論測試成功或者失敗流纹。
把你的應(yīng)用程序的行為劃分為越多的組件糜烹,就越能有效的測試你的代碼能否滿足參考標(biāo)準(zhǔn)的各種細(xì)節(jié),尤其是當(dāng)項(xiàng)目不斷的迭代更新的時(shí)候漱凝。對于很多組件組成的大型項(xiàng)目來說疮蹦,你需要運(yùn)行很多的測試來徹底檢測整個(gè)項(xiàng)目。如果可能的話茸炒,測試應(yīng)該快速運(yùn)行挚币,擔(dān)憂一些測試確實(shí)很大,所以運(yùn)行可能會慢一點(diǎn)扣典。當(dāng)有一些故障出現(xiàn)的時(shí)候妆毕,可以運(yùn)行一些小的測試快速測試,這樣可以輕松診斷和修復(fù)問題贮尖。
為項(xiàng)目組件設(shè)計(jì)測試是測試驅(qū)動(dòng)開發(fā)(test-driven-development TDD)的基礎(chǔ)笛粘,也是一種編寫代碼測試之前編寫測試邏輯的編碼方式。這種開發(fā)方法可以讓你在實(shí)施之前確定代碼需求和邊界情況湿硝。編寫測試后薪前,開發(fā)旨在通過測試的算法。在代碼通過測試以后关斜,你才有了提高代碼的基礎(chǔ)示括,才有信心在下一次運(yùn)行這些測試時(shí)能鑒定一些預(yù)期行為(導(dǎo)致你的產(chǎn)品產(chǎn)生BUG)的變化。

甚至在你不使用測試驅(qū)動(dòng)開發(fā)時(shí)痢畜,測試還可以降低修改代碼引入的BUG數(shù)量垛膝,從而幫你提高代碼的特性和功能。在一款運(yùn)行的應(yīng)用程序中進(jìn)行測試以確保未來的更改不會改變應(yīng)用的行為丁稀。當(dāng)你修復(fù)這些BUG后吼拥,你需要添加測試以確保該BUG已經(jīng)被修復(fù)。測試還可以檢測你的代碼线衫,所以有成功和失敗兩種預(yù)期凿可,以覆蓋所有邊界條件。
注意:為一個(gè)沒有考慮到測試的項(xiàng)目添加測試可能會要求重構(gòu)部分代碼來使測試變得更加簡單授账】菖埽“Writing Testable Code”包含游泳的編寫可測試代碼的簡單指南惨驶。
組件可以包括你的應(yīng)用程序的各部分之間的交互。由于有些測試可能需要很長時(shí)間敛助,所以你可能希望定期或者只在一臺服務(wù)器上運(yùn)行他們敞咧。(你可以組織自己的測試并以多種方式運(yùn)行它們,以滿足不同的需求)辜腺。

性能測試

測試的組件可以同時(shí)測試功能和記錄性能休建。使用XCTest提供的API你可以測量以時(shí)間為基準(zhǔn)的性能測試,對一個(gè)相似的方法或者功能你可以跟蹤性能的提高或者退化评疗。
為了衡量一個(gè)性能測試的成功或者失敗测砂,測試必須有一個(gè)基準(zhǔn)用來評估“俅遥基線是運(yùn)行10次以后計(jì)算出來的平均時(shí)間的性能測試砌些。如果與基線相差太多的時(shí)候?yàn)槭 ?**注意:當(dāng)你第一次運(yùn)行性能測試的時(shí)候系統(tǒng)會提示失敗,因?yàn)榈谝淮芜\(yùn)行的時(shí)候基線是未知的加匈。一旦你設(shè)定了一個(gè)測量準(zhǔn)線存璃,XCTest會報(bào)告成功或者失敗,并提示相信的結(jié)果信息雕拼。**

用戶界面測試

功能測試和性能測試一般都被稱為單元測試纵东,其中的單元是相對于組件和最小的模塊來確定的(大概意思)。單元測試主要是讓相關(guān)的組件能夠按照預(yù)期的那樣交互啥寇。從設(shè)計(jì)的角度來看偎球,單元測試是在開發(fā)的時(shí)候編寫的滿足你的預(yù)期。

用戶通過源代碼進(jìn)行界面的交互辑甜。界面的交互一般是整合一整個(gè)子系統(tǒng)的操作來實(shí)現(xiàn)預(yù)期的功能衰絮。這些很難使用單元測試來進(jìn)行測試,這種特殊的測試被稱為UI測試磷醋。
UI測試更貼近于用戶的體驗(yàn)猫牡。你可以編寫模擬事件添加到UI測試中,捕捉這些對象的反應(yīng)邓线,然后測試正確性和性能和單元測試十分類似淌友。

應(yīng)用程序測試和庫測試

Xcode測試提供兩種測試:應(yīng)用程序測試和庫測試。
應(yīng)用程序測試褂痰。應(yīng)用程序測試可以檢查App的代碼組件亩进,例如蘋果測試的官方demo。你可以利用應(yīng)用程序來確保你的UI控件保持原有的位置缩歪,并且你的控件和控制器對象能夠和對象模型正確地工作。
庫測試谍憔。庫測試可檢查獨(dú)立代碼(不再應(yīng)用程序中運(yùn)行的代碼)的行為是否正確匪蝙。利用庫測試主籍,你可以將整個(gè)庫的組件放在一起,通常是測試庫的對象和方法逛球。你也可以使用庫測試來執(zhí)行代碼的壓力測試千元,以確保它在極端的情況下也能正確執(zhí)行(不大可能出現(xiàn)在一個(gè)運(yùn)行的app中)。這些測試可以幫助你生成一個(gè)“健壯的”代碼颤绕,即使在沒有預(yù)料的情況下也能運(yùn)行正常幸海。

XCTest-Xcode測試框架

XCTest是一個(gè)Xcode5及以上版本中使用的測試框架。如果你以前使用過Xcode OCUnit測試奥务,你可能會發(fā)現(xiàn)XCTest和OCUnit有些相似物独。XCTest是OCUnit更現(xiàn)代化的替代,可以更好的與Xcode集成氯葬,為將來Xcode測試功能的改進(jìn)奠定了基礎(chǔ)挡篓。Xcode把XCTest.framework并入你的項(xiàng)目,而不是SenTesting.framework帚称。該框架提供可以讓你設(shè)計(jì)測試并在代碼中運(yùn)行的API官研。
**注意:Xcode包括一個(gè)遷移助手,可用來轉(zhuǎn)換包含OCUnit測試的項(xiàng)目闯睹。更多OCUnit想XCTest轉(zhuǎn)換的詳細(xì)信息戏羽,請參閱“Transitioning frome OCUnit to XCTest”**

測試從哪里運(yùn)行

當(dāng)你開始創(chuàng)建測試的時(shí)候,記住下面的方法:
  1. 專注于測試你的代碼的最基礎(chǔ)的功能楼吃、模型類蛛壳、方法,它們與控制器相交互所刀。
    應(yīng)用程序的高級框圖很可能會包含Model衙荐、View和Controller類別,對于每個(gè)使用Cocoa和Cocoa Touch的開發(fā)者來說浮创,這是一個(gè)熟悉設(shè)計(jì)模式忧吟。當(dāng)你編寫要覆蓋所有Model類別的測試時(shí),你必須要知道App的基礎(chǔ)已經(jīng)進(jìn)行了良好的測試斩披,而且要編寫Controller Classes測試之前溜族,它將帶你接觸你的應(yīng)用程序更復(fù)雜的部分。
  2. 作為一個(gè)可選的起始點(diǎn)垦沉,如果你正在編寫一個(gè)框架或庫煌抒,你可能想從App接口開始。從那里你可以按照你的方式進(jìn)入內(nèi)部類厕倍。

編寫測試類與方法

但你使用測試導(dǎo)航面板往項(xiàng)目中添加測試target的時(shí)候寡壮,Xcode會在測試導(dǎo)航面板里展示除測試類和測試方法。在測試target里是包含測試方法的測試類。

測試target况既、測試包这溅、測試導(dǎo)航

在學(xué)習(xí)創(chuàng)建測試類前,有必要看看測試導(dǎo)航面板棒仍。它對創(chuàng)建和運(yùn)行測試工作極為重要悲靴。
測試導(dǎo)航面板羅列了測試包里的所有組件內(nèi)容,并在一個(gè)層次列表里展示出測試類和測試方法莫其。下邊是一個(gè)工程的測試導(dǎo)航面板視圖癞尚,包含了多個(gè)測試目標(biāo),展示了測試包乱陡、測試類浇揩、以及測試方法的嵌套層級。

測試包里可以包含多個(gè)測試類蛋褥。你可以使用測試類把測試分到相關(guān)的組群里临燃,或者按照功能分,或者按照組織目的分烙心。例如蘋果測試的官方demo膜廊,創(chuàng)建了BasicFunctionsTests、AdvancedFunctionsTests淫茵、DisplayTests classes三個(gè)類爪瓜,但它們都屬于Mac_Calc_Tests測試包。



一些測試類型可能會共享某些類型的setup和teardown匙瘪,把這些測試整合到類里邊會更加合理铆铆,這樣可以最小化每個(gè)測試方法所需的編寫代碼。

創(chuàng)建測試

可以使用加號按鈕在導(dǎo)航測試面板中選中“New Test Class”命令來創(chuàng)建新測試類丹喻。


基于你在配置頁面鍵入的測試類名薄货,你添加的每一個(gè)類都會使得一個(gè)名為TestClassName.m的文件被添加到項(xiàng)目中。

注意:所有的測試類都是XCTest框架XCTestCase類的子類碍论。
盡管Xcode會默認(rèn)的把測試類添加到工程測試項(xiàng)目所創(chuàng)建的組中谅猾,你還是可以在項(xiàng)目中組織自己選擇的文件。當(dāng)你按下Next按鈕鳍悠,標(biāo)準(zhǔn)的Xcode添加文件頁面如下所示:

你可以使用相同的方法在工程導(dǎo)航面板中添加文件税娜。具體使用當(dāng)法詳見“Adding an Existing File or Folder”。
注意:當(dāng)你用Xcode5及以上版本創(chuàng)建工程時(shí)藏研,一個(gè)測試target和相關(guān)的測試包都會被默認(rèn)的創(chuàng)建敬矩,名稱根據(jù)工程名獲得。比如創(chuàng)建名為MyApp的項(xiàng)目蠢挡,則會自動(dòng)生成一個(gè)名為MyAppTests的測試包弧岳,以及一個(gè)名為MyAppTests的測試類凳忙,關(guān)聯(lián)在MyAppTests.m實(shí)例文件中。

測試類的結(jié)構(gòu)

測試類包含以下的基礎(chǔ)結(jié)構(gòu):

<code><pre>
*#import <XCTest/XCTest.h>

*@interface SampleCalcTests : XCTestCase

*@end

*@implementation SampleCalcTests

*- (void)setUp {

*[super setUp];

*// Put setup code here. Thismethod is called before the invocation of each test method in the class.

*}

*- (void)tearDown {

*// Put teardown code here. Thismethod is called after the invocation of each test method in the class.

*[super tearDown];

*}

*- (void)testExample {

*// This is an example of afunctional test case.

*// Use XCTAssert and relatedfunctions to verify your tests produce the correct results.

*}

*- (void)testPerformanceExample {

*// This is an example of aperformance test case.

*[self measureBlock:^{

*// Put the code you want tomeasure the time of here.

*}];

*}

@end
</code></pre>

測試類用Objective-C實(shí)現(xiàn)缩筛。注意實(shí)現(xiàn)里包含了方法消略,比如setup和teardown的基本實(shí)例方法堡称。這些方法是必須的瞎抛。如果類中的所有的測試方法都需要相同的代碼,你可以定制setup和teardown來包含這些代碼却紧。你添加的代碼在每一個(gè)測試方法的之前和之后調(diào)用桐臊。你可以選擇添加定制的設(shè)置(+ (void)setUp)和卸載teardown(+ (void)tearDown)方法,它們在類里所有的測試方法的之前和之后調(diào)用晓殊。Xcode執(zhí)行測試可以明確這些方法的使用断凶。

測試執(zhí)行的流程

在執(zhí)行測試的過程中,XCTest找到所有集成與XCTestCase(它是測試類)的類巫俺,為每一個(gè)類運(yùn)行它們的測試方法认烁。
對于每個(gè)類來說,測試開始于運(yùn)行類的setup方法介汹。對于每個(gè)測試方法來說却嗡,一個(gè)新的類實(shí)例被創(chuàng)建,他的實(shí)例setup方法就會執(zhí)行嘹承。在跑完測試方法之后窗价,實(shí)例teardown方法。類中這樣連續(xù)重復(fù)執(zhí)行所有的測試方法叹卷。在運(yùn)行了teardown最后的測試方法后撼港,Xcode會執(zhí)行類teardown方法,并開始下一個(gè)類骤竹。這種序列已知重復(fù)直到跑完所有測試類的所有測試方法帝牡。

編寫測試方法

你通過編寫測試方法把測試寫到測試類中,一個(gè)測試方法是以test開頭的測試類的實(shí)例方法蒙揣,沒有參數(shù)靶溜,返回void,比如TestColorsRed測試方法調(diào)用工程中的代碼鸣奔,如果代碼沒有產(chǎn)生預(yù)期的效果墨技,那么會用一系列的斷言API報(bào)錯(cuò)。比如挎狸,一個(gè)函數(shù)返回值可能于預(yù)期相比不同扣汪,或者你的測試方法使用了某個(gè)不適當(dāng)?shù)姆椒ǘ紝伋霎惓!锨匆!癤CTest Assertions”描述了這些情況崭别。
為了是測試方法能夠正常訪問被測代碼冬筒,引入正確的頭文件到測試類中很重要。
當(dāng)Xcode運(yùn)行測試時(shí)茅主,它調(diào)用的每個(gè)測試方法都是獨(dú)立的舞痰。因此每個(gè)方法需要準(zhǔn)備和清理輔助變量、結(jié)構(gòu)以及與主題API進(jìn)行交互的對象等诀姚。如果類中所有的測試方法的代碼是相同的响牛,你可以直接把它添加到必走的setup和teardown的實(shí)例方法中,詳見“Test Class Structure”赫段。

下邊是一個(gè)測試方法的模型:
<code><pre>
*- (void)testColorIsRed {

  • *// Set up, call test subject API. (Codecould be shared in setUp method.)
  • // Test logic and values, assertions reportpass/fail to testing framework.
  • // Tear down. (Code could be shared intearDown method.

}
</code></pre>
這里有一個(gè)簡單的測試方法例子呀打,檢查是否成功為SampleCalc創(chuàng)建了CalcView實(shí)例,詳見“快速啟動(dòng)”糯笙。
<code><pre>
*- (void) testCalcView {

  • // setup
  • app = [NSApplication sharedApplication];
  • calcViewController =(CalcViewController*)[NSApplication sharedApplication] delegate];
  • calcView = calcViewController.view;
  • XCTAssertNotNil(calcView, @"Cannot findCalcView instance");
  • // no teardown needed

}
</code></pre>

編寫異步操作測試

測試是同步的贬丛,因?yàn)橹挥挟?dāng)上一次測試結(jié)束以后才進(jìn)行下一個(gè)測試。但是越來越多的代碼使用異步執(zhí)行给涕。為了處理這些異步調(diào)用執(zhí)行的方法和功能組件豺憔,Xcode6增強(qiáng)了包括序列化異步執(zhí)行測試方法的能力,等待異步回調(diào)或者超時(shí)完成够庙。
例如:

<code><pre>
*// Test that the documentis opened. Because opening is asynchronous,

*// use XCTestCase'sasynchronous APIs to wait until the document has

// finished opening.

-(void)testDocumentOpening

{ *// Create anexpectation object.

  • *// This test only has one, but it'spossible to wait on multiple expectations.
  • *XCTestExpectation *documentOpenExpectation = [selfexpectationWithDescription:@"document open"];
  • *NSURL *URL =[[NSBundle bundleForClass:[self class]]
  •                        URLForResource:@"TestDocument"withExtension:@"mydoc"];
    
  • UIDocumentdoc = [[UIDocument alloc] initWithFileURL:URL];
  • *[docopenWithCompletionHandler:^(BOOL success) {
  •  *XCTAssert(success);
    
  •  *// Possibly assert other things here about the document after it hasopened...
    
  •  *// Fulfill the expectation-this will cause -waitForExpectation
    
  •   *// to invoke its completion handler andthen return.
    
  •  *[documentOpenExpectation fulfill];
    
  • *}];
  • *// The testwill pause here, running the run loop, until the timeout is hit
  • *// or all expectations are fulfilled.
  • *[selfwaitForExpectationsWithTimeout:1 handler:^(NSError *error) {
  •  *[doc closeWithCompletionHandler:nil];
    
  • *}];

*}
</code></pre>
有關(guān)更多異步操作的相信信息恭应,請參閱“XCTest.framework”下的XCTestCase+AsynchronousTesting.h文件。

性能測試

性能測試就是在代碼塊中運(yùn)行10次首启,收集平均執(zhí)行時(shí)間和和標(biāo)準(zhǔn)的偏差暮屡。這些值形成一個(gè)平均值,用來評估和基線對比的成功或者失敗。
**注意:基線是您指定要用于檢測合格與否的瓶價(jià)值。該報(bào)告的UI提供了一種機(jī)制來設(shè)置或者更改基準(zhǔn)值辛藻。**
為了實(shí)現(xiàn)性能測試端圈,在Xcode6以后當(dāng)中使用新的XCTest方法的API。

<code><pre>
*- (void)testPerformanceExample{

  • *// This is an example of a performance testcase.
  • *[self measureBlock:^{
  •   *// Put the code you want to measure thetime of here.
    
  • }];

*}
</code></pre>
下面的例子簡單的演示了一個(gè)用計(jì)算器應(yīng)用程序編寫的性能測試的測試速度。一個(gè)measureBlock隨著時(shí)間的增加XCTest迭代。
<code><pre>
*- (void) testAdditionPerformance{

  • *[self measureBlock:^{
  •   *// set the initial state
    
  •   *[calcViewController press:[calcViewviewWithTag: 6]];  // 6
    
  •   *// iterate for 100000 cycles of adding2
    
  •   *for (int i=0; i<100000; i++) {
    
  •      *[calcViewController press:[calcViewviewWithTag:13]];  // +
    
  •      *[calcViewController press:[calcViewviewWithTag: 2]];  // 2
    
  •      *[calcViewController press:[calcViewviewWithTag:12]];  // =
    
  •   *}
    
  • *}];

}
</code></pre>
運(yùn)行一次性能測試,在測試導(dǎo)航面板的導(dǎo)航器中提供信息彻秆。點(diǎn)擊該信息會顯示運(yùn)行出來的值。結(jié)果顯示包括控制設(shè)置的結(jié)果作為準(zhǔn)線和未來的測試做對比结闸〈蕉遥基線存儲了每個(gè)設(shè)備的配置,所以你相同的測試在不同的設(shè)備上執(zhí)行桦锄,會有不同的準(zhǔn)線扎附。(取決于配置的處理速度,內(nèi)存等等)
注意:性能測試總是在第一次運(yùn)行结耀,直到準(zhǔn)線被設(shè)置在一個(gè)特定的設(shè)備配置中報(bào)告失敗留夜。
有關(guān)性能測試的更多詳細(xì)的信息匙铡,請參閱XCTest.framework下的XCTestCase.h文件。

編寫UI測試

創(chuàng)建XCTest UI測試是單元測試的一個(gè)擴(kuò)展對于相同的編程模型碍粥。參見“User Interface Testing”鳖眼。

編寫swift測試

swift控制器和模型不能訪問程序內(nèi)部和框架內(nèi)部聲明。在Xcode6訪問swift的內(nèi)部功能嚼摩,你需要進(jìn)入公共的切入點(diǎn)來進(jìn)行測試钦讳,降低了swift的安全特性。
Xcode7提供了這個(gè)問題的解決方案:
  1. swift內(nèi)部訪問時(shí)低斋,測試通過通知編輯器生成進(jìn)行訪問蜂厅。編譯器通過一個(gè)新的控制-enable進(jìn)行更改匪凡,Xcode在接受到這個(gè)通知的時(shí)候生成膊畴。這種行為是控的,對新的項(xiàng)目的默認(rèn)設(shè)置來進(jìn)行設(shè)置病游。他不需要改變源代碼唇跨。
  2. 通過修改導(dǎo)入頭文件的聲明,來改變測試入口的可見性衬衬。使用新的@testable屬性導(dǎo)入买猖,改變你的測試代碼,不需要修改應(yīng)用代碼滋尉。
    <code><pre>
    *import Cocoa

*@NSApplicationMain

*class AppDelegate: NSObject, NSApplicationDelegate {

*@IBOutlet weak var window:NSWindow!

*func foo() {

*println("Hello,World!")

*}

}
</code></pre>

編寫一個(gè)測試類玉控,允許訪問Appdelegate類,修改導(dǎo)入的語句與你的測試代碼使用@testable屬性

<code><pre>
*// Importing XCTestbecause of XCTestCase
*import XCTest
*// Importing AppKitbecause of NSApplication

*import AppKit

*// Importing MySwiftAppbecause of AppDelegate

*@testable importMySwiftApp

*class MySwiftAppTests:XCTestCase {

  • *func testExample() {
  •   let appDelegate =NSApplication.sharedApplication().delegate as! AppDelegate
    
  •   appDelegate.foo()
    
  • }

}
</code></pre>
有了這個(gè)解決方案狮惜,你的swift內(nèi)部代碼能夠完全的被測試方法訪問到高诺。

XCTest斷言

你的測試方法使用XCTest框架提供給的斷言來展示Xcode的測試結(jié)果。所有的斷言都有一個(gè)類似的形式:項(xiàng)目比較或邏輯表達(dá)碾篡,一個(gè)失敗的結(jié)果字符串格式虱而,和插入到字符串格式中的參數(shù)。
**注意:所有的斷言最后一個(gè)參數(shù)是format…开泽,格式字符串和變量參數(shù)列表牡拇。XCTest為所有斷言提供了默認(rèn)的失敗結(jié)果字符串,可以使用參數(shù)傳遞到斷言里穆律。Format字符串提供了可選的額外的失敗自定義描述惠呼,就可以進(jìn)一步選擇提供的描述。這個(gè)參數(shù)是可選的峦耘,也可以完全忽略剔蹋。**
例如:

<code><pre>
XCTAssertEqualObjects([calcViewController.displayField stringValue], @"8", @"Part 1 failed.");
</code></pre>
這段簡單明了的描述是說:“Indicate a failure when a string created from the value of the controller’s display field is not the same as the reference string ‘8’”。如果斷言失敗那么Xcode在測試導(dǎo)航面板發(fā)出失敗信號贡歧,然后Xcode會在issues導(dǎo)航面板滩租、源碼編輯器以及其他地方展示失敗的描述赋秀。下面是源代碼編輯器典型的斷言結(jié)果:



測試方法可以包含多個(gè)斷言,如果任何斷言包含失敗報(bào)告律想,那么Xcode都會發(fā)出測試失敗信號猎莲。
斷言氛圍物種類型:無條件報(bào)錯(cuò)、等價(jià)測試技即、nil測試著洼、布爾測試以及異常測試。

用類別區(qū)分?jǐn)嘌?/h3>
下面的區(qū)域列出了XCTest斷言而叼。你可以XCTestAssertions.h中獲取更多斷言的信息身笤。
  1. 無條件報(bào)錯(cuò)
    XCTFail生成一個(gè)無條件的報(bào)錯(cuò)
    <code><pre>
    XCTFail(format...)
    </code></pre>
  2. 等價(jià)測試
    XCTAssertEqualObjectes,當(dāng)expresson1不等于expresson2時(shí)報(bào)錯(cuò)(或者一個(gè)對象為空葵陵,另一個(gè)對象不為空)
    <code><pre>
    XCTAssertEqualObjects(expression1, expression2, format...)
    </code></pre>
    XCTAssertNotEqualObjects. 當(dāng)expression1等于expression2時(shí)報(bào)錯(cuò)液荸。
    <code><pre>
    XCTAssertNotEqualObjects(expression1, expression2, format...)
    </code></pre>
    XCTAssertEqual. 當(dāng)expression1不等于expression2時(shí)報(bào)錯(cuò),這個(gè)測試用于C語言的標(biāo)量脱篙。
    <code><pre>
    XCTAssertEqual(expression1, expression2, format...)
    </code></pre>
    XCTAssertNotEqual. 當(dāng)expression1等于expression2時(shí)報(bào)錯(cuò)娇钱,這個(gè)測試用于C語言的標(biāo)量。
    <code><pre>
    XCTAssertNotEqual(expression1, expression2, format...)
    </code></pre>
    XCTAssertEqualWithAccuracy. 當(dāng)expression1和expression2之間的差別高于accuracy 將報(bào)錯(cuò)绊困。這種測試適用于floats和doubles這些標(biāo)量文搂,兩者之間的細(xì)微差異導(dǎo)致它們不完全相等,但是對所有的標(biāo)量都有效秤朗。
    <code><pre>
    XCTAssertEqualWithAccuracy(expression1, expression2, accuracy, format...)
    </code></pre>
    XCTAssertNotEqualWithAccuracy. 當(dāng)expression1和expression2之間的差別低于accuracy將產(chǎn)生失敗煤蹭。這種測試適用于floats和doubles這些標(biāo)量,兩者之間的細(xì)微差異導(dǎo)致它們不完全相等取视,但是對所有的標(biāo)量都有效硝皂。
    <code><pre>
    XCTAssertNotEqualWithAccuracy(expression1, expression2, accuracy, format...)
    </code></pre>
  3. Nil(空)測試
    XCTAssertNil. 當(dāng)expression參數(shù)非nil時(shí)報(bào)錯(cuò)。
    <code><pre>
    XCTAssertNil(expression, format...)
    </code></pre>
    XCTAssertNotNil. 當(dāng)expression參數(shù)為nil時(shí)報(bào)錯(cuò)贫途。
    <code><pre>
    XCTAssertNotNil(expression, format...)
    </code></pre>
  4. Boolean測試
    XCTAssertTrue. 當(dāng)expression計(jì)算結(jié)果為false時(shí)報(bào)錯(cuò)吧彪。
    <code><pre>
    XCTAssertTrue(expression, format...)
    </code></pre>
    XCTAssert. 當(dāng)expression計(jì)算結(jié)果為false時(shí)報(bào)錯(cuò),與XCTAssertTrue同義丢早。
    <code><pre>
    XCTAssert(expression, format...)
    </code></pre>
    XCTAssertFalse. 當(dāng)expression計(jì)算結(jié)果為true報(bào)錯(cuò)姨裸。
    <code><pre>
    XCTAssertFalse(expression, format...)
    </code></pre>
  5. 異常測試
    XCTAssertThrows.當(dāng)expression不拋出異常時(shí)報(bào)錯(cuò)。
    <code><pre>
    XCTAssertThrows(expression, format...)
    </code></pre>
    XCTAssertThrowsSpecific.當(dāng)expression針對指定類不拋出異常時(shí)報(bào)錯(cuò)怨酝。
    <code><pre>
    XCTAssertThrowsSpecific(expression, exception_class, format...)
    </code></pre>
    XCTAssertThrowsSpecificNamed. 當(dāng)expression針對特定類和特定名字不拋出異常時(shí)報(bào)錯(cuò)傀缩。對于AppKit框架或Foundation框架非常有用,拋出帶有特定名字的NSException(NSInvalidArgumentException等等)农猬。
    <code><pre>
    XCTAssertThrowsSpecificNamed(expression, exception_class, exception_name, format...)
    </code></pre>
    XCTAssertNoThrow. 當(dāng)expression拋出異常時(shí)報(bào)錯(cuò)赡艰。
    <code><pre>
    XCTAssertNoThrow(expression, format...)
    </code></pre>
    XCTAssertNoThrowSpecific. 當(dāng)expression針對指定類拋出異常時(shí)報(bào)錯(cuò)。任意其他異常都可以斤葱;也就是說它不會報(bào)錯(cuò)慷垮。
    <code><pre>
    XCTAssertNoThrowSpecific(expression, exception_class, format...)
    </code></pre>
    XCTAssertNoThrowSpecificNamed. 當(dāng)expression針對特定類和特定名字拋出異常時(shí)報(bào)錯(cuò)揖闸。對于AppKit框架或Foundation框架非常有用,拋出帶有特定名字的NSException(NSInvalidArgumentException等等)
    <code><pre>
    XCTAssertNoThrowSpecificNamed(expression, exception_class, exception_name, format...)
    </code></pre>

運(yùn)行測試并查看結(jié)果

使用Xcode測試導(dǎo)航面板料身,可以很容易的運(yùn)行測試并查看結(jié)果汤纸。有另外幾種運(yùn)行測試的交互方法。Xcode運(yùn)行測試取決于一個(gè)scheme中開啟了哪些test target芹血。測試導(dǎo)航面板讓你無需使用scheme編輯器就能直接控制那些被包含贮泞、被開啟或關(guān)閉的test target、類以及方法幔烛。

運(yùn)行測試命令

測試導(dǎo)航面板提供了快捷的方法啃擦,以將運(yùn)行測試作為編碼流程的一部分。測試同樣可以直接在源代碼編輯器里運(yùn)行或者使用product菜單運(yùn)行饿悬。
  1. 使用測試導(dǎo)航面板
    在測試導(dǎo)航面板中令蛉,將鼠標(biāo)停在測試包、類或方法名上時(shí)乡恕,會出現(xiàn)一個(gè)“Run”按鈕言询。你可以運(yùn)行某個(gè)特定測試,也可以運(yùn)行一個(gè)類中的測試或運(yùn)行一個(gè)測試包中的所有測試傲宜,這取決于列表中的鼠標(biāo)停留位置。
    將鼠標(biāo)懸停在測試包名上夫啊,并點(diǎn)擊右邊出現(xiàn)的運(yùn)行按鈕來測試一個(gè)包中的所有測試函卒。



    將鼠標(biāo)懸停在類名上,并點(diǎn)擊右邊出現(xiàn)的運(yùn)行按鈕來測試一個(gè)類中的所有測試撇眯。



    將鼠標(biāo)巡艇在測試方法名上报嵌,并點(diǎn)擊右側(cè)出現(xiàn)的運(yùn)行按鈕來測試一個(gè)單獨(dú)的測試。
  2. 使用源代碼編輯器
    當(dāng)在源代碼編輯器中打開一個(gè)測試類熊榛,每個(gè)測試方法名字旁的邊欄會明顯的指示器锚国。在指示器上懸停鼠標(biāo),出現(xiàn)一個(gè)運(yùn)行按鈕玄坦。點(diǎn)擊按鈕運(yùn)行該測試方法血筑,指示器隨后顯示該測試成功或失敗的狀態(tài)。再次將鼠標(biāo)懸停到指示器上可以再次顯示運(yùn)行按鈕來重復(fù)測試煎楣。這種機(jī)制一次只運(yùn)行一個(gè)測試豺总。

    注意:出現(xiàn)在@implementation旁邊的指示器同樣也適用于類,允許你運(yùn)行類中所有的測試择懂。
  3. 使用Product菜單
  • Product菜單包括了從鍵盤直接運(yùn)行測試的快捷命令喻喳。
  • Product>Test運(yùn)行當(dāng)前激活的方案(scheme)。鍵盤快捷鍵是Conmmand-U困曙。
  • Product>Build for>Testing和Product>Perform Action>Test without Building表伦。這兩個(gè)命令可以用來構(gòu)建測試并運(yùn)行獨(dú)立于其他的測試谦去。這是簡化構(gòu)建和測試進(jìn)程的快捷命令。對于修改了代碼并在構(gòu)建過程中檢查警告或錯(cuò)誤時(shí)蹦哼,這是特別游泳的哪轿,或者如果你知道當(dāng)前的構(gòu)建是最新的,他也可以加速測試過程翔怎。鍵盤快捷方式分別是Shift-Command-U和Control-Command-U窃诉。
  • Product>Perform Action>Test。當(dāng)你編輯一個(gè)測試方法時(shí)赤套,這個(gè)動(dòng)態(tài)菜單選項(xiàng)展示當(dāng)前光標(biāo)所處的測試方法飘痛,并允許你使用鍵盤快捷鍵方式來運(yùn)行測試。命令的名稱取決于將要運(yùn)行的測試容握,比如Product>Perform Action>Test testAddition宣脉。快捷鍵Control-Opention-Command-U剔氏。
    注意:除了源代碼編輯器塑猖,該命令還基于工程導(dǎo)航面板中的選擇情況運(yùn)行。當(dāng)人和一個(gè)導(dǎo)航面板處于激活狀態(tài)谈跛,源代碼編輯器就是去了焦點(diǎn)羊苟,并且該命令將使用任何一個(gè)導(dǎo)航面板中的當(dāng)前選擇作為輸入。在測試導(dǎo)航面板中感憾,可以選擇測試包蜡励、類、或方法阻桅。在工程導(dǎo)航面板中凉倚,可以選擇測試類實(shí)現(xiàn)文件,例如CalcTests.m嫂沉。
  • Product>Perform Action>Test Again稽寒。當(dāng)測試方法在調(diào)試/編輯代碼中暴露出問題時(shí),返回最后一個(gè)被執(zhí)行的測試方法非常有用趟章。像Product>Perform Action>Test命令杏糙,運(yùn)行的測試名稱在命令中出現(xiàn),例如Product>Perform Action>Test Again testAddition尤揣。鍵盤的快捷方式Control-Option-Command-G搔啊。

顯示測試結(jié)果

XCTest框架有幾種不同的方式在Xcode中展示測試結(jié)果。下面的屏幕截圖展示了在哪里查看這些測試結(jié)果.
  1. 在一個(gè)或一組測試運(yùn)行后北戏,你可以在測試導(dǎo)航面板中瀏覽測試通過或者失敗.



    如果測試方法被疊加到各自的類中负芋,或測試方法被折疊到測試包中,該標(biāo)識則反映了封閉測試的集合狀態(tài),表明在這個(gè)類或者包中至少有一個(gè)測試方法不通過旧蛾。


  2. 在源代碼編輯器中莽龟,你可以瀏覽測試通過或者失敗的標(biāo)識和調(diào)試信息


  3. 在報(bào)告導(dǎo)航面板中,可以通過測試運(yùn)行結(jié)果查看锨天。

    對于一個(gè)性能測試毯盈,單擊時(shí)間列中的值,獲得性能測試的詳細(xì)報(bào)告病袄。你可以通過單擊各個(gè)測試運(yùn)行按鈕搂赋,查看10次運(yùn)行的詳細(xì)信息。編輯按鈕可以修改基線和允許通過或者失敗的最大標(biāo)準(zhǔn)偏差益缠。

    日志導(dǎo)航面板中脑奠,你可以瀏覽相關(guān)的錯(cuò)誤描述和其他一些輸出摘要。點(diǎn)擊走遍的提示箭頭標(biāo)識幅慌,可以展開所有的測試運(yùn)行細(xì)節(jié)宋欺。

    注意:出了左邊展開的三角圖標(biāo),測試失敗項(xiàng)右邊的小圖標(biāo)可以展開顯示更多信息胰伍。
  4. 調(diào)試控制臺以文本形式展示了測試運(yùn)行的綜合信息齿诞。這些信息和日志導(dǎo)航面板中顯示的信息一樣。但如果你已經(jīng)處于debug狀態(tài)骂租,那么debug的輸出也會出現(xiàn)在這里祷杈。


使用Schemes(方案)和Test Target(測試目標(biāo))

Xcode Scheme控制著構(gòu)建、運(yùn)行菩咨、測試和調(diào)試這些菜單命令的行為吠式。當(dāng)創(chuàng)建Test Target并使用測試導(dǎo)航面板執(zhí)行其他測試系統(tǒng)操作時(shí),Xcode5為我們管理Scheme配置——例如抽米,當(dāng)你開啟或者關(guān)閉一個(gè)測試方法、測試類或測試包時(shí)糙置。使用Xcode Server和持續(xù)集成需要通過設(shè)置Manager Schemes頁面中的復(fù)選框來將一個(gè)Scheme設(shè)置稱共享云茸,并將其連同你的工程和源代碼導(dǎo)出到一個(gè)源文件倉庫。

Scheme配置方法如下:

  1. 選擇Scheme menu >Manage Scheme谤饭,彈出管理頁标捺。



    這個(gè)工程中有兩個(gè)Scheme,一個(gè)用來構(gòu)建應(yīng)用揉抵,一個(gè)用來構(gòu)建框架/庫亡容。右側(cè)的Share復(fù)選框用來將Scheme配置為共享,并允許Xcode Server bots使用冤今。

  2. 在管理頁中闺兢,雙擊一個(gè)Scheme,顯示Scheme Editor戏罢。一個(gè)Scheme的測試行為標(biāo)識了你執(zhí)行測試命令時(shí)Xcode執(zhí)行的測試屋谭。

    注意:測試目標(biāo)脚囊、測試類和測試方法所關(guān)聯(lián)的測試導(dǎo)航面板和配置/設(shè)置助手通常維護(hù)所有關(guān)于測試操作的Scheme設(shè)置。
    關(guān)于使用桐磁、配置和編輯Scheme的更多信息可以查看Scheme Configuration Help悔耘,或者視頻WWDC 2012:Working with Scheme and Projects in Xcode。

構(gòu)建測試-測試應(yīng)用我擂、測試庫

應(yīng)用程序在你的應(yīng)用的上下文中運(yùn)行衬以,允許你創(chuàng)建測試,這些測試結(jié)合了不同的類校摩、庫/框架和應(yīng)用功能的角度的行為看峻。庫測試獨(dú)立于你的應(yīng)用,在一個(gè)庫或框架中采用實(shí)驗(yàn)類和方法秧耗,來驗(yàn)證它們的行為符合庫的明確要求备籽。
兩種類型的測試包需要不同的構(gòu)建設(shè)置。在新的target助手中通過選擇目標(biāo)參數(shù)來創(chuàng)建test target時(shí)分井,會執(zhí)行構(gòu)建設(shè)置配置车猬。目標(biāo)助手隨著目標(biāo)下拉菜單顯示。名為SampleCalc的應(yīng)用和名為CalcLibrary的庫可供選擇尺锚。

選擇SampleCalc作為該測試目標(biāo)所關(guān)聯(lián)的構(gòu)建產(chǎn)品配置構(gòu)建設(shè)置來測試一個(gè)應(yīng)用珠闰。測試的執(zhí)行基于應(yīng)用進(jìn)程,測試在得到SampleCalc你可以根據(jù)自己的偏好改變它瘫辩。
如果你選擇CalcLibrary作為關(guān)聯(lián)的構(gòu)建產(chǎn)品伏嗜,目標(biāo)助手將會在配置構(gòu)建設(shè)置來測試庫。Xcode引導(dǎo)測試運(yùn)行時(shí)上下文和框架/庫伐厌,以及你的測試代碼-基于一個(gè)Xcode管理的進(jìn)程承绸。這種情況下默認(rèn)的產(chǎn)品名字來自于庫目標(biāo)(“CalcLibrary Tests”)。同樣你可以基于自己的喜好更改挣轨。

默認(rèn)構(gòu)建設(shè)置

大多數(shù)情況下军熏,配置構(gòu)建設(shè)置來測試應(yīng)用或庫所要做的唯一一件事就是選擇正確的測試目標(biāo)。Xcode則自動(dòng)關(guān)注構(gòu)建設(shè)置管理卷扮。因?yàn)槟憧赡苡幸粋€(gè)需要復(fù)雜構(gòu)建設(shè)置的功能荡澎,所以了解Xcode為應(yīng)用測試和庫測試所建立的標(biāo)準(zhǔn)是非常有用的。

在這里使用官方的測試demo來演示:

  1. 在工程導(dǎo)航面板中單擊SampleCalc進(jìn)入工程編輯器晤锹,然后選擇SampleCalc Tests應(yīng)用測試目標(biāo)摩幔。在編輯器的General面板中,有一個(gè)目標(biāo)快捷菜單鞭铆。該下拉菜單應(yīng)當(dāng)展示SampleCalc為目標(biāo)或衡。



    你可以檢查該構(gòu)建設(shè)置是否正確。

  2. 點(diǎn)擊構(gòu)建設(shè)置,在搜索框中輸入Bundle Loader薇宠。針對SampleCalc的應(yīng)用測試被SampleCalc App加載偷办。你可以看到針對Debug和Release的作為自定義參數(shù)的可執(zhí)行文件路徑。搜索Test Host也可以看到相同的路徑澄港。



    該工程的庫目標(biāo)名為CalcLibrary椒涯,并且已經(jīng)與名為CalcLibraryTests的測試目標(biāo)關(guān)聯(lián)。

  3. 選擇CalcLibraryTests目標(biāo)并查看General面板回梧。CalcLibrary被作為目標(biāo)废岂。


  4. 像應(yīng)用測試目標(biāo)一樣,你可以使用build Settings面板查看Bundle Loader和Test Host構(gòu)建設(shè)置狱意,下圖展示Bundle Loader搜索設(shè)置湖苞。



    在庫測試目標(biāo)的案例中,Bundle Loader和Test Host項(xiàng)目都沒有關(guān)聯(lián)的參數(shù)详囤。這表明Xcode已經(jīng)默認(rèn)正確配置了它們财骨。

測試的目的

應(yīng)用測試在OS X,iOS(真機(jī))和iOS模擬器上運(yùn)行藏姐。庫測試運(yùn)行在OS X和iOS模擬器上隆箩。Xcode Server可以通過是黨的配置源代碼倉庫,共享Scheme和bot在運(yùn)行OS X Server的Mac上運(yùn)行羔杨。更多關(guān)于Xcode Server運(yùn)行目標(biāo)的信息捌臊,請查看“Automating the Test Process with Continuous Integration”。

調(diào)試測試

所有標(biāo)準(zhǔn)的Xcode調(diào)試工具在執(zhí)行測試的時(shí)候都可以使用兜材。

測試調(diào)試工作流

要確定的第一件事情就是:造成測試失敗的原因是測試中的代碼有BUG還是執(zhí)行的測試方法存在BUG理澎。測試失敗可以指出一些不同類型的問題,即有你的假設(shè)曙寡,在測試中的代碼需求糠爬,也有測試代碼本身,所以調(diào)試測試可以橫跨幾個(gè)不同的工作流举庶。然而通常你的測試方法是相對較小和直接的秩铆,所以最好首先檢查測試的目的是什么,以及它是如何實(shí)現(xiàn)的灯变。

值得注意的一些常見的問題:

  1. 測試邏輯是否正確?實(shí)現(xiàn)是否正確捅膘?測試方法用作比較基礎(chǔ)使用的字面值添祸,檢查它們的筆誤和粗舞始終是個(gè)好主意。

  2. 假設(shè)是什么寻仗?例如刃泌,你可能在測試方法里使用了錯(cuò)誤的數(shù)據(jù)類型,創(chuàng)建了一個(gè)你所測試的代碼的范圍錯(cuò)誤。

  3. 是否使用了正確的斷言來報(bào)告耙替,“通過/失敗”狀態(tài)亚侠?例如,可能測試的狀態(tài)需要XCTAssertTure而不是XCTAsserFalse俗扇。有時(shí)候很容易造成這些錯(cuò)誤硝烂。

    假設(shè)你的測試假設(shè)是正確的,并且測試方法也正確铜幽,那么錯(cuò)誤一定在要測試的代碼中≈托唬現(xiàn)在定位并修復(fù)它。

具體的測試調(diào)試工具

Xcode有幾個(gè)工具專門用來在你測試時(shí)定位和調(diào)試代碼除抛。

  1. 測試失敗斷點(diǎn)
    在斷電導(dǎo)航面板中(BreakPoint Navigator)狮杨,點(diǎn)擊Add(加號)按鈕,選擇Add Test Failure breakpoint設(shè)置一個(gè)特殊的斷點(diǎn)到忽。



    當(dāng)測試方法觸發(fā)了失敗斷言橄教,這個(gè)斷點(diǎn)會終止測試的運(yùn)行。在測試代碼發(fā)生錯(cuò)誤點(diǎn)擊后立馬停止運(yùn)行喘漏,可以讓你快速的找到問題發(fā)生的位置护蝶。你可以看看testAddition測試方法,通過為錯(cuò)誤字符串設(shè)置用來比較的參考標(biāo)準(zhǔn)陷遮,比較字符串被強(qiáng)行斷言為失敗滓走。測試失敗斷點(diǎn)檢測該失敗斷言并停止了該點(diǎn)測試的執(zhí)行。



    當(dāng)測試終端帽馋,你也就停止了測試的執(zhí)行搅方。然后在斷言前設(shè)置一個(gè)常規(guī)的斷點(diǎn),再次運(yùn)行測試(為了簡單期間绽族,你可以在源代碼編輯器側(cè)欄中點(diǎn)擊“Run”按鈕來運(yùn)行該測試)姨涡,并繼續(xù)調(diào)試操作來修復(fù)問題。
  2. 使用工程菜單命令運(yùn)行測試
    調(diào)試測試方法時(shí)吧慢,最好記住菜單命令Project>Perform Action>Test Again和Project>Perform Action>Test涛漂。如果你正在測試失敗發(fā)生后編輯修復(fù)代碼,或運(yùn)行你正在編寫的測試方法检诗,它們提供了一個(gè)便捷的方式來測試最后一個(gè)方法匈仗。更多信息請查看“Using the Product menu”。
    當(dāng)然你也可以始終使用測試導(dǎo)航面板或源代碼編輯器側(cè)邊欄中的“Run”按鈕來運(yùn)行測試逢慌,都很方便悠轩。
  3. 輔助編輯器類別
    輔助編輯器分類中增加了兩個(gè)專門的分類來運(yùn)行特殊的測試。


  • Test Callers category攻泼。如果你修復(fù)了一個(gè)飲用測試失敗的方法火架,你可能會想要檢查該方法在其他測試中是否被調(diào)用并運(yùn)行成功鉴象。帶著這個(gè)問題,在源代碼編輯器中打開輔助編輯器何鸡,并從菜單中選擇Test Classes分類纺弊。你可以從下拉菜單定位到任何調(diào)用它的測試方法的位置,這樣你就可以運(yùn)行它們骡男,以確保你的修復(fù)沒有造成其他的問題淆游。
  • Test Classes Category。該分類和Test Callers類似洞翩,不過顯示的是包含測試方法的類列表稽犁,這些方法與主源碼編輯器中編輯類的相關(guān)。對于增加測試來說骚亿,是一個(gè)非常好的機(jī)會已亥,例如給還沒有被并入測試方法中的新方法增加測試。
  1. 測試時(shí)的異常斷點(diǎn)
    通常當(dāng)異常被異常斷點(diǎn)捕獲時(shí)就會終止測試執(zhí)行来屠,所以測試運(yùn)行時(shí)通常都會關(guān)閉異常斷點(diǎn)以避免不適當(dāng)?shù)亩ㄎ粧伋龅臄帱c(diǎn)虑椎。當(dāng)你尋找一個(gè)特定的問題并想終止測試來修復(fù)它時(shí)可以打開異常斷點(diǎn)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末俱笛,一起剝皮案震驚了整個(gè)濱河市捆姜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌迎膜,老刑警劉巖泥技,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異磕仅,居然都是意外死亡珊豹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門榕订,熙熙樓的掌柜王于貴愁眉苦臉地迎上來店茶,“玉大人,你說我怎么就攤上這事劫恒》坊茫” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵两嘴,是天一觀的道長丛楚。 經(jīng)常有香客問我,道長憔辫,這世上最難降的妖魔是什么鸯檬? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮螺垢,結(jié)果婚禮上喧务,老公的妹妹穿的比我還像新娘。我一直安慰自己枉圃,他們只是感情好功茴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著孽亲,像睡著了一般坎穿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上返劲,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天玲昧,我揣著相機(jī)與錄音,去河邊找鬼篮绿。 笑死孵延,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的亲配。 我是一名探鬼主播尘应,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吼虎!你這毒婦竟也來了犬钢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤思灰,失蹤者是張志新(化名)和其女友劉穎玷犹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洒疚,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歹颓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拳亿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晴股。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡踪蹬,死狀恐怖部服,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情筐带,我是刑警寧澤鹅经,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布寂呛,位于F島的核電站,受9級特大地震影響瘾晃,放射性物質(zhì)發(fā)生泄漏贷痪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一蹦误、第九天 我趴在偏房一處隱蔽的房頂上張望劫拢。 院中可真熱鬧肉津,春花似錦、人聲如沸舱沧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熟吏。三九已至距糖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間牵寺,已是汗流浹背悍引。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留帽氓,地道東北人趣斤。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像杏节,于是被迫代替她去往敵國和親唬渗。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

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