- Web測試囧事
- 黃勇等
- 1529字
- 2019-01-05 03:43:29
提到測試,大家首先會想到的就是功能性的測試,因為只有保證了產品的基本功能和流程,產品才具備給用戶提供使用價值的能力,從而才有可能確定產品的核心競爭力。基于這一點,不僅測試人員和開發人員,還有產品經理、項目經理、業務方對功能完備性和正確性的重視程度也往往都是最高的。這也使得功能測試成為任何測試類型的基礎。
在進行功能測試時,我們會使用諸如邊界值分析、等價類劃分、因果分析、組合測試(Pairwise Testing)等測試方法來設計和規劃測試用例,但是這些方法大多都是從書本上學來或者從別的渠道了解到的理論方法。而實際上在一個真實的項目中如何運用,或者如何在特定的場景和情境下使用這些方法,去充分發揮這些測試方法的作用,并幫助我們高效地設計和執行測試用例卻是更重要的問題。
正因如此,我們在功能測試部分并沒有介紹這些方法是什么,而重點在于展示在一個具體的場景下,讀者應該如何思考,怎么把理論知識和實際工作結合起來,以發現和避免可能遇到的陷阱。
功能測試部分的故事篇幅都會比較長,希望讀者能夠每讀完一個故事,都留出一段時間進行思索和回味,從而理解故事的核心,觸類旁通。
為了讓每一章的故事更凝練,我們把功能測試部分分成了4章,分別是:技術篇、測試覆蓋篇、測試實踐篇和業務需求篇。這4章從Web開發流行的各種技術(例如響應式設計、特性開關、虛擬化等)、測試技術(例如實例化需求、集成測試、契約測試等)、測試實踐(例如探索性測試、回顧會議、缺陷大掃除等)和業務需求(例如用戶的并發操作、關聯操作以及產品功能的一致性等)方面向讀者全方位展示功能測試范疇中的常見問題和解決辦法,更重要的是指引大家從一步一步的分析中得到解決問題的思路。
本章(技術篇)介紹了在開發和測試的技術方面引起的11個功能測試問題,現在大家和我們一起來看看這些豐富多彩的故事。
1.1 輸入框中輸入超過最大允許值造成頁面跳轉溢出
作為計算機系畢業生的小蔡,一直覺得學校里學的理論知識和現在的測試工作差距太大,在實際的工作中也沒有什么作用,直到有一天她碰到這么一個有趣的問題。
小蔡負責測試的是一個Web產品,基于不同的搜索條件會顯示大量的結果。由于搜索結果太多,所以頁面有分頁功能,為了方便用戶快捷跳轉到特定的頁面,開發人員特意設計了一個頁面快速跳轉的功能(見圖1-1)。

圖1-1 搜索結果頁面快速跳轉
在設計測試用例的時候小蔡就留心了,因為很多測試理論的書籍都描述過,對于輸入框可以進行的驗證點很多,比如:特殊字符、超長字符、負值、0值和null值,以及很大的數值等。小蔡發現,對于大部分的測試用例,開發人員都處理得很好,沒有發現缺陷,她也就松了口氣。
但是,當她測試到輸入大數值的測試用例時,由于不確定多大的數值會出錯,也不能拿到代碼,小蔡就探索性地選了一個數值:9999999999(10個“9”)。當輸入10個“9”點擊“確定”按鈕時,突然頁面崩潰了!她仔細回想剛才的測試過程:100以內的小數值,以及輸入小于等于搜索結果頁面數的數值等情況,測試結果都很正常。那到底數值大到什么程度的時候頁面會崩潰呢?一時想不到更好的辦法,小蔡只好硬著頭皮嘗試著定位出錯的數值范圍。
她發現,當輸入10個“9”就會出錯,而輸入9個“9”,頁面正常跳轉到最后一頁。突然,小蔡想起來數據結構課程不是學過很多查找法嘛!這樣,二分法就這么出現在了眼前,對,二分查找法(見圖1-2)! 5000000000(9個“0”),出錯;2500000000(8個“0”),正常。她還是沒有線索,可是她堅持這么一點一點查找。最后花了將近3個小時,小蔡終于定位到了出錯的數值:4294967295。這個時候,小蔡很納悶,怎么是這么一個奇怪的數值呢?有零有整的。計算機專業的背景給了小蔡一個提示,不會是2的多少次冪吧?果真,4294967295是232-1。當小蔡收集到這些線索之后和開發人員一溝通,才發現由于開發人員設想頁面最大不會超過232,所以對這個字段可以輸入的最大數值的類型,選擇的是int32。但是,開發人員并沒有對超過這個范圍的數值進行任何的處理,這就造成了程序判斷中請求更大數值頁面時的溢出,從而導致了產品頁面的崩潰。

