麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

[iOS翻譯]《iOS7byTutorials》系列:在Xcode5里使用單元測試(上)

2019-11-14 20:24:41
字體:
供稿:網(wǎng)友

簡介:

單元測試是軟件開發(fā)的一個重要方面。畢竟,單元測試可以幫你找到bug和崩潰原因,而程序崩潰是Apple在審查時拒絕app上架的首要原因。

單元測試不是萬能的,但Apple把它作為開發(fā)工具包的一部分,不僅讓你創(chuàng)作的APP更穩(wěn)定,而且提供了一致、有趣的用戶體驗,這些都是讓用戶給你五星評價的源泉!iOS7提供了一個升級的單元測試框架,讓你在Xcode中運(yùn)行單元測試更為容易。當(dāng)你完成這一章節(jié),你將學(xué)會如何給現(xiàn)有app添加測試——并有可能培養(yǎng)出對編寫測試的熱愛!

/*

本文翻譯自《iOS7 by Tutorials》一書的第十一章“Unit Testing in Xcode 5”,想體會原文精髓的朋友請到Raywenderlich商店支持正版。

——————(博客園、新浪微博)葛布林大帝

*/

 

目錄:

一、單元測試基礎(chǔ)

二、開始項目

三、下一步何去何從?

四、挑戰(zhàn)

附錄:XCTest斷言參考

 

一、單元測試基礎(chǔ)

在過去,Xcode引入了一個叫做OCUnit的開源單元測試框架。而在Xcode 5里面,Apple發(fā)布了他們自己的的單元測試框架,叫做XCTest。

如果你已經(jīng)熟悉OCUnit,別擔(dān)心,XCTest是一個建立在OCUnit之上并且十份相似的API。從OCUnit過渡到XCTest非常簡單,要做的僅僅是把STFail替換為XCTFail、STAssert替換為XCTAssert等等諸如此類。如果你已經(jīng)熟悉這些基礎(chǔ),可以直接跳到下一節(jié)。

 

 

1.高層次概述

 

 單元測試有四個層級。從上到下,它們分別是:

 

  • 測試套件(Test suite)
    • 這是項目里測試的全部集合。在Xcode里,測試套件被設(shè)置為一個單獨的build target。
  • 測試用例類(Test case classes)
    • 正如你可能所期待的,在一個面向?qū)ο篌w系中,測試被整合到類里。在你的app里,每個測試類通常對應(yīng)一個單獨類。例如,DeveloperTests類應(yīng)該對應(yīng)Developer類的測試。
  • 測試用例方法(Test case methods)
    • 每個測試類包含多種方法,用來測試類的各種功能。就像一個方法或函數(shù)應(yīng)該既精簡又實用,每個測試用例應(yīng)該測試一個特定的結(jié)果——并且完全測試。
  • 斷言(Assertions)
    • 斷言檢查對應(yīng)預(yù)期結(jié)果的具體條件。如果條件不符合預(yù)期結(jié)果, Xcode會報錯指出斷言失敗。例如,可以斷言你的Developer 類響應(yīng)“writeKillerApp: message”;如果它沒有,斷言失敗,Xcode報錯。

 

 

理論很美好,但有時舉例會更容易闡述事物。用Empty application 模板創(chuàng)建一個新項目,命名為EmptyApp。 Xcode模板會自動包含一個叫做EmptyAPPTests的test target,添加到EmptyApp的 app target里,如下圖:

 

注意測試用例類包含了一個沒有關(guān)聯(lián)頭文件的.m文件,打開EmptyAppTests.m看看第一個測試用例的源代碼。

測試方法必須以單詞test開始,以便test runner能找到它們。在你的示例項目里,測試類包含了一個測試方法,叫做testExample

 

setUptearDown方法就像守護(hù)在測試用例周圍的衛(wèi)兵一樣。

把所有對象的程序設(shè)置代碼或重復(fù)性代碼放到setUp里,使測試用例方法保持清爽、高效。

類似的,關(guān)閉文件句柄或取消掛起網(wǎng)絡(luò)請求等清理活動的方法應(yīng)該放到tearDown里。

 

