你真的懂測試嗎?從“用戶登錄”測試談起

可能你會說,“用戶登錄”這個測試對象也有點太簡單了吧,我只要找一個用戶,讓他在界面上輸入用戶名和密碼,然後點擊“確認”按鈕,驗證一下是否登錄成功就可以了。的確,這構成了一個最基本、最典型的測試用例,這也是終端用戶在使用系統時最典型的Happy Path場景。

但是作爲測試工程師,你的目標是要保證系統在各種應用場景下的功能是符合設計要求的,所以你需要考慮的測試用例就需要更多、更全面,於是你可能會根據“用戶登錄”功能的需求描述,結合等價類劃分和邊界值分析方法來設計一系列的測試用例。

那什麼是等價類劃分和邊界值分析方法呢?首先,這二者都隸屬於最常用、最典型、也是最重要的黑盒測試方法。

  • 等價類劃分方法,是將所有可能的輸入數據劃分成若干個子集,在每個子集中,如果任意一個輸入數據對於揭露程序中潛在錯誤都具有同等效果,那麼這樣的子集就構成了一個等價類。後續只要從每個等價類中任意選取一個值進行測試,就可以用少量具有代表性的測試輸入取得較好的測試覆蓋結果。
  • 邊界值分析方法,是選取輸入、輸出的邊界值進行測試。因爲通常大量的軟件錯誤是發生在輸入或輸出範圍的邊界上,所以需要對邊界值進行重點測試,通常選取正好等於、剛剛大於或剛剛小於邊界的值作爲測試數據。

從方法論上可以看出來,邊界值分析是對等價類劃分的補充,所以這兩種測試方法經常結合起來使用。

現在,針對“用戶登錄”功能,基於等價類劃分和邊界值分析方法,我們設計的測試用例包括:

  1. 輸入已註冊的用戶名和正確的密碼,驗證是否登錄成功;
  2. 輸入已註冊的用戶名和不正確的密碼,驗證是否登錄失敗,並且提示信息正確;
  3. 輸入未註冊的用戶名和任意密碼,驗證是否登錄失敗,並且提示信息正確;
  4. 用戶名和密碼兩者都爲空,驗證是否登錄失敗,並且提示信息正確;
  5. 用戶名和密碼兩者之一爲空,驗證是否登錄失敗,並且提示信息正確;
  6. 如果登錄功能啓用了驗證碼功能,在用戶名和密碼正確的前提下,輸入正確的驗證碼,驗證是否登錄成功;
  7. 如果登錄功能啓用了驗證碼功能,在用戶名和密碼正確的前提下,輸入錯誤的驗證碼,驗證是否登錄失敗,並且提示信息正確。

列出這些測試用例後,你可能已經覺得比較滿意了,因爲你感覺已經把自己的測試知識都用在這些用例設計中了。

的確,上面的測試用例集已經涵蓋了主要的功能測試場景。但是在一個優秀的測試工程師眼中,這些用例只能達到勉強及格的標準。

什麼?纔剛剛及格?如果你有這個想法,那我建議你在繼續看下面的內容前,先仔細思考一下,這些測試用例是否真的還需要擴充。

現在,我跟你分享一下有經驗的測試工程師會再增加的測試用例:

  1. 用戶名和密碼是否大小寫敏感;
  2. 頁面上的密碼框是否加密顯示;
  3. 後臺系統創建的用戶第一次登錄成功時,是否提示修改密碼;
  4. 忘記用戶名和忘記密碼的功能是否可用;
  5. 前端頁面是否根據設計要求限制用戶名和密碼長度;
  6. 如果登錄功能需要驗證碼,點擊驗證碼圖片是否可以更換驗證碼,更換後的驗證碼是否可用;
  7. 刷新頁面是否會刷新驗證碼;
  8. 如果驗證碼具有時效性,需要分別驗證時效內和時效外驗證碼的有效性;
  9. 用戶登錄成功但是會話超時後,繼續操作是否會重定向到用戶登錄界面;
  10. 不同級別的用戶,比如管理員用戶和普通用戶,登錄系統後的權限是否正確;
  11. 頁面默認焦點是否定位在用戶名的輸入框中;
  12. 快捷鍵Tab和Enter等,是否可以正常使用。

看完這些用例,你可能會說:“哇塞,原來一個簡簡單單的登錄功能居然有這麼多需要測試的點”。但是,你別高興得太早,“用戶登錄”功能的測試還沒結束。

雖然改進後的測試用例集相比之前的測試覆蓋率的確已經提高了很多,但是站在資深測試人員的角度來看,還有很多用例需要設計。

經我這麼一說,你可能已經發現,上面所有的測試用例設計都是圍繞顯式功能性需求的驗證展開的,換句話說,這些用例都是直接針對“用戶登錄”功能的功能性進行驗證和測試的。

但是,一個質量過硬的軟件系統,除了顯式功能性需求以外,其他的非功能性需求即隱式功能性需求也是極其關鍵的。

