全棧必備 測試基礎

碼農的產品和服務大都是以軟件形式存在的,我們存在的價值之一就是快速提供高質量的軟件產品或服務。如何保障軟件的高質量呢?這與軟件測試分不開的,測試是保證軟件質量的關鍵環節之一。

老碼農早年曾經做過兩年的軟件測試,現斗膽介紹一下老碼農眼中的測試。

什么是軟件測試?

軟件測試是以評價一個程序或者系統屬性為目標的任何一種活動。測試是對軟件質量的度量。——《軟件測試完全指南》

遠在1983年,IEEE對軟件測試是:使用人工或自動的手段來運行或測定某個軟件系統的過程,其目的在于檢驗它是否滿足規定的需求或弄清預期結果與實際結果之間的差別。也就是說,軟件測試的最初目的是為了檢驗軟件系統是否滿足需求。

雖然測試是為了發現程序中的錯誤而執行程序的過程,但并不僅僅是為了找出錯誤。通過分析錯誤產生的原因和發生趨勢,還可以幫助我們發現當前軟件開發過程中的缺陷,以便及時改進。當然,沒有發現錯誤的測試也是有價值的,完整的測試是評定軟件質量的一種方法。

簡單地說,軟件測試就是證明軟件不存在錯誤的過程。

測試與QA的區別

QA是quality assurance的縮寫,也就是質量保證。軟件測試只是QA的一部分,是QA 的子集。QA的內容比測試大多了,能對產品、工作流程、組織方式等跟公司經營有關的事情進行反饋,很多外企的高層都是QA出身,尤其在制造業。
簡單的來說,測試從技術上保證軟件質量,QA從過程上保證軟件質量。

QA關注的重點不僅僅是軟件的質量,而是整個軟件過程,尤其是過程和體系,例如ISO 9000系列的質量體系等。一句話,所有和質量相關的事都是QA的事。

測試的領域

剛入行的時候,從硬件工程師轉作測試。嚴格遵循貝爾北方實驗室的軟件工程流程,將測試領域分為13個,由于年代的久遠,現在只能記得11個了。

功能性測試 functionaliy

軟件的功能性是第一要務,完成一半功能的成品也要強于完成了全部功能的半成品。 軟件實現了哪些功能?是否真正完成了這些功能呢?

健壯性測試 Robustness

健壯性是指軟件的容錯能力,違約的輸入能否導致故障的引入呢?長時間的壓測是否會導致程序異常呢?

性能測試 performance

用戶體驗至上的背后是性能至上,良好的運行性能才能滿足用戶的預期。性能測試是和時間賽跑,測試軟件的運行速度, 以及資源的使用率。

互操作性測試 interoperability

很多軟件不是孤立存在的,不能因為用戶使用了我們的軟件,導致用戶所使用的其他軟件不能正常使用,同時還要保證用戶正在使用的軟件不會對我們的軟件產出不良影響。尤其注意的是,軟件間存在相互調用的情況。

輔助性測試 Accessibility test

可用性主要針對不同用戶和不同場景。例如,前些天“餓了么”聽障騎手的故事就說明了這個問題, 可用性測試沒有過關,好在后來雪峰說新版本可以讓聽障騎手方便使用了。

易用性測試 usability

方便用戶的使用又是一個比較泛的領域。用戶的使用習慣,單雙手操作,按鈕的位置,實現目標功能的路徑深度等等,都是易用性的考量指標,有時也會把審美考慮進去。

安全性測試 security

和健康一樣,只有失去它的時候才知道它的可貴。數據源的安全,傳輸信道的安全,數據存儲的安全等等,盡管安全的重要性眾所周知,但真正為安全投入的公司并不是很多。

恢復性測試 recovery

恢復性測試一般指系統在正常或異常退出后,是否能夠恢復到之前的運行狀態。例如,很多手機都有recovery模式, 拔電源等破壞性測試有時也作為測試手段。

兼容性測試 compatibility

兼容性涉及的領域也較多。常見的如多瀏覽器測試,app的多機型測試等等,好在現在有一些云測試平臺可以幫我們解決環境的兼容性問題。 我們更多的關注軟件自身的不同版本間的兼容性,包括前向兼容和后向兼容。

發布測試 deliverable

發布測試更多是在軟件的下載,安裝,卸載等。一般地,把升級和熱更新等也放到發布測試中,包括灰度升級。