Test runner 會依次調(diào)用setUp、testExample和tearDown方法。如果你申明了第二個測試方法testSecondExample,Test runner會依次調(diào)用setUp、testSecondExample,最后是tearDown方法。如果你有多個測試方法,setUp和tearDown會在一個測試環(huán)節(jié)調(diào)用多次——每經(jīng)過一個測試用例方法調(diào)用一次!

 

這個故事的寓意是不要放任何處理太慢或處理頻繁的東西到setUp或tearDown方法里——這會讓你運(yùn)行測試套件時面臨漫長的等待

 

 

 

2.創(chuàng)建你的第一個測試

 

 

testExample方法只有一個叫做XCTFail的語句,正如它名字里暗示的:總是會失敗。這個語句不是非常有用,你可以寫一個比它更好的!刪除testExample方法,并添加如下方法:

- (void)test_addition_twoPlusTwo_isFour 
{  XCTAssert(
2 + 2 == 4, @"2 + 2 should be 4 but %d was returned instead", 2+2);}

測試用例的一個常用命名標(biāo)準(zhǔn)是:unitOfWork_stateUnderTest_expectedBehavior (工作單元_測試狀態(tài)_預(yù)期行為)。

在這個例子里,被測試的工作單元是加法,測試狀態(tài)是2 + 2,預(yù)期行為是結(jié)果為4。

所有XCTest斷言都有前綴XCT。XCTAssert是可用于單元測試的簡單斷言,第一個參數(shù)是預(yù)評估為ture的表達(dá)式,當(dāng)斷言失敗時,其后NSLog風(fēng)格的參數(shù)會顯示一條消息。

 

確保項目的當(dāng)前target為iphone模擬器,通過窗口頂部目錄的PRoduct -> Test(Command-U)來運(yùn)行測試,模擬器會啟動并執(zhí)行測試套件。如果通知處于激活狀態(tài),你會看到下列確認(rèn)消息:

 

 

為了證實第一個單元測試成功,切換到Test Navigator,箭頭指出了它:

哈哈!翠綠色的小勾旁邊顯示出了你的單元測試。

你還可以看到邊框空白處菱形圖標(biāo)旁的代碼,如下所示:

這些圖標(biāo)展示關(guān)聯(lián)測試代碼的狀態(tài):

@implementation旁的綠色小勾表示這個類測試通過,test_addition_twoPlusTwo_isFour旁的綠色小勾表示這個方法測試通過。

同時,這些圖標(biāo)也是按鈕:

點擊@implementation旁的圖標(biāo)將會運(yùn)行這個類的所有測試,點擊其他測試方法旁的圖標(biāo)則會運(yùn)行該測試方法,試一試吧!

 

現(xiàn)在你已經(jīng)對測試的概念和執(zhí)行有了初步了解,是時候開始本章的示例項目了——測試開始!

 

二、開始項目

本章的剩余部分你將使用一個名為Reversi的黑白棋游戲項目,規(guī)則:兩個玩家,分別代表白方和黑方,輪流在8x8棋盤上落子。通過包圍對方棋子來吃掉它,游戲結(jié)束時棋子最多的為勝者。

如何創(chuàng)建這個游戲,請看:http://www.raywenderlich.com/29228/how-to-develop-an-ipad-board-game-app-part-12

下載本文頁尾提供的示例項目并運(yùn)行,點擊屏幕下方的Vs Computer按鈕與電腦進(jìn)行對戰(zhàn),感受一下這個游戲的界面和玩法。

你獲勝了嗎?或者被AI對手爆出翔?不管怎樣,你的工作不是整日玩游戲——是時候添加一些有用的測試到項目里了。

 

1.添加測試的支持

第一個需要單元測試的是GameBoard類。這個類囊括了8x8棋盤的基本邏輯,64個單元格中的每個都有一個狀態(tài)——空、黑棋或白棋——并且GameBoard實例讓你能獲取并設(shè)置每一個方塊的狀態(tài)。 