圖1-2 二分查找的原理
提示
二分查找算法(binary search)或者折半查找算法,是一種在有序數組中查找某一特定元素的搜索算法。
搜索過程從數組的中間元素開始,如果中間元素正好是要查找的元素,則搜索過程結束;如果某一特定元素大于或者小于中間元素,則在數組大于或小于中間元素的那一半中查找,而且跟開始一樣從中間元素開始比較。如果在某一步驟數組為空,則代表找不到。這種搜索算法每一次比較都使搜索范圍縮小一半。
發現了這個隱藏的缺陷,小蔡很有成就感,但又覺得如果能早點知道代碼的邏輯,可能自己就不會花這么長的時間了。同時,小蔡一直覺得計算機的理論知識不會應用到測試實踐中,可沒想到這次多虧了學校中學到的這些基礎知識,不只是int32,232,甚至還有二分查找算法也給了自己解決問題的靈感。沒有這些知識,定位問題就更困難了。
核心知識:邊界值分析法
邊界值分析法是一種常見的黑盒測試方法。
測試界的前輩們通過分析常見Bug,發現絕大多數的Bug都出現在輸入/輸出范圍的邊界處。因此,如果能夠針對這些邊界來設計用例,通常能夠更加有效。
邊界值測試法通常是作為等價類測試法的補充,和等價類測試法結合起來用。即每個等價類的邊界部分就可以作為邊界值的測試用例之一。
舉個例子。假設有一個日期選擇器(date picker)的需求,要求我們能夠輸入時間后,點擊搜索查詢輸入日期前后一年范圍內的數據。假設我們把輸入的時間分為如下幾個等價類:
1)正常時間范圍內:now-1年< test data < now+1年;
2)正常時間范圍外:test data < now-1年或者test data > now+1年
3)特殊時間:例如now=2月29,1970/01/01等
4)輸入非時間的input value:比如輸入值為@等
……
結合分類1、2,這個時候邊界值的取值則可以取:
▼test data=now-1年;
▼test data=now+1年;
▼test data=now-1年-1天;
▼test data=now-1年+1天
……
考慮到輸出范圍是一整年的數據,結合特殊時間和時間的邊界(跨年、跨月等),還可以增加
▼test data=2月29
▼test data=12月31號
▼test data=1月1號
……
總之,邊界值的取值,應該著重考慮邊界情況。如果測試對象是時間,則應該重點考慮跨年、跨月等;如果測試對象是純數字,則應該重點考慮數字的類型與取值范圍;如果測試對象是數據表,則應該重點考慮數據表設計的字段長度,等等。
拓展知識:測試用例設計
測試用例記錄了測試的過程,我們可以通過測試用例了解哪些場景已經被驗證了,哪些場景還沒有被驗證。除此之外,在傳統的測試行業中,測試用例數量通常也被作為度量測試工作量和指定測試工作計劃的重要輸入。
測試用例通常會包含幾個基本要素:用例編號、輸入數據、期望結果以及前置條件等。測試覆蓋率則是評價測試用例好壞的關鍵標準。覆蓋率高的測試用例能夠提高開發、產品以及其他驗收人員對產品的信心。在設計過程中,我們通常會通過邊界值、等價類等測試方法,結合配對組合測試(pairwise testing),基本路徑分析法等測試策略優化測試用例,以達到提升測試覆蓋率和減少冗余測試用例的方法。
以下是測試用例設計原則。
1)測試用例的代表性:能夠代表并覆蓋各種合理的和不合理的、合法的和非法的、邊界的和越界的以及極限的輸入數據、操作和環境設置等。
2)測試結果的可判定性:即測試執行結果的正確性是可判定的,每一個測試用例都應有相應的期望結果。
3)測試結果的可再現性:即對同樣的測試用例,系統的執行結果應當是相同的。
1.2 索引值計算錯誤使資源縮略圖顯示和大圖展現不一致
業務方希望在商品展示的頁面,不僅能添加展示圖片,還可以展示關于商品的視頻(見圖1-3)。

圖1-3 商品展示頁面支持展示圖片和視頻
業務方希望通過圖1-3下方的統一翻頁操作,實現無縫瀏覽圖片和視頻。如果商品既有圖片又有視頻,當用戶在瀏覽圖片時,在圖1-3右下角顯示“Video”(視頻),這時用戶可以通過點擊“Video”鏈接打開第一個視頻;同樣當用戶在瀏覽視頻時,在圖1-3右下角顯示“Image”(圖片),這時用戶可以通過點擊“Image”鏈接打開第一張圖片。
小蔡按照通常的步驟編寫完測試用例,開始使用標準測試數據執行測試。小蔡首先發現點擊右下角鏈接時,本應該顯示第1張圖片或者視頻,但是打開的卻是第2張圖片或者視頻。
小蔡覺得這可能是開發人員在處理圖片和視頻展示的數組時,使用的是自然數計數,從1開始作為第1個數據項,而非計算機程序數組中通常使用的把從0開始計數作為第一個數據項。當小蔡把這一問題上報之后,開發人員發現確實是這個原因,并進行了快速修正。
小蔡在開發人員新發布的包上又一次進行了測試,這次測試用例基本沒有什么問題,她就開始在類真實環境中執行探索性測試,結果發現在某些商品頁面進行圖片和視頻跳轉時,出現圖片或視頻顯示錯誤或者顯示成空白的問題。
在老牛的協助下,小蔡發現了問題出現的兩個規律:①當從第n張圖片切換到視頻的時候,系統顯示的并不是用戶期待的第1個視頻,而是第n個視頻;②當商品的圖片和視頻數量不一致,從數量多的資源切換到另一個數量少的資源時,內容就會出現空白。
小蔡和老牛都覺得出現問題的原因比較明確了,是因為在圖片和視頻跳轉時,打開資源的索引值并沒有清零,而是保存著前一個元素的索引值。
為什么這個問題在測試環境中沒有發現,而在類真實環境中才被發現?原來最初小蔡在測試環境中執行測試用例的時候,使用的是基本測試數據,圖片和視頻都只有兩個,而且兩張圖片和兩個視頻的內容分別都是一樣的,因此不會出現這個問題。
小蔡和老牛商量了下,決定為了避免遺漏這樣的問題,需要豐富測試環境的測試數據,使得測試數據更像真實數據,這樣測試結果才更為準確。
同時他們認為這個問題在開發人員的開發過程中也是不應該引入的,因為這樣的錯誤比較初級。于是小蔡和開發人員進行了溝通,發現引入該問題的根源在于開發人員的疏忽。由于圖片的文件格式和視頻的文件格式不同,所以開發人員使用了兩個庫來支持圖片和視頻的打開,但是兩個庫之間的跳轉需要通過在兩個庫之間傳遞參數來實現,然而開發人員并沒有仔細檢查兩個庫之間所傳遞的參數,導致并不需要被傳遞的索引值也傳遞到另一個庫中。
老牛帶著小蔡和開發人員立下一個約定:在使用第三方庫實現功能時,一定要把使用的函數方法中的所有參數都核對清楚。
核心知識①:探索性測試
探索性測試(Exploratory Testing)是軟件測試方法的一種。這種方法強調測試者的主觀能動性,以及測試設計和測試執行的同時性。目的是探索開發更多不同形態的測試方法,以便改善測試流程。
“先設計,再測試”的傳統做法,通常是先分析出測試點,然后針對測點設計好測試方法,最后執行測試。這種模式也帶來了一些問題,比如在測試目標不確定的情況下(改需求、輸出范圍過大等)經常可能出現測試遺漏等,而且在一定程度上也限制了測試思維的發散。而探索性測試的出現,正好彌補了傳統測試中出現的這種問題。
探索式軟件測試一共分為自由式探索式測試、基于場景的探索式測試、基于策略的探索式測試和基于反饋的探索式測試。
(1)自由式探索
純粹從使用的角度出發,拋開規則、模式,測試人員可以以任意順序和方式對軟件進行使用測試。這種測試通常會被選作快速冒煙測試用例。
(2)基于場景的探索式測試
這種測試跟傳統基于場景的測試比較像,不同的是,在這種測試中測試人員會擴大測試范圍。例如,對某搜索框的測試,傳統的場景測試用例可能是:
1)輸入“電視”,期望結果是搜索到電視;
2)輸入“123”,搜索到123相關的內容。
而基于場景的探索性測試下,測試場景則可能是:
1)輸入“電視”,探索搜索結果;
2)粘貼“ 1@3”,搜索結果;
3)輸入一個亂碼,搜索結果;
4)輸入電視,搜索結果后回退到搜索首頁再搜索;
……
(3)基于策略的探索性測試
這是一種比較依靠經驗的測試方式。簡單講就是測試老手,融合自己的經驗、技能、感知等條件,結合自由式探索性測試,用自己積累下來的知識來指導測試。是一種經驗結合隨機性的測試。
(4)基于反饋的探索性測試
反饋指的是當測試人員對被測程序做出指令后得到的響應結果。基于這個結果,測試人員可以調整自己的輸入,以期望得到不同的結果。例如,在基于場景的探索性測試的描述中,輸入電視和輸入電冰箱會得到不同的結果,而其中電視的搜索結果就是對電視這個輸入的反饋,電冰箱的結果就是對電冰箱這個輸入的反饋。
核心知識②:軟件開發中的各種環境
1)開發環境:就是每個開發人員進行編程的電腦,包括軟硬件及其配置,為了開發調試方便,一般打開全部錯誤報告。
2)測試環境:測試人員進行產品部署,并進行功能等測試的環境。
3)預生產環境(非必須):與生產環境不定期同步,保持和生產環境的設置、數據的一致性,也是用于測試的環境。與測試環境的最大區別就是它和生產系統同步性最高,有些比如數據遷移測試,用這個環境測試比測試環境(一般情況下數據較少)更準確。
4)生產環境:正式使用的系統環境,一般會關掉錯誤報告,打開錯誤日志。
通常情況下,一個環境對應一個服務器,不同環境代表著系統開發的不同階段:開發→測試→部署→上線。
1.3 測試Web Service能否正常提供JSON數據
某一天,小蔡所在的項目組剛開發完成一個Web Service,服務的功能是,通過在客戶端調用時指定的一個ID,可以從后臺數據庫中讀取對應的房產信息,還有與這個房產關聯的一到多個房東信息、一到多個圖片信息,以及地址信息等。Web Service最終把這些信息組合成JSON格式的數據返回給調用方,調用方可以通過界面來展示相關信息,也可以通過其他方式去使用這些信息。但是,調用方具體如何使用這些信息與Web Service服務本身的測試關系不大,所以暫且不表了。小蔡需要做的是驗證這個Web Service服務能否正常地提供JSON數據。
1.尋找測試關鍵點
和開發人員討論后,小蔡了解到,給Web Service服務發送ID后,后臺系統會根據這個ID去查詢數據庫,數據庫對應的對象模型如圖1-4所示。