文檔完整性測試 documentation

文檔是一個老話題,程序員經常抱怨文檔不足,又往往討厭寫文檔,陷入自相矛盾中。測試文檔的完整性會被認為不那么重要,好的方式可能是從產品側解決,讓產品自身具有自解釋性,代碼也是如此。

測試的過程

測試的領域是從空間的維度對測試進行的分類,從時間的維度來看,又可以大概分為4個過程。

單元測試

單元測試:是在軟件開發過程中要進行的最低級別的測試活動,在單元測試活動中,軟件的獨立單元將在與程序的其他部分相隔離的情況下進行測試。通常情況下,單元測試(模塊測試)是RD編寫的一小段代碼,用于檢驗被測代碼的一個很小的、很明確的功能是否正確。通常而言,一個單元測試是用于判斷某個特定條件(或者場景)下某個特定函數的行為。

集成測試

集成測試也叫組裝測試或聯合測試。在單元測試的基礎上,將所有函數或程序模塊按照設計要求(如根據結構圖)組裝成為子系統或系統,進行集成測試。通常情況下,集成測試是RD進行的一種檢驗程序內部各函數或各模塊聯合起來是否存在問題的一種方式。

端到端測試

端到端測試(E2E),其實就是對多個系統進行系統測試。在端到端測試中,業務流程是最重要的,端到端測試是范圍最廣的測試。集成測試主要關注系統之間的接口。系統之間需要交換信息,所以集成測試是端到端測試的先決條件。E2E的測試并不局限于功能性。在端到端的測試環境中,需要對服務的許多非功能性屬性進行評估,如性能和安全性。

用戶場景測試

用戶場景測試是指部分真實用戶對產品或服務的真實使用測試,在過去的電信類產品中是現場測試(field trial),或者beta測試。 對互聯網產品往往是友好用戶測試(公測),或者灰度升級測試。

基于階段目的的測試

至于大家常說的黑白灰盒測試,是從產品細節的透明度來看的,程序員可以不必仔細區分。但是,對一些特定階段的測試還需給予關注。

冒煙測試 smoke test

冒煙測試是在將代碼更改簽入到產品的發布版之前對這些更改進行驗證的過程。在檢查了代碼后,冒煙測試是確定和修復軟件缺陷的最經濟有效的方法。冒煙測試用于確認代碼中的更改會按預期運行,且不會破壞整個版本的穩定性。簡單地說,冒煙測試是對軟件基本的功能進行測試,以確認基本功能正常,保證系統能跑起來,正是進入測試階段的版本必須首先通過冒煙測試的考驗。

回歸測試 regression test

回歸測試是指修改了舊代碼后,重新進行測試以確認修改沒有引入新的錯誤或導致其他代碼產生錯誤。回歸測試在整個軟件測試過程中占有很大的工作量比重,開發的各個階段都會進行多次回歸測試。在漸進和快速迭代開發中,新版本的連續發布使回歸測試進行的更加頻繁,而在極限編程等敏捷流程中,更是要求每天都進行若干次回歸測試。因此,選擇正確的回歸測試策略來改進回歸測試的效率和有效性是非常有意義的。

壓力測試 stress test

壓力測試往往被安排在測試流程中相對靠后的階段,是性能測試和健壯性測試的一部分。壓測通過確定一個系統的瓶頸或者不能接受的性能點,來確定產品或服務可以正常服務的最高性能。通過測試系統在資源超負荷情況下的表現,或者在系統資源特別低的情況下軟件系統運行情況,找到系統在哪里失效以及如何失效的地方。

其他針對專項的測試還有很多,例如面向配置的容量測試,面向安全的滲透性測試等等。

自動化測試

軟件研發敏捷性的一個重要表征就是產品的自動化測試程度。自動化測試一般是使用自動化測試工具來進行的測試,不需要人為的干預。然而,自動化測試不是把手工測試從測試過程中拋棄,也不是要用自動化測試替代掉所有的手工測試。

自動化測試的前提是有充分的測試設計和數據準備,其中測試覆蓋度完全是由測試設計來決定的,這就是測試架構師非常難得的原因之一。個人認為,自動測試更適合于相對穩定的功能測試,壓力測試,尤其是各種回歸測試。

客戶端自動化測試工具一瞥