打開GameBoard.h看一下里面的方法,在開始為現(xiàn)有代碼編寫測試之前,弄清楚各方法的作用和實現(xiàn)是一個好主意。

GameBoard.h,你會看到下列兩個方法:

// gets the state of the cell at the given location// raises an NSRangeException if the column or row are out of bounds- (BoardCellState) cellStateAtColumn:(NSInteger)column andRow:(NSInteger)row;// sets the state of the cell at the given location// raises an NSRangeException if the column or row are out of bounds- (void) setCellState:(BoardCellState)state forColumn:(NSInteger)column andRow:(NSInteger)row;

cellStateAtColumn:andRow: 和 setCellState:forColumn:andRow: 由你非常熟悉的getter/setter模式里發(fā)展出來,你的第一個測試是執(zhí)行如下動作:

  • 初始化一個GameBoard實例
  • 設(shè)置cell狀態(tài)
  • 獲取cell狀態(tài)
  • 從指定的cell里獲取cell狀態(tài)

 

第一步是創(chuàng)建一個GameBoard測試類,右擊ReversiGameTests分組,選擇 iOS/Cocoa Touch/Objective-C test case class 創(chuàng)建一個名為GameBoardTests的測試類,繼承自XCTestCase。

確保你的新測試用例添加到ReversiGameTests target,如下圖(這個步驟非常重要,如果沒添加到正確的target里,你的測試不會運(yùn)行):

 

打開 GameBoardTests.m 并且刪除 testExample 方法,你不需要它。

然后在 GameBoardTests.m 頂部導(dǎo)入頭文件(這僅僅是讓你的測試類能夠訪問GameBoard類):GameBoard.h 

#import "GameBoard.h"

 

你需要為你的所有測試提供一個GameBoard 實例,創(chuàng)建一個實例變量會比在每個測試?yán)锷昝饕粋€清爽得多。

GameBoardTests.m 里更新@interface 如下:

@interface GameBoardTests : XCTestCase 
{

  GameBoard *_board;}

現(xiàn)在你有了_board實例變量,可以開始測試了。

 

setUp 方法是第一次初始化_board的好地方,修改setUp如下:

- (void)setUp{  [super setUp];  _board = [[GameBoard alloc] init]; }

現(xiàn)在這個類的所有測試用例方法都能夠訪問初始化后的_board實例變量了。

 

2.第一個測試

這是你需要為首個測試用例添加的所有步驟,添加以下方法到GameBoardTests.m

- (void)test_setAndGetCellState_setValidCell_cellStateChanged {  [_board setCellState:BoardCellStateWhitePiece forColumn:4 andRow:5];
  BoardCellState retrievedState = [_board cellStateAtColumn:4 andRow:5];
  

  XCTAssertEqual(BoardCellStateWhitePiece,           retrievedState,           @"The cell should be white!");}

上面的代碼在(4,5)單元格里設(shè)置了一個白棋,并且立刻檢索了相同單元格的狀態(tài)。XCTAssertEqual 斷言檢查它們是否相等,如果不相等,你會看到一個異常信息,然后你將得知有一些東西需要檢查。

上面代碼的方法名遵循我之前提到的格式,通過這個方法名,你可以很容易看出它通過設(shè)置正確的單元格位置來測試setter和getter方法,并期待單元格狀態(tài)的改變。

 

如果你的測試工作是有計劃的,確保iPhone和iPad模擬器都測試,然后運(yùn)行測試(Command-U)。

切換到Test Navigator,你會看到一個綠色小勾表示測試通過,如下圖:

這看起來只是一個簡單的測試,但是它在調(diào)試錯誤里提供了巨大的價值。

 

在內(nèi)部, GAMEBOARD類使用一個簡單的二維數(shù)組來跟蹤8X8棋盤。但如果你曾經(jīng)改變了代表向量或矩陣的數(shù)組,本次測試將作為回歸測試,確保interface 的基礎(chǔ)仍在工作。

作為一個附帶的好處,為現(xiàn)有的類編寫測試可以大大有助于理解代碼是如何工作的。分析類的方法可以幫助你辨別其功能,并為你編寫測試提供便利。

 