圖1-4 生成JSON的對象模型
在這個對象關系圖里可以看到,Building對象是圖的核心,其他對象分別和Building對象是一對一或者一對多的關系。那么小蔡覺得,測試的關鍵點就是這些數據之間的關系能否正確反映在生成的JSON數據里。(特別是要確保生成的JSON數據的格式沒有被破壞,否則解析器就無法解析JSON數據了。)
2.爬樓梯開始了
在確定好測試點之后,小蔡測試思路如下。
1)依據邊界值進行測試。由于數據庫的數據存在多種情況:0條記錄、單條記錄、多條記錄,需要驗證根據這些數據條數生成的JSON文件是否正確。
2)需要關注對象之間的關聯關系限制。例如一個Building對應0到4個Callout,那么需要測試當多于4個Callout時,生成的JSON的情況。
3)Web Service允許用戶輸入參數,所以需要驗證輸入特殊數據后,系統是否出現異常或者崩潰的現象,以及是否會出現SQL注入的問題。
4)Web Service有可能會被多個客戶端并發調用,因此需要驗證其性能是否符合設計要求。
根據測試思路,小蔡設計了如下測試用例。
1)Building對象可以有多個Space,所以可以選取0個、1個、6個Space去看生成的JSON是否正確,這個可以通過修改數據庫數據的方式生成假數據去完成相關測試。另外,如圖1-4所示,小蔡還需要測試Building和其他對象的關系,包括Customer、MediaLink等。小蔡還特別注意了邊界值測試,比如,一個Building對應0~4個Callout,那么可以用0、1、4、5個Callout去測試。當有5個Callout的時候,要去查看返回的JSON數據是返回了前4個Callout,還是返回了前5個,又或者拋出了異常,當然,具體哪種結果是程序設計所期望的,需要和開發人員去溝通。
2)調用Web Service時需要指定ID,所以可以測試在ID存在和不存在兩種情況下JSON結果是否返回正常。
3)異常處理,調用Web Service時可以把ID換成錯誤的參數,例如null、非常長的字符串、空字符串、英文字符、其他文字(例如中文字符)等。接著小蔡就去驗證服務對異常是否做出了正確的處理。
4)安全測試,這個Web Service會被外網使用,那就需要在安全性上投入更多的測試。例如,如果URL可以輸入任何參數,這些參數是否包含危險數據導致SQL注入這類安全問題。還有,因為Web Service被外網使用,那在調用這個服務時是否需要提供用戶名和密碼。
JSON使用了一種特殊描述數據的方式,用“, ”、“[”、“]”、“{”、“}”等分割數據,小蔡需要測試,如果數據庫存儲的數據恰好有這些符號,這些數據被讀取并生成為JSON后是否會破壞JSON的格式。
5)性能測試,如何對Web Service進行性能測試呢,快速測試方式就是通過一些工具的多線程調用,或者手工編寫簡單多線程代碼去調用,然后查看持續調用兩小時之后服務是否正常,服務后臺內存曲線是否出現異常,有沒有出現內存泄露等問題。另外,查看Web Service是否能在符合性能期望的時間內返回數據。
還有一個邊緣的性能測試路徑是:一個對象有成千上萬個關聯子對象,能否正常生成對應的JSON文件,以及性能是否能達到期望目標。慶幸小蔡這次測試任務不需要這么做,因為后臺數據明確了不可能存在這種情況,但是在別的測試任務中可能需要測試。
提示
假設一種大數據量的場景,如果關聯的對象有10萬個,我們可以通過工具在數據庫中生成10萬條數據。這時候,生成的JSON文件可能會有幾十兆,那么我們要看需求文檔,對這種場景期待的性能指標是多少,例如單個用戶調用的話5分鐘之內需要生成完畢,20個用戶并發情況下10分鐘生成完畢。我們需要驗證是否5分鐘或者10分鐘內能生成完畢,同時還要驗證,在這個過程中,后臺內存增長曲線是否出現過于陡峭的現象。
6)查看生成的JSON數據中,一些特殊類型的數據是否和數據庫完全一致。例如,對于float類型,有個Bug是該類型數據精度在數據庫中是保存到小數點后8位,但生成的JSON中只保留小數點后2位;類似的特殊數據還包括非常長的字符串,需要查看是否被截斷;如果在數據庫中保存的是0,在JSON中是否會生成0.00,此外還可以查看空字符串是否正確生成在JSON中。
7)確定服務是否需要支持HTTPS加密,如果需要,就要去測試返回結果是否正常。
哈哈!終于爬完樓梯了,小蔡可以松口氣了,走!喝杯啤酒,再來塊炸雞么?
1.4 利用JavaScript加載的漏洞提前購買搶購商品
自從小米手機推出以來,搶購風潮在各類網站上盛行起來,小蔡測試的網站自然也不能免俗,項目組開發的網站也包含了搶購功能。
對于搶購來說,只有到了特定的時間后,商品才會開放并允許搶購,并且搶購網頁的代碼里使用的時間會定期和服務器進行同步。
小蔡設計了豐富和全面的測試用例,在執行基礎測試用例過程中沒有發現搶購功能的Bug,不過在進行多地區和多語言的性能測試時,她發現了一個功能上的漏洞,發現漏洞的過程是這樣的。
在執行性能測試時,需要選取不同國家和地區的服務器去模擬用戶的真實訪問,以驗證產品性能是否能滿足用戶體驗的要求。顯然,通過這些不同國家和地區的服務器訪問網站,會比小蔡在公司內部使用內網訪問速度慢,更別提有些國家和地區網絡發展慢,這些區域的訪問速度就更慢了。
然而正是通過使用這些網速很慢的服務器,小蔡發現了這個功能上的漏洞。
1)在高速或者說正常網速的情況下,當用戶打開搶購商品的頁面時,頁面JavaScript會很快加載并執行完成,這時“加入購物車”的按鈕會變灰,無法進行操作(見圖1-5)。