很多客戶端平臺自帶了一些測試工具,例如Android 上的Monkey等,可以編寫腳步利用這些工具

Web 測試: Selenium

Selenium 是一組跨平臺的web應用自動化測試工具。通過使用Selenium,開發人員在不需要學習任何測試腳本語言的情況下,可以很容易地使用記錄/回放測試工具來編寫測試,讓我想起了久遠的MS-Test。


webdriver.png

Selenium 提供對眾多編程語言的支持,包括c#、Java、Groovy、Perl、PHP、Python、Ruby和各種流行的測試框架。

APP 測試:Appnium

Appium是一個開源、跨平臺的測試框架,可以用來測試原生及混合的移動端應用。Appium支持IOS、Android及FirefoxOS平臺,使用WebDriver的json wire協議,來驅動iOS系統的UIAutomation庫和Android系統的UIAutomator框架。

Appium支持Selenium WebDriver支持的所有語言,如java、Object-C、JavaScript、Php、Python、Ruby、C#、Clojure等,也可以使用Selenium WebDriver的Api。Appium支持任何一種測試框架,支持真正的跨平臺自動化測試。


appium.png

Appium采用C/S架構,客戶端對webdriver做了封裝,讀取各種語言編寫的測試腳本并轉換為測試命令發送給服務端。服務端的兩個功能,一是接收從Appium Client發送過來的命令(也就是測試用例),另一個是作為bootstrap客戶端,接收client的命令后,通過socket方式,發給目標android機器的bootstrap,驅動Uiautomator執行自動化操作。

類似的還有rebotium 等。

服務端的自動化測試工具一瞥

服務端測試包括兩部分:一種是針對web或app的服務端進行測試;另一種是針對后端的數據庫,緩存系統,中間件或文件系統等進行的測試。

請求模擬:postman

postman是Chrome的一個插件,從字面意思理解就是能夠發送POST請求的工具,是一個非常卓越的WebAPI接口測試的工具,能夠非常方便的構造Web請求并且驗證返回的結果信息。如果用瀏覽器直接請求查看接口返回結果的話,修改參數以及發送post請求時很不方便,postman就提供了這些便利。


postman.jpeg

Postman請求支持多種格式解析如JSON/XML/文本,支持管理請求包括分組、重命名等,支持導出數據包存為文件或者云存儲,而且是跨平臺的,通過api 編程接口可以實現基于postman 的自動化測試。

抓包分析:charles

Charles 常用的網絡抓包工具,通過將自己設置成系統的網絡訪問代理服務器,使得所有的網絡訪問請求都通過它來完成,從而實現了網絡包的截取和分析,配合 SSL 功能,還可以分析Https協議。Charles 支持重發網絡請求,修改網絡請求參數,支持網絡請求的截獲并動態修改,更重要的是支持模擬慢速網絡。


charles.png

當然,也可以使用其他sniffer 工具配合wireshark 完成傳輸鏈路的自動化測試。

壓力測試:AB

壓測的工具很多,ab、http_load、webbench、siege等等。ab是apache自帶的壓力測試工具,是apachebench命令的簡稱。它非常實用,它不僅可對apache服務器進行訪問壓測,也可以對其它類型的服務器進行壓測,比如nginx、tomcat等。


ab.png

ab命令會創建多個并發訪問線程,模擬多個訪問者同時對某一URL地址進行訪問。ab命令對發出負載的計算機要求很低,它既不會占用很高CPU,也不會占用很多內存,卻會給目標服務器造成巨大的負載,其原理類似CC攻擊。使用時需要注意的是,在剛開始壓測的時候,負載不要太大,否則可能造成目標服務器資源耗完,嚴重時甚至導致死機。

對應更加完備的壓測,可以使用LoadRunner 等其他商業工具軟件。

面向測試的開發

對于程序員來講,測試是保證高質量軟件的關鍵手段之一。將質量思維融入開發流程,可以采用測試驅動開發(TDD)的極限編程方法,從業務入手,以測試先行的方法來反向推動代碼的實現。

簡單的說,就是每當需要添加一個新功能,或修改現有功能時,首先思考這部分代碼期望達到的輸入與輸出,先把驗證該業務的單元測試用例寫出來,再去寫最簡單的實現代碼來通過該測試;不斷重復此過程直到完成整個功能。