3.測試異常

按照設(shè)計的功能測試代碼有助于確保其正確性,但也使得你的app“早早失敗或高調(diào)失敗”——那些異常游戲狀態(tài)或無效條件被調(diào)試器很快抓住。

GameBoard.h里cellStateAtColumn:andRow: 和 setCellState:forColumn:andRow: 方法的注釋表明,如果行或列超出棋盤邊框,它們會彈出錯誤。看起來你已經(jīng)找到更多的測試條件。

添加下列兩個方法:

- (void)test_setCellState_withInvalidCoords_exceptionThrown {XCTAssertThrowsSpecificNamed([_board setCellState:BoardCellStateBlackPieceforColumn:10andRow:7], NSException,NSRangeException,@"Out-of-bounds board set should raise an exception");}- (void)test_getCellState_withInvalidCoords_exceptionThrown {XCTAssertThrowsSpecificNamed([_board cellStateAtColumn:7 andRow:-10],NSException,NSRangeException,@"Out-of-bounds board access should raise an exception");}

上面的代碼里,test_setCellState_withInvalidCoords_exceptionThrown: 試圖設(shè)置超出范圍的單元格(10,7),同時test_setCellState_withInvalidCoords_exceptionThrown: 試圖獲取超出范圍的單元格(7,-10)。再次的,方法名已指出在正測試不正確的坐標(biāo),報出異常正在意料之中。

 

XCTAssertThrowsSpecificNamed 采用以下四點作為參數(shù):

  • 應(yīng)該報出異常的表達(dá)式
  • 排除的類
  • 排除的名稱
  • 測試失敗時顯示的消息

點擊Command-U運(yùn)行測試,你應(yīng)該看到以下結(jié)果

這是什么?你希望用出色的代碼通過測試,但是兩個錯誤標(biāo)記在Issue Navigator上。測試失敗信息也會顯示在代碼上,如下圖:

 

所有的測試失敗消息為:

[GameBoardTests test_getCellState_withInvalidCoords_exceptionThrown] failed: (([_board cellStateAtColumn:7 andRow:-10]) throws <NSException, "NSRangeException">) failed: throwing <NSException, "NSGenericException", "row or column out of bounds"> - Out-of- bounds board access should raise an exception

如果你分解上面的消息,你會看到你希望的行為是(throws <NSException, "NSRangeException">) ,而實際發(fā)生的是(throwing <NSException, "NSGenericException">) 。

在這個例子里,你期待的是NSRangeException ,但接收到的卻是NSGenericException 。

看起來你已經(jīng)做了一些研究!

 

示例項目地址:http://pan.baidu.com/s/1o6x6zxg

 

 

 

 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美成人免费看 | 亚洲va久久久噜噜噜久久男同 | 亚洲av一级毛片特黄大片 | 久久久一二三 | 国产精品一区在线看 | 北原夏美av | 一级毛片免费高清 | 国产成人精品无人区一区 | 成人在线观看地址 | 天天天干夜夜夜操 | 粉嫩粉嫩一区二区三区在线播放 | 国产资源视频在线观看 | 99综合视频 | 97精品国产高清在线看入口 | 欧美三级美国一级 | 黄网站色成年大片免费高 | 色污视频 | 欧美一级二级毛片视频 | 亚洲国产一区二区三区 | 久久精品无码一区二区日韩av | 国产精品一区在线观看 | 欧美黄 片免费观看 | 国产亚洲精品综合一区91 | 亚洲成人免费网站 | 国产在线观看一区二区三区 | 草莓福利社区在线 | 亚洲一区二区中文字幕在线观看 | 3344永久免费 | 久久精品久久精品国产大片 | 极品国产91在线网站 | 精品在线视频播放 | 国产精品亚洲欧美 | 羞羞视频2023 | 久草视频福利在线观看 | 在线成人免费视频 | 亚洲第一成人久久网站 | 性爱视频免费 | 国产精品一区久久久久 | 午夜热门福利 | 免费午夜视频在线观看 | 美女毛片在线观看 |