圖1-5 正常網速,等JavaScript加載完成之后“加入購物車”不能操作
2)而當網速很慢時,由于網頁中JavaScript是順序加載執行的,所以“加入購物車”按鈕先會顯示為可以操作的狀態,等JavaScript加載完成后,才會變灰,不可操作(見圖1-6)。

圖1-6 慢速網絡,在JavaScript加載完成之前“加入購物車”按鈕可以操作
3)所以在慢速網絡中,當頁面JavaScript沒有加載完成時,用戶會看到“加入購物車”按鈕是可用狀態,因此用戶可以點擊該按鈕,并把搶購商品加入購物車,于是用戶就可以在正式搶購開始之前順利地搶到該商品了。實際上甚至在商品無貨的情況下,用戶也可以在JavaScript沒有加載完時點擊“加入購物車”按鈕,并且成功把無貨商品加入購物車(見圖1-7和圖1-8)。

圖1-7 慢速網絡,無貨的商品也可以添加到購物車

圖1-8 慢速網絡,無貨的商品也可以支付購買
這個問題是由JavaScript沒有加載完成引起的,但是稍懂技術的人甚至可以禁用瀏覽器的JavaScript,或者通過查看網絡訪問的URL后,在按鈕是灰色的狀態下也有可能提交購買請求。所以,修改這個Bug時,還需要在提交訂單時做二次驗證,去驗證該商品是否有貨,或者是否已經處于搶購狀態,當狀態為“是”的時候,才允許后續操作。
當小蔡把這個問題提交給開發人員和產品經理后,經過大家的討論,發現如果調整商品頁面上的JavaScript加載順序,會涉及很多JavaScript文件的修改,影響范圍會很廣,包括移動頁面上的代碼也需要大幅修正,因此整體工作量比較大。鑒于剛才提到的在提交訂單時做二次驗證也能避免這樣的問題,所以他們一致決定采取做二次驗證這種方案來進行修復。
拓展知識:JavaScript的加載與執行
瀏覽器的渲染線程和JS執行線程是互斥的,并且JavaScript默認是阻塞加載的。頁面的下載和渲染都必須停下來等待腳本執行完成。JavaScript執行過程耗時越久,瀏覽器等待響應用戶輸入的時間就越長。
(1)加載
不管是script標簽直接引入的情況,還是src加載的外部資源,都會阻塞頁面的渲染。所以一般為了從體驗上考慮,我們會將JS文件放置在body標簽閉合之前。不過新版的IE、Firefox、Safari和Chrome都允許并行下載JavaScript文件。但是只是JavaScript文件可以并行下載,渲染還是被阻塞的,頁面仍然必須等待所有JavaScript代碼下載并執行完成才能繼續。
(2)執行
每當JavaScript文件加載完成后,都會立刻執行該文件。所以你會看到下一次的請求并不是在上一次請求結束之后立即開始,中間的耗時就是上一個腳本文件的執行時間。
一般對于JavaScript的優化建議如下。
1)將script腳本文件放置在body標簽閉合之前。
2)減少script請求數量。
3)無阻塞腳本,在頁面加載完成后才加載JavaScript代碼。這就意味著在window對象的onload事件觸發后再下載腳本。
▼Defer, async。
▼動態添加script元素。
不過在上面這個故事中,正是由于對JavaScript的優化引發了搶購頁面先顯示元素可操作,然后在JavaScript加載完成后,JavaScript執行使元素不可操作。
1.5 過長的控件名稱造成其他元素顯示錯位
小蔡接到一個公司內部在線表單項目的測試任務,這個項目中有3個獨立的角色:管理員A負責編輯和布局表單控件,用戶B負責填寫表單中控件的內容,而審核員C只能查看B操作后的結果。
這個需求看上去不難,小蔡快速分析并且記錄了以下幾個測試點,開始了測試工作。
1)A可以正常添加不同類型控件(文本框、富文本框、下拉列表、多選框、單選框等)到頁面中。
2)B可以正常在這些控件中輸入數據。
3)C可以正常查看B所有的操作內容。
4)針對各個角色所具有的不同的操作權限進行驗證。
5)A更新表單后,B要可以看到對應的變化。
6)A未完成操作或者未保存的表單,B是無法看到和使用的。
7)B不保存后者提交操作結果,C無法看到B的操作內容。
8)跨瀏覽器和跨平臺測試。
在測試過程中,小蔡發現這個表單做的類似于我們熟知的Office應用的所見即所得的形式,即A在屏幕左上方放置一個多選框并保存后,B打開頁面后也可以在屏幕左上方看到一個多選框,最后C登錄后也可以在屏幕左上方看到這個多選框。這使得整個功能變得更加容易測試,幾乎是瞥一眼就能看到有沒有問題。
三下五除二就跑完用例,小蔡正準備結束測試,偶然間一眼瞥到表單上的多選框選項上,她突然意識到既然多選框和單選框中的選項內容都是自己定義的,那在選項內容中輸入超長字符串時,會不會導致該控件的顯示位置發生變化呢?
帶著這個疑問,小蔡重新使用A角色設置了一個超長的多選框選項名稱,然后用B角色做了勾選操作,最后再用C去查看結果。結果她發現了問題:C查看到的結果中,勾選后的內容和多選框顯示錯位了。
再仔細重現了一遍問題后,小蔡發現A在編輯模式給多選框設置超長的選項名稱的時候,在界面上多選框的位置被擠到了文本中央,如圖1-9所示。

