全棧必備 測試基礎

weixin_34054866發表於2018-01-06

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

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

什麼是軟體測試?

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

遠在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。


73516-b9915e720c2723f8.png
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支援任何一種測試框架,支援真正的跨平臺自動化測試。


73516-18f869ad1e6d9f8e.png
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就提供了這些便利。


73516-3e619660b3be6acc.jpeg
postman.jpeg

Postman請求支援多種格式解析如JSON/XML/文字,支援管理請求包括分組、重新命名等,支援匯出資料包存為檔案或者雲端儲存,而且是跨平臺的,通過api 程式設計介面可以實現基於postman 的自動化測試。

抓包分析:charles

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


73516-952422a58686f34b.png
charles.png

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

壓力測試:AB

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


73516-5d340c18790f7133.png
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。 質量在很多時候是產品存亡的關鍵因素,沒有質量的產品很難說什麼使用者體驗。作為一個程式設計師,要把質量思維融入到開發中,對測試做到胸中有數。

相關文章