典型的TDD開發步驟如下:

  1. 分析并確定一個目標場景
  2. 用一個單元測試來驗證該場景的輸入輸出
  3. 運行該測試,得到失敗的測試結果
  4. 以最簡單的功能代碼來通過該測試
  5. 再次運行該測試,測試通過
  6. 進行代碼重構,包括功能代碼和單元測試代碼
  7. 重復以上步驟,直至開發完成

在TDD中遵循一切從簡的原則,以業務為導向,隔離目標場景,通過重構改進代碼的可讀性,可維護性,減少冗余代碼等。同時維護一個測試列表 - 在開始開發之前,先列出所有需要的測試,并在開發中不斷維護該列表,避免遺忘一些必要的測試。提高效率,不需要另外單獨的文檔,而是在測試類中對每個測試方法對應的業務場景,輸入和期望的輸出進行詳細的描述。

由于測試先行,并達到足夠的覆蓋率,確保代碼都經過了測試,有利提高代碼質量。 TDD產生的測試就是對系統的一套完整的說明文檔, 還能夠產生一組完備的測試套件,這讓團隊可以更加自信得去進行代碼重構。同時大大提高回歸測試的頻率,同時減少所花費的時間,避免產生冗余的,沒有用的代碼,減少對代碼 Debugging 的時間。 將一個功能分解為一個個可以測試的更小單元,能夠產生更小的,更清晰的,更加責任明確的類,更加松耦合的組件和清晰的接口。

ATDD是TDD的變種,TDD是基于單元測試的,而ATDD面向用戶驗收測試的。
在準備實施一個功能前,首先定義出期望的質量標準和驗收細則,以及明確且達成共識的驗收測試計劃,以此來驅動開發人員的TDD實踐和測試人員的測試腳本開發。對開發團隊來說,ATDD 是由外向內,多方介入的,基于拉動策略的,并行開發測試方法;確保所有交付的產品都經過了充分的測試。

另外,BDD是TDD的補充,更適用于高級別的業務需求和驗收標準。通過用戶故事定義需求,BDD定義的用戶故事可以作為開發過程中的統一標準,促進開發人員、測試人員及用戶共同協作。Cucumber是一個BDD自動化測試框架,提供了對自然語言定義行為及步驟的支持。在執行用例時,會通過行為和步驟定義自動調用步驟定義內的代碼運行。同時,提供了良好的斷言機制,當執行失敗時,可以清晰的看到測試用例的執行步驟,明確失敗原因。

事情都有兩面性,沒有銀彈。TDD產生的代碼質量取決于測試的質量,不正確的測試會產生錯誤的代碼,業務場景覆蓋不充分的測試液會產生功能不完整的代碼。更重要的是,TDD只適用于輸入輸出明確的開發項目,不適用于某些探索性的,輸出不確定的開發,比如人工智能,安全等領域的研發。 另外在某些環境,TDD實施會有一些困難,例如異步通信等,需要一些額外的輔助工具,增加了復雜性。

也就是說,TDD不是萬能的,不能完全依賴TDD提高質量。TDD既無法替代集成測試、性能測試等,也不能讓程序沒有bug。關鍵一點,TDD不適合所有項目,要求需求必須足夠清晰,模型和依賴特別復雜的項目也不太行。

小結

No test, No quality。 質量在很多時候是產品存亡的關鍵因素,沒有質量的產品很難說什么用戶體驗。作為一個程序員,要把質量思維融入到開發中,對測試做到胸中有數。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,814評論 25 708
  • 1.測試與軟件模型 軟件開發生命周期模型指的是軟件開發全過程、活動和任務的結構性框架。軟件項目的開發包括:需求、設...
    Mr希靈閱讀 21,984評論 7 278
  • 1.測試與軟件模型 軟件開發生命周期模型指的是軟件開發全過程、活動和任務的結構性框架。軟件項目的開發包括:需求、設...
    宇文臭臭閱讀 6,745評論 5 100
  • 文/李衛星 本周是新學期開學的第一周,周五下午是我們學校初中部全體教師例會的時間。會議由教務處孫主任主持,會議內容...
    生命主宰閱讀 1,083評論 4 4
  • 歷史原因,項目 app debug 與 release 版本需要使用不同簽名,使用Eclipse切換簽名文件較為復...
    dongbingliu閱讀 1,692評論 0 4