圖1-9 表單編輯界面
B在操作視圖中看到的這個多選框又被強制對齊到了文字最左側,如圖1-10所示。

圖1-10 表單操作界面
而C在審核視圖中看到的情況卻是A和C的結合體,即多選框被重置到了文字中央,而被勾選的位置卻出現在文字的最左端(見圖1-11)。

圖1-11 操作結果查看頁面
有了小蔡的過程重現,開發人員很快就定位到出現問題的原因:首先是在A用戶使用的過程中(見圖1-9),沒有把操作結果查看視圖中的多選框強制左對齊。其次是在用戶C使用過程中(見圖1-11),由于使用jQuery定制化多選框中的代碼邏輯錯誤,導致勾選狀態下的可勾選位置和多選框本身出現了分離,最終導致問題出現。
核心知識:常見的HTML元素及常見檢查點
1)<select>標簽,可創建單選或多選菜單。
常見檢查點:下拉列表數據的正確性;數據被選中是否正確,是否變形,是否只讀,多選/單選是否正確。
2)<label>標簽,相當于一個展示文本框。
常見檢查點:文本是否正確;文本字體、大小、顏色、間距是否正確;for屬性是否綁定了正確的元素等。
3)<input>標簽,用于收集用戶信息。
根據不同的type屬性值,輸入字段擁有很多種形式。可以是文本字段、復選框、掩碼后的文本控件、單選按鈕、按鈕等。
4)button可點擊的按鈕,點擊后通常會觸發相應事件。
常見檢查點:點擊按鈕后觸發的行為和期望不符合;頁面卡死未響應;點擊后變形等。
5)text文本輸入。
常見檢查點:是否只讀;SQL注入攻擊;輸入內容超過文本框長度是否引起形變等。
6)checkbox多選框。
常見檢查點:選中/取消勾選是否有效;文本長度過長是否引起形變;頁面刷新后是否被自動取消/勾選等。
7)radio單選框。
常見檢查點:單選是否有效;文本長度過長是否引起形變;頁面刷新后是否被自動取消/勾選等。
8)image圖片區域。
常見檢查點:圖片加載是否正確;圖片加載失敗或者關閉時行為是否符合預期;鼠標指針移動到圖片上后顯示的文本是否正確;圖片是否可以正確點擊/拖曳等。
9)submit提交按鈕,提交當前<form>表單信息到指定頁面。
常見檢查點:提交信息完整性等。
1.6 多次操作本該禁用的頁面組件造成服務器出錯
對頁面上的組件進行多次點擊是測試人員經常使用的小技巧之一,通常小蔡在執行完基本測試用例之后,開始進行探索性測試時會使用這個技巧,并且利用這個測試技巧發現了不少問題。
這些問題主要集中在用戶提交服務器請求后服務器進行處理的相關功能上,例如讀取、保存、提交、刪除等功能(見圖1-12)。

圖1-12 用戶通過“刪除”“保存”等功能和服務器交互
小蔡發現如果網絡速度比較慢或者產品本身性能不夠好,在用戶點擊了這些功能按鈕后,而頁面刷新完成之前這段時間內,該功能按鈕仍然可能被用戶繼續點擊。即使有些頁面上的按鈕處于灰色不可用狀態,但當你嘗試點擊這些灰色的按鈕,會發現點擊后仍然會給服務器端發送請求(見圖1-13)。

圖1-13 功能按鈕在被置灰后仍然可以使用
這樣帶來了一系列問題,舉例來說,對于保存功能,用戶多次點擊后會向后臺發送多次請求,數據庫中也會產生多條重復的數據,這樣不僅會造成數據統計錯誤,更會給再次使用這些數據的人或程序造成很大的麻煩。一個更極端的例子是免密碼支付的場景,當用戶不小心多次點擊支付按鈕后,會給用戶造成不小的損失;對于刪除功能來說,多次點擊“刪除”按鈕后,實際上第一個請求已經讓數據庫將對應的數據刪除了,接下來的刪除請求可能會造成后臺程序的大量異常。
小蔡發現解決此類問題也很簡單,只需要開發人員在編寫代碼時注意,只允許對該類功能按鈕操作一次,在用戶操作之后,不僅需要把對應的功能按鈕置灰,同時需要取消這些功能按鈕上面綁定的事件響應處理機制。
通常小蔡除了會在小組的回顧會議上向開發人員分析這些問題產生的原因和避免方式,還在每張開發故事卡上明確地標注需要測試多次快速點擊按鈕的場景,這樣可以讓開發人員從意識上提高對這類缺陷的警惕,從而在編寫代碼時注意預防此類問題的發生。
拓展知識:回顧會議
無論一個Scrum團隊有多出色,總有需要改進的地方。即使一個好的Scrum團隊會不斷尋找需要改進的方面,這個團隊也應該做一個簡單回顧,目的是在每個迭代的最后來回顧團隊目前做得如何以及找到改進的方法。
回顧會議(Sprint Retrospective)通常發生在每個迭代最后一天,用來幫助團隊進行自我改進。會議長度通常為1個小時,團隊成員在一起列出團隊應該做的事情、需要停止做的事情、應該保持下去的事情。接著團隊成員對所有提議進行投票,這樣可以在有限的時間里優先討論大家最關心的幾個問題。通過集思廣益,提出改進方法,在緊接著的迭代中進行改進。
在下個迭代的回顧會議一開始,會首先關注上一次回顧會議的結果是否被落實。
1.7 頁面跳轉后出現HTTP 400錯誤
公司網站又升級了!這次升級后網站增加了一個保險報價功能:客戶先在網站上回答公司設計的各種問題(單選題),系統會把答案匯總起來,傳給后臺計算價格,然后后臺系統把計算出的保險報價返回給網站并顯示在頁面上。
從功能上看,小蔡覺得這個功能需求的關鍵是網站上設計的每一個問題都會作為一個價格因子并對最終報價產生影響。測試的重點應該是檢查每個因子能夠引起的價格變化是否符合預期。另外由于每類問題都分布在不同的頁面上,所以需要確保在頁面切換后,系統能保存之前選擇的答案而不丟失。最后性能要求是在后臺系統返回報價的時間上,根據業務方的需求需要遵守2/5/8原則,最長不能超過8秒,所以還需要增加對應的性能測試。
設計完用例,小蔡和開發人員一起進行了冒煙測試,結果每個功能都符合預期。于是小蔡在正式測試階段把大部分精力都放到了驗證各個價格因子對價格變化的影響上面。
經過大量的反復選擇問題答案和頁面切換操作后,小蔡像之前一樣準備進入到報價匯總頁面查看最終價格,突然發現頁面出現HTTP 400錯誤(見圖1-14)!

