摘要:而且,構造函數不應該包含行為,所以沒有值得測試的東西。一旦一個被創建了,你測試它的不為空因為你知道構造函數創建了一個新的并將它賦給了變量。現在為類的構造函數編寫的測試出問題了,即便類運行良好,但并沒有包括。
在研究了有關測試的相關內容,發現有些被忽略掉的很明顯的問題。
1、為什么需要測試從積極的方面來說,寫自動化測試的優勢如下:
使重構更簡單 —— 你可以自信的修改實現細節,而不用去觸及公有 API。
避免代碼惡化—— 惡化在什么時候發生?在你修改代碼的時候。
提供了可執行的說明和文檔 —— * 你在什么時候更想知道軟件實際上是如何工作的?在你想修改它們的時候
減少了創建軟件的時間 —— 怎么減少時間的?是通過更快速地修改你的代碼,出錯時測試會自信地告訴你哪里出錯了
降低了創建軟件的代價 —— 好吧,時間就是金錢,我的朋友
其實上述優勢最大的就是,當我們需要優化代碼,進行修改時,會給予我們一種保障。所以在自動化測試的支撐下,我們需要做的就比較簡單了。
2、測試的最佳實踐指導有 5 條被認為是每個測試都應該遵守的基本原則。便于記憶這 5 條規則的縮寫是: F.I.R.S.T.
測試應該:
壞的實踐很快速(Fast) —— 測試應該能夠被經常執行。
能隔離(Isolated) —— 測試本身不能依賴于外部因素或者其他測試的結果。
可重復(Repeatable) —— 每次運行測試都應該產生相同的結果。
帶自檢(Self-verifying) —— 測試應該包括斷言,不需要人為干預。
夠及時(Timely) —— 測試應該和生產代碼一同書寫。
不要測試私有方法
私有方法意味著私有。如果你感到有必要測試一個私有方法,那么那個私有方法一定含有概念性錯誤,通常是作為私有方法,它做的太多了, 從而違背了單一職責原則
如果僅僅為了測試,就讓私有方法變為公有,那么就會改變方法的私有性,會有被其他類調用的風險。那么應該該如何去做呢。
通過這個類的公有 API。永遠通過公有 API 測試你的代碼。程序的公有 API 定義了一個約定,它是一組關于你的程序對應于不同輸入時定義良好的一組期望。私有 API (私有方法或者整個類) 并沒有定義約定,并且可以不經通知自行修改,所以你的測試 (或者你的同事) 不能依賴于它們。
通過這種方法測試你的私有方法,你可以自由地修改你的 (真正的) 私有代碼,并且通過劃分成只做一件事情,并經過正確測試的小的類,來提升代碼的設計。
不要Stub 私有方法
Stub 私有方法和測試私有方法具有相同的危害,更重要的是,stub 私有方法將會使程序難以調試。
同樣,當我們 stub 一個方法的時候,我們必須依據它做出的約定來進行。但是私有方法沒有指定的約定的 —— 畢竟,這也是為什么它們是私有的原因。由于私有方法的行為可以不經通知自行修改,你的 stub 可能與實際情況背道而馳,但是你的測試仍然會通過。這是多么的可怕啊,讓我們來看一個例子:
今天:一個類的公有方法依賴于該類的一個私有方法。這個私有方法 foo 永遠不會返回空。為公有方法編寫的測試為了方便起見,我們 stub 出了私有方法。當 stub foo 方法的時候,你永遠不會考慮到 foo 返回為空的情況,因為現在這種情況永遠不會發生。
明天:這個私有方法被修改了,現在它返回空了。它是一個私有方法,所以這沒什么問題。為公有方法編寫的測試不會相應地被修改 (“我正在修改一個私有方法,所以我為什么要更新我的測試?”)。公有方法現在在私有方法返回空的情況下會出錯,但是測試仍然會通過!
不要 Stub 外部庫
第三方代碼不應該在你的測試中直接出現。
今天:你的網絡部分的代碼依賴于著名的 HTTP 庫 LSNetworking.為了避免使用實際的網絡 (為了讓你的測試更快速更可信),你 stub 了那個庫中的方法 -[LSNetworking makeGETrequest:],沒有通過實際的網絡合適地替代了它的行為 (它通過一個封裝好的響應調用了執行成功的回調)。
明天:你需要使用一個替代品來取代 LSNetworking (可能是 LSNetworking 已經不再維護或者是你需要換成一個更先進的庫,因為它有很多你需要的新特性等等)。這是一次重構,所以你不應該修改測試。你替換了庫。你的測試會失敗,因為依賴的網絡沒有被 stub (-[LSNetworking makeGETrequest:]不會被調用)。
應該做什么:測試中,依靠 stubbing 傘 (umbrella stubbing) 來替代那個庫的全部功能。
stubbing 傘 (一個我剛剛發明的術語) 包括了對于所有你的代碼可能用到的方式 -- 不管事現在還是將來 -- 的 stub。它們可以通過良好聲明的 API 完成一些任務,而不去關心實現的細節。
不要測試構造函數
構造函數定義的是實現細節,你不應該測試構造函數,這是因為我們認同測試應該與實現細節解耦這一觀點。而且,構造函數不應該包含行為,所以沒有值得測試的東西。
今天:你有一個 Car 類,并包含一個構造函數。一旦一個 Car 被創建了,你測試它的 Engine 不為空 (因為你知道構造函數創建了一個新的 Engine 并將它賦給了變量 _engine)。
明天:Engine 類創建起來變得代價很高,所以你決定使用延遲初始化 (lazily initialize),在第一次調用 Engine 的 getter 方法時才初始化 Engine (這是很好的)。 現在為 Car 類的構造函數編寫的測試出問題了,即便 Car 類運行良好,但 Car 并沒有包括 Engine。另一個可能是你的測試不會失敗,因為測試包含 Engine 的 Car 類會觸發 Engine 的延遲加載。所以我的問題是:為什么還要測試?
3、如何進行測試Given / When / Then模式
我們可以根據 Given-When-Then 模式來組織我們的測試用例,將測試用例拆分成三個部分。
在 given 部分里,通過創建模型對象或將被測試的系統設置到指定的狀態,來設定測試環境。when 這部分包含了我們要測試的代碼。在大部分情況,這里只有一個方法調用。在 then 這部分中 ,我們需要檢查我們行為的結果:是否得到了我們期望的結果?對象是否有改變?這部分主要包括一些斷言。簡單一點來講就是,設定環境、調用方法、檢測結果。
簡單的例子看起來是這個樣子的:
- (void)testThatItDoesURLEncoding { // given NSString *searchQuery = @"$content$amp;?@"; HTTPRequest *request = [HTTPRequest requestWithURL:@"/search?q=%@", searchQuery]; // when NSString *encodedURL = request.URL; // then XCTAssertEqualObjects(encodedURL, @"/search?q=%24%26%3F%40"); }
這種簡單的模式使我們能夠更容易地書寫和理解這些測試用例,因為它們都遵循了同樣的模式。為了更快地瀏覽,我們甚至會在每個部分的代碼上寫上 “given”,“when”,“then” 的注釋。通過這種方式,這個方法就能很快被理解。
Mock
在iOS測試中的mock測試框架可以采用OCMock。
我們用 mock 來管理一個對象的所有依賴項。通過這個方式,我們可以測試這個類在隔離情況下的行為。但是這里有個明顯的缺點,那就是當我們修改了一個類后,其他依賴于這個類的類的單元測試不能自動失敗。但是關于這一點我們可以通過集成測試來補救,因為它可以測試所有的類。
我們不應該‘過度mock’,也就是說,去 mock 除了被測試的對象的其他對象這樣的習慣是要盡量避免的。當我們剛開始的時候,我們經常會這樣做,我們甚至會 mock 那些簡單到可以作為方法參數的對象。現在我們使用了不少真實的對象,而不是 mock 它們。
4、編寫測試是一種投資我們需要花時間編寫和維護它們。我們可以證明這種投資有回報的唯一方法就是我們期望節省時間。將實現細節和測試耦合在一起會減少測試帶來的回報,使得那些投資變得不合算,甚至在某些情況下變得一文不值。
在編寫測試、重構以及修改系統行為的時候,檢查你的測試在面對錯誤的原因時是失敗還是通過,然后退一步問問自己,那些測試是否能夠最大化你投資的成果
測試代碼量會比被測試代碼還要多
目前為止,我們的編碼庫已經縱橫 190 個文件和 18,000 行代碼,達到了 544 kB。我們測試部分的代碼現在差不多有1,200 kB,大概有被測試代碼的兩倍。雖然我們還沒有完全結束這個項目,但是已經接近尾聲。
引用文章
Real-World Testing with XCTest
Bad Testing Practices
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/8749.html
摘要:正是因為這樣的協議存在一些自動化測試框架可以使用多種語言編寫測試腳本。支持了所有的主流瀏覽器,同時還支持了和的移動應用測試。接下來就帶著大家一步一步使用進行進行自動化測試全局安裝的如果覺得比較慢,就換淘寶的鏡像吧。 Macaca macaca是阿里開源的基于Node.js開發的自動化測試工具,支持native,hybird,moblie web,關于macaca具體的內容參見官網mac...
摘要:,部分設備支持功能,在啟用功能后,系統會對內存進行壓縮,增加,會相應減少,由于壓縮會占用資源,同時相應會導致降低虛擬內存整機可用剩余內存,極限測試情況下開啟可能會造成性能損耗。 一、PerfDog簡介 PerfDog性能狗是移動全平臺iOS/Android性能測試工具,快速定位分析性能問題,...
摘要:本文目的是通過自己寫的一個的簡單的庫花密密碼生成工具,來學習我認為的庫開發的一些規范,以及上持續構建你的項目的一些方法。給自己的項目開啟持續構建。包發布以及當你的代碼完成后,測試完成后。 本文目的是通過自己寫的一個php的簡單的庫(花密密碼生成工具), 來學習我認為的php庫開發的一些規范,以及github上持續構建你的項目的一些方法。其實是為了顯示下邊一系列的的徽章 showImg(...
摘要:王者榮耀項目組高級測試工程師工程師文化團隊中的實踐本文不是一篇入門教程,而是從結合實際場景,闡述在團隊協作中如何去好好地應用。 CI Weekly 圍繞『 軟件工程效率提升』 進行一系列技術內容分享,包括國內外持續集成、持續交付,持續部署、自動化測試、 DevOps 等實踐教程、工具與資源,以及一些工程師文化相關的程序員 Tips 。同步于 flow.ci Blog、微信公眾號、官方微...
閱讀 1551·2023-04-26 02:29
閱讀 3016·2021-10-11 10:58
閱讀 2894·2021-10-08 10:16
閱讀 3155·2021-09-24 09:47
閱讀 1563·2019-08-29 16:56
閱讀 2711·2019-08-29 11:03
閱讀 1992·2019-08-26 13:35
閱讀 3167·2019-08-26 13:34