顯式功能性需求(Functional requirement)的含義從字面上就可以很好地理解,指的是軟件本身需要實現的具體功能, 比如“正常用戶使用正確的用戶名和密碼可以成功登錄”、“非註冊用戶無法登錄”等,這都是屬於典型的顯式功能性需求描述。

那什麼是非功能性需求(Non-functional requirement)呢?從軟件測試的維度來看,非功能性需求主要涉及安全性、性能以及兼容性三大方面。 在上面所有的測試用例設計中,我們完全沒有考慮對非功能性需求的測試,但這些往往是決定軟件質量的關鍵因素。

明白了非功能性需求測試的重要性後,你可以先思考一下還需要設計哪些測試用例,然後再來看看我會給出哪些用例,相信這種方式對你的幫助會更大。

安全性測試用例包括:

  1. 用戶密碼後臺存儲是否加密;
  2. 用戶密碼在網絡傳輸過程中是否加密;
  3. 密碼是否具有有效期,密碼有效期到期後,是否提示需要修改密碼;
  4. 不登錄的情況下,在瀏覽器中直接輸入登錄後的URL地址,驗證是否會重新定向到用戶登錄界面;
  5. 密碼輸入框是否不支持複製和粘貼;
  6. 密碼輸入框內輸入的密碼是否都可以在頁面源碼模式下被查看;
  7. 用戶名和密碼的輸入框中分別輸入典型的“SQL注入攻擊”字符串,驗證系統的返回頁面;
  8. 用戶名和密碼的輸入框中分別輸入典型的“XSS跨站腳本攻擊”字符串,驗證系統行爲是否被篡改;
  9. 連續多次登錄失敗情況下,系統是否會阻止後續的嘗試以應對暴力破解;
  10. 同一用戶在同一終端的多種瀏覽器上登錄,驗證登錄功能的互斥性是否符合設計預期;
  11. 同一用戶先後在多臺終端的瀏覽器上登錄,驗證登錄是否具有互斥性。

性能壓力測試用例包括:

  1. 單用戶登錄的響應時間是否小於3秒;
  2. 單用戶登錄時,後臺請求數量是否過多;
  3. 高併發場景下用戶登錄的響應時間是否小於5秒;
  4. 高併發場景下服務端的監控指標是否符合預期;
  5. 高集合點併發場景下,是否存在資源死鎖和不合理的資源等待;
  6. 長時間大量用戶連續登錄和登出,服務器端是否存在內存泄漏。

兼容性測試用例包括:

  1. 不同瀏覽器下,驗證登錄頁面的顯示以及功能正確性;
  2. 相同瀏覽器的不同版本下,驗證登錄頁面的顯示以及功能正確性;
  3. 不同移動設備終端的不同瀏覽器下,驗證登錄頁面的顯示以及功能正確性;
  4. 不同分辨率的界面下,驗證登錄頁面的顯示以及功能正確性。

說到這裏,你還會覺得“用戶登錄”功能的測試非常簡單、不值一提麼?一個看似簡單的功能測試,居然涵蓋了如此多的測試用例,除了要覆蓋明確的功能性需求,還需要考慮其他諸多的非功能性需求。

另外,通過這些測試用例的設計,你也可以發現,一個優秀的測試工程師必須具有很寬廣的知識面,如果你不能對被測系統的設計有深入的理解、不明白安全攻擊的基本原理、沒有掌握性能測試的基本設計方法,很難設計出“有的放矢”的測試用例。

通過“用戶登錄”功能測試這個實例,我希望可以激發你對測試更多的思考,並且開拓你設計測試用例的思路,以達到拋磚引玉的效果。

看完了這些測試用例,你可能會說還有一些遺漏的測試點沒有覆蓋到,這個功能的測試點還不夠全面。那麼,接下來我再跟你說說測試的不可窮盡性,即絕大多數情況下,是不可能進行窮盡測試的。

所謂的“窮盡測試”是指包含了軟件輸入值和前提條件所有可能組合的測試方法,完成窮盡測試的系統裏應該不殘留任何未知的軟件缺陷。 因爲如果有未知的軟件缺陷,你可以通過做更多的測試來找到它們,也就是說你的測試還沒有窮盡。

但是,在絕大多數的軟件工程實踐中,測試由於受限於時間成本和經濟成本,是不可能去窮盡所有可能的組合的,而是採用基於風險驅動的模式,有所側重地選擇測試範圍和設計測試用例,以尋求缺陷風險和研發成本之間的平衡。

總結

首先,對於高質量的軟件測試,用例設計不僅需要考慮明確的顯式功能性需求,還要涉及兼容性、安全性和性能等一系列的非功能性需求,這些非功能性需求對軟件系統的質量有着舉足輕重的作用。

其次,優秀的測試工程師必須具有寬廣的知識面,才能設計出有針對性、更易於發現問題的測試用例。

最後,軟件測試的用例設計是不可窮盡的,工程實踐中難免受制於時間成本和經濟成本,所以優秀的測試工程師需要兼顧缺陷風險和研發成本之間的平衡。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章