圖1-14 HTTP 400異常
小蔡眼睛一亮,趕緊回退到上一個頁面,重新點擊報價匯總按鈕再次進入報價匯總頁面,反復試了好幾次,發現仍然會碰到HTTP 400這個問題。于是她關閉并重新啟動瀏覽器,嘗試再次重現這個問題,準備整理下出現問題的場景,然后報給研發人員修復,結果這次卻正常進入到報價匯總頁面。
小蔡覺得挺奇怪的,難道剛才是服務器“抽風”才導致HTTP 400異常?于是她又一連操作了好幾次到匯總頁面的場景,結果都沒有重現問題。雖然感覺很神奇,但是因為沒有能夠重現問題,小蔡也只能暫時作罷,一邊想著肯定是服務器抽風了吧,一邊繼續測試價格因子。
5分鐘以后,當她再次準備進入到價格匯總頁面時,問題又出現了,再次顯示HTTP 400錯誤頁面!看著頁面上提示的錯誤信息,小蔡突然間有點兒明白了,提示信息說HTTP Request Header長度過長,因此問題應該是在HTTP Request Header上。小蔡利用瀏覽器自帶的開發工具查看了下HTTP的請求頭,結果瞬間就發現Cookie看上去似乎比平時看到的要長好多(見圖1-15)。

圖1-15 從瀏覽器工具中查看Cookie
小蔡懷疑是Cookie有問題,于是就找開發人員確認。在給開發人員演示了一遍這個Bug后,開發人員終于分析出造成這一結果的直接原因是Cookie長度太長,導致Request Header長度超標,最后發生HTTP Error 400。而再深入一層的根本原因是開發人員為了在切換頁面時保存前幾個頁面的答案狀態,把這些狀態存到了Cookie里面,而每次翻頁的時候又把答案信息錯誤地添加到Cookie已有信息之后,導致隨著小蔡翻頁操作越來越多,Cookie也越來越長,最后當Cookie長度超過瀏覽器限制后就產生了錯誤。
知道了問題原因,小蔡仔細回想了下整個用例設計過程,覺得這樣的問題即使通過覆蓋各種用戶使用場景仍然會不好發現。但如果測試人員在測試之前能夠對整個功能的設計或者實現有一些了解的話,就可以注意到這個點,并且加以測試了。例如這次的Cookie超長問題,如果測試人員和開發人員先進行一些溝通,了解到代碼是通過把信息存儲到Cookie中去實現該功能,那么測試人員會很自然地想到Cookie長度通常是有限制的,因此會對這種存儲信息的方式做特定的測試。
核心知識:HTTP Request Header長度限制
Request Header就是往服務器發送的請求頭,HTTP協議中并沒有限制Header的大小。理論上無論我們的Header有多大都是可以的。
但實際上各個主流瀏覽器都會對Header長度進行限制,從幾十KB到幾百MB不等,基本上能滿足平時的需求。此外,在服務端也可以對Heder長度做限制。比如Nginx就可以限制Header的長度。
HTTP Header如果不限制大小會有什么影響?
如果某個網站的服務器是不限制Header大小的,那么它就有可能被黑客利用實施攻擊,比如DDoS。黑客可以利用這一點,發送一個非常大(比如幾MB)的請求,會占用服務器一個進程來專門處理這個請求。此類請求數量過多時,服務器就無法提供其他對外服務。
1.8 使用沒有添加時間戳的緩存使用戶看到過期數據
當代主流的網站都使用了緩存技術,目的在于減少用戶請求對服務器的壓力。當用戶首次通過瀏覽器請求服務器的資源時,服務器會返回所有的資源;當用戶再次請求服務器資源時,瀏覽器會判斷資源是否已更新,如果更新了,再向服務器發起請求,如果沒有更新,就使用瀏覽器中緩存的資源。
這里有一個問題,瀏覽器是如何判斷資源是否更新了?一般來說,資源文件在文件名中要么添加時間戳(見圖1-16),要么添加標識符(標識符可以是任何一組區別資源不同版本的數值,如v1、v2,或者GUID等)來唯一區分資源的不同版本(見圖1-17)。只要本地緩存的資源文件和服務器端最新的資源文件名稱不一樣,瀏覽器就要從服務器端獲取新的資源文件,如果一樣,就使用本地緩存的資源。

圖1-16 帶有時間戳的資源文件

圖1-17 帶有標識符的資源文件
如果資源文件沒有被添加時間戳或者標識符呢?那用戶只能通過手動清除瀏覽器的緩存來強制獲取最新的資源文件了,不過這樣等于所有用戶請求的文件都沒有從瀏覽器緩存中讀取,也就沒有為服務器緩解訪問壓力。并且絕大多數用戶并不會去手動清除瀏覽器的緩存,這就導致用戶看到網頁的資源文件不是最新的。
最近小蔡測試的商品詳細信息頁面出現的Bug就屬于這種情況。根據用戶線上反饋,當用戶修改了商品圖片并且發布之后,不能及時看到更新后的圖片,而是需要等一段不確定的時間才能看到更新后的圖片。
經過小蔡和開發人員的調查,發現導致這個問題的原因是緩存資源文件沒有被設置時間戳或者標識符,導致用戶修改后不能看到更新后的圖片。而之所以會造成不確定時間后才能看到更新后的圖片,是由于不同瀏覽器對于沒有設置時間戳或者標識符的緩存資源文件處理不一致造成的。
例如IE緩存時間就是一個Session的時間,如果用戶打開一個新的IE窗口時,他們就會獲取最新的靜態資源;而其他瀏覽器(例如Firefox),則會通過HTTP頭文件中Last-Modified參數的具體定義來判斷是否需要去重新獲取資源。
而小蔡在之前的測試中,為了避免緩存數據對測試結果的影響,她在瀏覽器中設置了每次退出瀏覽器時清空緩存(見圖1-18),這反而導致小蔡漏測了緩存沒有及時刷新的問題。

圖1-18 退出IE時自動刪除緩存
由于緩存在Web產品中是普遍存在的,所以小蔡立刻取消了瀏覽器中清除緩存的設置,改為使用手工清除緩存的方式。當她之后在測試中遇到測試結果和預期結果不同,并且有可能是緩存未清除造成的情況時,她會手動清除緩存,這樣可以更準確地進行測試。
核心知識:Web緩存
瀏覽器本身有緩存機制,比較常見的是瀏覽器會緩存訪問過的網頁,當再次訪問這個URL地址的時候,如果網頁沒有更新,就不會再次下載網頁,而是直接使用本地緩存中的網頁。只有當網站明確標識資源已經更新,瀏覽器才會再次下載網頁。
使用Web緩存可以減少網絡帶寬消耗、降低服務器壓力、減少網絡延遲,加快頁面打開速度。同時我們也可以使用代理服務器,在代理過程中做緩存處理,也可以使用CDN網絡提供的緩存能力。
除了上述提到的軟件之外的緩存方式,服務器端軟件內部也經常使用各種緩存,例如使用數據庫進行緩存,或者使用內存進行緩存,也可以提高用戶訪問網頁的速度。
1.9 代理服務器過度緩存文件導致讀取錯誤的賬號信息
緩存不僅僅是Web產品為了緩解用戶訪問帶給服務器的壓力而設置的,而且用戶(例如企業)為了減少多用戶訪問同一個網站占用過多帶寬,也可以設置自己內部的緩存服務器。
小蔡的公司就為大家設置了這樣一組緩存服務器。這些緩存服務器的原理和瀏覽器的緩存原理類似,當大家訪問網頁時,首先請求的是這些服務器上的資源,如果沒有命中,也就是說這些資源不在公司內部的緩存服務器上,這些服務器才向公司外部真實的服務器發送請求,等請求返回后,緩存服務器還需要把這些資源保存在本地,以便于其他用戶對同一網頁的再次訪問,然后才把這些資源發送回最開始發送請求的用戶(見圖1-19)。

圖1-19 企業內部緩存服務器
當然我們這里只是簡單地介紹一下內部緩存服務器進行緩存的過程,很多例如緩存如何過期這些細節在這里就不詳述了。
小蔡在測試網站的過程中,發現自己登錄測試賬號后,首先會看到其他測試賬號信息(而且這個賬號不固定),如果這時候進行任何操作,很有可能出現錯誤頁面,尤其是與賬戶信息相關的操作,所以小蔡只有強制刷新或者退出后,再次登錄才能看到剛才登錄的賬號信息,并且正常地進行測試。這個問題在早上一般不會發生,而其他時間出現的頻率就要高很多。
發生幾次之后,小蔡覺得很好奇,就詢問了其他的測試人員,發現大家都有同樣的問題,在和老牛一起分析后,他們覺得有可能是公司內部緩存服務器機制導致了這個問題,但是至于為什么早上這個問題不容易發生,還是不太了解。
帶著這個問題還有他們的懷疑,小蔡和老牛找到了公司信息維護的相關人員。經確認,確實是他們緩存了測試服務器的資源,而且還緩存了登錄用戶的Cookie文件。
所以當測試人員訪問測試服務器時,緩存服務器將輸入的用戶名和密碼以及Cookie文件一起發送給了測試服務器。雖然服務器接收了新的登錄用戶名和密碼,但是顯示卻使用的是Cookie里面的信息。所以,在進行賬戶相關操作時,服務器并不知道應該對哪個賬號進行操作,于是出現了錯誤頁面。
那為什么早上這個問題出現的幾率會小很多呢?根據小蔡他們的猜測,很可能是因為早上正式開始執行測試的人員比較少,時間間隔長,導致Cookie文件雖然被發送,但是過期了,所以服務器很少會出現錯誤頁面。
最后,經過公司信息維護的相關人員的重新配置,取消了對登錄用戶Cookie文件的緩存,小蔡他們再也沒有遇到這個賬號顯示錯亂的問題。
拓展知識:Session和Cookie
由于HTTP是一個無狀態協議,客戶端每次發出請求時,本次請求無法得知上一次請求的狀態信息。在常見的網站中,服務端需要在多次HTTP請求間共享數據,例如用戶在購物網站登錄后,跳轉到商品頁面,這時候服務器端需要知道該用戶是否已經登錄過。在技術上可以使用Session和Cookie去做這件事情。
簡單來說,Session是在服務端保存的數據,Cookie是在客戶端瀏覽器中保存的數據,它們一起合作,來實現跨HTTP請求的數據共享。例如,當服務器第一次創建Session時,在內存中記錄了用戶的信息,同時會在HTTP協議中告訴客戶端,需要在Cookie里面記錄一個Session ID,以后每次請求都會把這個Session ID發送到服務器,服務器就可以知道這個用戶是誰了,從而能從服務器端查詢出此用戶的各種相關信息。
1.10 多余的空格造成服務器被刪除
在敏捷測試中,測試工作不僅包括設計和執行測試用例、編寫測試報告,以及測試計劃和策略的制定,還有測試部署腳本等工作。這次小蔡在執行部署腳本的測試過程中發現了一個嚴重的問題,這個Bug會導致整個測試服務器被刪除,事情的緣由是這樣的。
小蔡根據開發人員提交的部署腳本和執行步驟,一步步在測試環境中進行部署,同時去驗證部署腳本中是否有遺漏和錯誤。當執行完部署腳本中刪除臨時文件的步驟后,小蔡發現后續步驟都不能執行了!經過調查發現原因是測試服務器已經被格式化了。
雖然測試服務器都是虛擬化的,可以很快在測試環境重新建立一臺測試服務器,但是,如果這個Bug出現在生產環境,那將會是非常大的災難!
小蔡找到了剛才執行過程中出現問題的語句,是“rm -rf / tmp”。她仔細檢查了整個語句,發現測試服務器被格式化的原因是在tmp前面多了一個空格,這個空格不仔細看還看不出來(業內也有同樣的知名例子:Bumblebee誤刪用戶文件夾,如圖1-20所示,在最后一行的/usr /lib…語句中在usr后就被多寫了一個空格)。

圖1-20 Bumblebee誤刪用戶文件夾
不過在Linux系統中,即使輸入了災難性的操作語句,但如果沒有管理員的權限也是無法執行的,因為在執行這條語句的時候,只會出現權限不足,無法操作的提示,不會把服務器整個刪除。如圖1-21所示,執行刪除語句的用戶由于沒有管理員權限而被拒絕執行了。

圖1-21 刪除文件需要相應的權限
所以小蔡下一步需要在腳本中找出是哪里賦予了管理員權限,導致后來刪除語句被允許執行的。再仔細查找之前的部署腳本,果然不出所料,之前有一個操作步驟需要用管理員權限來復制幾個不同的文件到管理員文件夾。通常做此類操作時,會只針對這條語句賦予權限,例如使用sudo命令的這條語句:“sudo cp xxx.zip /var/xxx/xxx/”,但開發人員在這里為了簡化腳本的書寫,把每一句最開始的sudo轉換成單獨的一條“su-root”,這種改變造成之后執行的所有語句都被賦予管理員權限進行執行,最終導致格式化測試服務器的命令也被執行了。
小蔡把這一發現告訴了開發人員后,開發人員修改了兩處代碼:一是刪除“su-root”命令,改為針對每次執行需要特定權限的語句時單獨添加sudo的方式,確保腳本執行的權限是正確的;第二是刪除了導致測試服務器被格式化的那個空格。
核心知識①:sudo和su
sudo用于類UNIX操作系統(如BSD)、Mac OS X,以及GNU/Linux,以允許用戶通過安全的方式使用特殊的權限去運行程序,例如使用系統的超級用戶權限去運行程序。
su命令可以讓操作者在虛擬控制臺切換當前用戶賬戶,使用su的缺點之一是必須要先獲取超級用戶的密碼。
核心知識②:Linux文件權限
Linux系統中的文件和目錄通過使用訪問許可權限,來確定誰能通過何種方式進行訪問與操作。文件或目錄的訪問權限分為只讀、只寫和可執行3種。
確定了文件的訪問權限后,用戶能使用Linux系統自帶的chmod命令來重新設定訪問權限,也能利用chown命令來更改文件或目錄的所有者,或者使用chgrp命令來更改文件或目錄的用戶組。
拓展知識:虛擬化
在計算機技術中,虛擬化(virtualization)是一種資源管理技術,將計算機的各種實體資源,如服務器、網絡、內存及存儲等,予以抽象、轉換后呈現出來,供多個用戶共享使用。
1.11 IE 9不支持占位符導致搜索行為異常
對于瀏覽器兼容性測試,一直都是Web測試中重要的一環,小蔡在測試產品中自然也不能漏掉。
由于小蔡測試的產品是面向普通用戶的,所以小蔡選擇進行測試的瀏覽器,也是開發團隊選擇優先支持的瀏覽器,是基于市場占有率最高的幾款瀏覽器:Chrome、Firefox、Safari和IE。這些瀏覽器的版本也很多,如果全部支持也是不可能的,所以開發團隊選擇支持最新版本的Chrome、Firefox和Safari,以及IE 9~IE 11,還有IE EDGE。
Chrome和Safari都是基于WebKit核心的,所以差別不大。Firefox雖然基于Gecko,但是對于絕大多數Web標準協議都是支持的,所以和Chrome及Safari的差別也很小。IE因為使用的是微軟自己的內核,所以和其他瀏覽器的差別會大不少,尤其是版本較早的IE 9~IE 11,不過微軟在IE EDGE上已經開始兼容WebKit,并且兼容最新的Web標準協議,所以和其他瀏覽器的差別也不大了。
小蔡根據搜集到的這些瀏覽器差異的信息,決定兼容性測試的重點放在測試Chrome和IE 9兩個瀏覽器上面。
由于產品是大型購物網站,所以用戶需要使用搜索特定商品來查看商品詳細信息。而在搜索框中,業務方希望推廣一些暢銷產品,所以使用了占位符(Placeholder)的方式,使用戶在點擊搜索框之前,在搜索框的搜索關鍵字部分,看到的是通過占位符設置的推廣產品的信息。
小蔡在執行瀏覽器兼容性測試時發現,由于添加了占位符,導致Chrome和IE 9瀏覽器上搜索功能的行為不一致(見圖1-22)。

圖1-22 IE 9的占位符會被當作搜索關鍵字
▼在Chrome上當用戶點擊搜索框時,占位符會消失,用戶輸入的字符會被當作搜索關鍵字進行搜索。
▼在IE 9上當用戶點擊搜索框時,占位符并不會消失,用戶輸入的字符以及占位符的內容會一起被當作搜索關鍵字進行搜索。
這就導致用戶在兩個瀏覽器上使用相同的操作步驟進行搜索時的搜索結果不一致。想要解決這個問題,用戶只有一個一個字符地刪除IE 9瀏覽器中搜索框里的占位符,這對用戶來說并不友好。
經過開發人員調查發現,這個問題的原因是IE 9瀏覽器本身就不支持占位符,所以對于占位符的操作也是有問題的。開發人員只好對IE 9上的搜索框單獨處理,給搜索框先添加一組灰色的默認文字,來展示暢銷商品,等用戶點擊搜索框時再清除這些字符。
小蔡慶幸IE 9是支持的最低版本的IE,如果需要再兼容IE 6~IE 8,那瀏覽器之間的差異更多更復雜,也會讓開發和測試工作的難度加大不少。同時她決定定期查看用戶的瀏覽器使用率和使用量,等大量用戶不再使用IE 9時,就可以不用再做現在這種針對特定瀏覽器編寫代碼和測試某項功能了。
拓展知識:瀏覽器內核
排版引擎負責解析標記式內容(如HTML、XML、CSS、XSL及圖像文件等),并將排版后的內容輸出至顯示器或打印機。Chromium/Chrome(iOS版除外)與Opera使用的瀏覽器引擎是基于Blink,是WebKit的一個分支,Firefox網頁瀏覽器使用了Gecko網頁瀏覽器引擎,Internet Explorer使用的是Trident網頁瀏覽器引擎。
1.12 小結
本章我們介紹了由特定技術引起的功能測試問題,下一章我們會接觸到由于測試覆蓋導致的問題。
- Oracle從新手到高手
- Web Scraping with Python
- The Computer Vision Workshop
- aelf區塊鏈應用架構指南
- OpenGL Data Visualization Cookbook
- Java語言程序設計教程
- Access 2010數據庫應用技術實驗指導與習題選解(第2版)
- C語言程序設計與應用(第2版)
- QGIS 2 Cookbook
- Python語言科研繪圖與學術圖表繪制從入門到精通
- 數字媒體技術概論
- Python Automation Cookbook
- 你必須知道的.NET(第2版)
- Getting Started with the Lazarus IDE
- 開發者測試