官术网_书友最值得收藏!

  • Web測試囧事
  • 黃勇等
  • 2153字
  • 2019-01-05 03:43:28

提到測試,大家首先會(huì)想到的就是功能性的測試,因?yàn)橹挥斜WC了產(chǎn)品的基本功能和流程,產(chǎn)品才具備給用戶提供使用價(jià)值的能力,從而才有可能確定產(chǎn)品的核心競爭力。基于這一點(diǎn),不僅測試人員和開發(fā)人員,還有產(chǎn)品經(jīng)理、項(xiàng)目經(jīng)理、業(yè)務(wù)方對功能完備性和正確性的重視程度也往往都是最高的。這也使得功能測試成為任何測試類型的基礎(chǔ)。

在進(jìn)行功能測試時(shí),我們會(huì)使用諸如邊界值分析、等價(jià)類劃分、因果分析、組合測試(Pairwise Testing)等測試方法來設(shè)計(jì)和規(guī)劃測試用例,但是這些方法大多都是從書本上學(xué)來或者從別的渠道了解到的理論方法。而實(shí)際上在一個(gè)真實(shí)的項(xiàng)目中如何運(yùn)用,或者如何在特定的場景和情境下使用這些方法,去充分發(fā)揮這些測試方法的作用,并幫助我們高效地設(shè)計(jì)和執(zhí)行測試用例卻是更重要的問題。

正因如此,我們在功能測試部分并沒有介紹這些方法是什么,而重點(diǎn)在于展示在一個(gè)具體的場景下,讀者應(yīng)該如何思考,怎么把理論知識和實(shí)際工作結(jié)合起來,以發(fā)現(xiàn)和避免可能遇到的陷阱。

功能測試部分的故事篇幅都會(huì)比較長,希望讀者能夠每讀完一個(gè)故事,都留出一段時(shí)間進(jìn)行思索和回味,從而理解故事的核心,觸類旁通。

為了讓每一章的故事更凝練,我們把功能測試部分分成了4章,分別是:技術(shù)篇、測試覆蓋篇、測試實(shí)踐篇和業(yè)務(wù)需求篇。這4章從Web開發(fā)流行的各種技術(shù)(例如響應(yīng)式設(shè)計(jì)、特性開關(guān)、虛擬化等)、測試技術(shù)(例如實(shí)例化需求、集成測試、契約測試等)、測試實(shí)踐(例如探索性測試、回顧會(huì)議、缺陷大掃除等)和業(yè)務(wù)需求(例如用戶的并發(fā)操作、關(guān)聯(lián)操作以及產(chǎn)品功能的一致性等)方面向讀者全方位展示功能測試范疇中的常見問題和解決辦法,更重要的是指引大家從一步一步的分析中得到解決問題的思路。

本章(技術(shù)篇)介紹了在開發(fā)和測試的技術(shù)方面引起的11個(gè)功能測試問題,現(xiàn)在大家和我們一起來看看這些豐富多彩的故事。

1.1 輸入框中輸入超過最大允許值造成頁面跳轉(zhuǎn)溢出

作為計(jì)算機(jī)系畢業(yè)生的小蔡,一直覺得學(xué)校里學(xué)的理論知識和現(xiàn)在的測試工作差距太大,在實(shí)際的工作中也沒有什么作用,直到有一天她碰到這么一個(gè)有趣的問題。

小蔡負(fù)責(zé)測試的是一個(gè)Web產(chǎn)品,基于不同的搜索條件會(huì)顯示大量的結(jié)果。由于搜索結(jié)果太多,所以頁面有分頁功能,為了方便用戶快捷跳轉(zhuǎn)到特定的頁面,開發(fā)人員特意設(shè)計(jì)了一個(gè)頁面快速跳轉(zhuǎn)的功能(見圖1-1)。

圖1-1 搜索結(jié)果頁面快速跳轉(zhuǎn)

在設(shè)計(jì)測試用例的時(shí)候小蔡就留心了,因?yàn)楹芏鄿y試?yán)碚摰臅济枋鲞^,對于輸入框可以進(jìn)行的驗(yàn)證點(diǎn)很多,比如:特殊字符、超長字符、負(fù)值、0值null值,以及很大的數(shù)值等。小蔡發(fā)現(xiàn),對于大部分的測試用例,開發(fā)人員都處理得很好,沒有發(fā)現(xiàn)缺陷,她也就松了口氣。

但是,當(dāng)她測試到輸入大數(shù)值的測試用例時(shí),由于不確定多大的數(shù)值會(huì)出錯(cuò),也不能拿到代碼,小蔡就探索性地選了一個(gè)數(shù)值:9999999999(10個(gè)“9”)。當(dāng)輸入10個(gè)“9”點(diǎn)擊“確定”按鈕時(shí),突然頁面崩潰了!她仔細(xì)回想剛才的測試過程:100以內(nèi)的小數(shù)值,以及輸入小于等于搜索結(jié)果頁面數(shù)的數(shù)值等情況,測試結(jié)果都很正常。那到底數(shù)值大到什么程度的時(shí)候頁面會(huì)崩潰呢?一時(shí)想不到更好的辦法,小蔡只好硬著頭皮嘗試著定位出錯(cuò)的數(shù)值范圍。

她發(fā)現(xiàn),當(dāng)輸入10個(gè)“9”就會(huì)出錯(cuò),而輸入9個(gè)“9”,頁面正常跳轉(zhuǎn)到最后一頁。突然,小蔡想起來數(shù)據(jù)結(jié)構(gòu)課程不是學(xué)過很多查找法嘛!這樣,二分法就這么出現(xiàn)在了眼前,對,二分查找法(見圖1-2)! 5000000000(9個(gè)“0”),出錯(cuò);2500000000(8個(gè)“0”),正常。她還是沒有線索,可是她堅(jiān)持這么一點(diǎn)一點(diǎn)查找。最后花了將近3個(gè)小時(shí),小蔡終于定位到了出錯(cuò)的數(shù)值:4294967295。這個(gè)時(shí)候,小蔡很納悶,怎么是這么一個(gè)奇怪的數(shù)值呢?有零有整的。計(jì)算機(jī)專業(yè)的背景給了小蔡一個(gè)提示,不會(huì)是2的多少次冪吧?果真,4294967295是232-1。當(dāng)小蔡收集到這些線索之后和開發(fā)人員一溝通,才發(fā)現(xiàn)由于開發(fā)人員設(shè)想頁面最大不會(huì)超過232,所以對這個(gè)字段可以輸入的最大數(shù)值的類型,選擇的是int32。但是,開發(fā)人員并沒有對超過這個(gè)范圍的數(shù)值進(jìn)行任何的處理,這就造成了程序判斷中請求更大數(shù)值頁面時(shí)的溢出,從而導(dǎo)致了產(chǎn)品頁面的崩潰。

圖1-2 二分查找的原理

提示

二分查找算法(binary search)或者折半查找算法,是一種在有序數(shù)組中查找某一特定元素的搜索算法。

搜索過程從數(shù)組的中間元素開始,如果中間元素正好是要查找的元素,則搜索過程結(jié)束;如果某一特定元素大于或者小于中間元素,則在數(shù)組大于或小于中間元素的那一半中查找,而且跟開始一樣從中間元素開始比較。如果在某一步驟數(shù)組為空,則代表找不到。這種搜索算法每一次比較都使搜索范圍縮小一半。


發(fā)現(xiàn)了這個(gè)隱藏的缺陷,小蔡很有成就感,但又覺得如果能早點(diǎn)知道代碼的邏輯,可能自己就不會(huì)花這么長的時(shí)間了。同時(shí),小蔡一直覺得計(jì)算機(jī)的理論知識不會(huì)應(yīng)用到測試實(shí)踐中,可沒想到這次多虧了學(xué)校中學(xué)到的這些基礎(chǔ)知識,不只是int32,232,甚至還有二分查找算法也給了自己解決問題的靈感。沒有這些知識,定位問題就更困難了。

核心知識:邊界值分析法

邊界值分析法是一種常見的黑盒測試方法。

測試界的前輩們通過分析常見Bug,發(fā)現(xiàn)絕大多數(shù)的Bug都出現(xiàn)在輸入/輸出范圍的邊界處。因此,如果能夠針對這些邊界來設(shè)計(jì)用例,通常能夠更加有效。

邊界值測試法通常是作為等價(jià)類測試法的補(bǔ)充,和等價(jià)類測試法結(jié)合起來用。即每個(gè)等價(jià)類的邊界部分就可以作為邊界值的測試用例之一。

舉個(gè)例子。假設(shè)有一個(gè)日期選擇器(date picker)的需求,要求我們能夠輸入時(shí)間后,點(diǎn)擊搜索查詢輸入日期前后一年范圍內(nèi)的數(shù)據(jù)。假設(shè)我們把輸入的時(shí)間分為如下幾個(gè)等價(jià)類:

1)正常時(shí)間范圍內(nèi):now-1年< test data < now+1年;

2)正常時(shí)間范圍外:test data < now-1年或者test data > now+1年

3)特殊時(shí)間:例如now=2月29,1970/01/01等

4)輸入非時(shí)間的input value:比如輸入值為@等

……

結(jié)合分類1、2,這個(gè)時(shí)候邊界值的取值則可以取:

▼test data=now-1年;

▼test data=now+1年;

▼test data=now-1年-1天;

▼test data=now-1年+1天

……

考慮到輸出范圍是一整年的數(shù)據(jù),結(jié)合特殊時(shí)間和時(shí)間的邊界(跨年、跨月等),還可以增加

▼test data=2月29

▼test data=12月31號

▼test data=1月1號

……

總之,邊界值的取值,應(yīng)該著重考慮邊界情況。如果測試對象是時(shí)間,則應(yīng)該重點(diǎn)考慮跨年、跨月等;如果測試對象是純數(shù)字,則應(yīng)該重點(diǎn)考慮數(shù)字的類型與取值范圍;如果測試對象是數(shù)據(jù)表,則應(yīng)該重點(diǎn)考慮數(shù)據(jù)表設(shè)計(jì)的字段長度,等等。

拓展知識:測試用例設(shè)計(jì)

測試用例記錄了測試的過程,我們可以通過測試用例了解哪些場景已經(jīng)被驗(yàn)證了,哪些場景還沒有被驗(yàn)證。除此之外,在傳統(tǒng)的測試行業(yè)中,測試用例數(shù)量通常也被作為度量測試工作量和指定測試工作計(jì)劃的重要輸入。

測試用例通常會(huì)包含幾個(gè)基本要素:用例編號、輸入數(shù)據(jù)、期望結(jié)果以及前置條件等。測試覆蓋率則是評價(jià)測試用例好壞的關(guān)鍵標(biāo)準(zhǔn)。覆蓋率高的測試用例能夠提高開發(fā)、產(chǎn)品以及其他驗(yàn)收人員對產(chǎn)品的信心。在設(shè)計(jì)過程中,我們通常會(huì)通過邊界值、等價(jià)類等測試方法,結(jié)合配對組合測試(pairwise testing),基本路徑分析法等測試策略優(yōu)化測試用例,以達(dá)到提升測試覆蓋率和減少冗余測試用例的方法。

以下是測試用例設(shè)計(jì)原則。

1)測試用例的代表性:能夠代表并覆蓋各種合理的和不合理的、合法的和非法的、邊界的和越界的以及極限的輸入數(shù)據(jù)、操作和環(huán)境設(shè)置等。

2)測試結(jié)果的可判定性:即測試執(zhí)行結(jié)果的正確性是可判定的,每一個(gè)測試用例都應(yīng)有相應(yīng)的期望結(jié)果

3)測試結(jié)果的可再現(xiàn)性:即對同樣的測試用例,系統(tǒng)的執(zhí)行結(jié)果應(yīng)當(dāng)是相同的

1.2 索引值計(jì)算錯(cuò)誤使資源縮略圖顯示和大圖展現(xiàn)不一致

業(yè)務(wù)方希望在商品展示的頁面,不僅能添加展示圖片,還可以展示關(guān)于商品的視頻(見圖1-3)。

圖1-3 商品展示頁面支持展示圖片和視頻

業(yè)務(wù)方希望通過圖1-3下方的統(tǒng)一翻頁操作,實(shí)現(xiàn)無縫瀏覽圖片和視頻。如果商品既有圖片又有視頻,當(dāng)用戶在瀏覽圖片時(shí),在圖1-3右下角顯示“Video”(視頻),這時(shí)用戶可以通過點(diǎn)擊“Video”鏈接打開第一個(gè)視頻;同樣當(dāng)用戶在瀏覽視頻時(shí),在圖1-3右下角顯示“Image”(圖片),這時(shí)用戶可以通過點(diǎn)擊“Image”鏈接打開第一張圖片。

小蔡按照通常的步驟編寫完測試用例,開始使用標(biāo)準(zhǔn)測試數(shù)據(jù)執(zhí)行測試。小蔡首先發(fā)現(xiàn)點(diǎn)擊右下角鏈接時(shí),本應(yīng)該顯示第1張圖片或者視頻,但是打開的卻是第2張圖片或者視頻。

小蔡覺得這可能是開發(fā)人員在處理圖片和視頻展示的數(shù)組時(shí),使用的是自然數(shù)計(jì)數(shù),從1開始作為第1個(gè)數(shù)據(jù)項(xiàng),而非計(jì)算機(jī)程序數(shù)組中通常使用的把從0開始計(jì)數(shù)作為第一個(gè)數(shù)據(jù)項(xiàng)。當(dāng)小蔡把這一問題上報(bào)之后,開發(fā)人員發(fā)現(xiàn)確實(shí)是這個(gè)原因,并進(jìn)行了快速修正。

小蔡在開發(fā)人員新發(fā)布的包上又一次進(jìn)行了測試,這次測試用例基本沒有什么問題,她就開始在類真實(shí)環(huán)境中執(zhí)行探索性測試,結(jié)果發(fā)現(xiàn)在某些商品頁面進(jìn)行圖片和視頻跳轉(zhuǎn)時(shí),出現(xiàn)圖片或視頻顯示錯(cuò)誤或者顯示成空白的問題。

在老牛的協(xié)助下,小蔡發(fā)現(xiàn)了問題出現(xiàn)的兩個(gè)規(guī)律:①當(dāng)從第n張圖片切換到視頻的時(shí)候,系統(tǒng)顯示的并不是用戶期待的第1個(gè)視頻,而是第n個(gè)視頻;②當(dāng)商品的圖片和視頻數(shù)量不一致,從數(shù)量多的資源切換到另一個(gè)數(shù)量少的資源時(shí),內(nèi)容就會(huì)出現(xiàn)空白。

小蔡和老牛都覺得出現(xiàn)問題的原因比較明確了,是因?yàn)樵趫D片和視頻跳轉(zhuǎn)時(shí),打開資源的索引值并沒有清零,而是保存著前一個(gè)元素的索引值。

為什么這個(gè)問題在測試環(huán)境中沒有發(fā)現(xiàn),而在類真實(shí)環(huán)境中才被發(fā)現(xiàn)?原來最初小蔡在測試環(huán)境中執(zhí)行測試用例的時(shí)候,使用的是基本測試數(shù)據(jù),圖片和視頻都只有兩個(gè),而且兩張圖片和兩個(gè)視頻的內(nèi)容分別都是一樣的,因此不會(huì)出現(xiàn)這個(gè)問題。

小蔡和老牛商量了下,決定為了避免遺漏這樣的問題,需要豐富測試環(huán)境的測試數(shù)據(jù),使得測試數(shù)據(jù)更像真實(shí)數(shù)據(jù),這樣測試結(jié)果才更為準(zhǔn)確。

同時(shí)他們認(rèn)為這個(gè)問題在開發(fā)人員的開發(fā)過程中也是不應(yīng)該引入的,因?yàn)檫@樣的錯(cuò)誤比較初級。于是小蔡和開發(fā)人員進(jìn)行了溝通,發(fā)現(xiàn)引入該問題的根源在于開發(fā)人員的疏忽。由于圖片的文件格式和視頻的文件格式不同,所以開發(fā)人員使用了兩個(gè)庫來支持圖片和視頻的打開,但是兩個(gè)庫之間的跳轉(zhuǎn)需要通過在兩個(gè)庫之間傳遞參數(shù)來實(shí)現(xiàn),然而開發(fā)人員并沒有仔細(xì)檢查兩個(gè)庫之間所傳遞的參數(shù),導(dǎo)致并不需要被傳遞的索引值也傳遞到另一個(gè)庫中。

老牛帶著小蔡和開發(fā)人員立下一個(gè)約定:在使用第三方庫實(shí)現(xiàn)功能時(shí),一定要把使用的函數(shù)方法中的所有參數(shù)都核對清楚

核心知識①:探索性測試

探索性測試(Exploratory Testing)是軟件測試方法的一種。這種方法強(qiáng)調(diào)測試者的主觀能動(dòng)性,以及測試設(shè)計(jì)和測試執(zhí)行的同時(shí)性。目的是探索開發(fā)更多不同形態(tài)的測試方法,以便改善測試流程。

“先設(shè)計(jì),再測試”的傳統(tǒng)做法,通常是先分析出測試點(diǎn),然后針對測點(diǎn)設(shè)計(jì)好測試方法,最后執(zhí)行測試。這種模式也帶來了一些問題,比如在測試目標(biāo)不確定的情況下(改需求、輸出范圍過大等)經(jīng)常可能出現(xiàn)測試遺漏等,而且在一定程度上也限制了測試思維的發(fā)散。而探索性測試的出現(xiàn),正好彌補(bǔ)了傳統(tǒng)測試中出現(xiàn)的這種問題。

探索式軟件測試一共分為自由式探索式測試、基于場景的探索式測試、基于策略的探索式測試和基于反饋的探索式測試。

(1)自由式探索

純粹從使用的角度出發(fā),拋開規(guī)則、模式,測試人員可以以任意順序和方式對軟件進(jìn)行使用測試。這種測試通常會(huì)被選作快速冒煙測試用例。

(2)基于場景的探索式測試

這種測試跟傳統(tǒng)基于場景的測試比較像,不同的是,在這種測試中測試人員會(huì)擴(kuò)大測試范圍。例如,對某搜索框的測試,傳統(tǒng)的場景測試用例可能是:

1)輸入“電視”,期望結(jié)果是搜索到電視;

2)輸入“123”,搜索到123相關(guān)的內(nèi)容。

而基于場景的探索性測試下,測試場景則可能是:

1)輸入“電視”,探索搜索結(jié)果;

2)粘貼“ 1@3”,搜索結(jié)果;

3)輸入一個(gè)亂碼,搜索結(jié)果;

4)輸入電視,搜索結(jié)果后回退到搜索首頁再搜索;

……

(3)基于策略的探索性測試

這是一種比較依靠經(jīng)驗(yàn)的測試方式。簡單講就是測試?yán)鲜郑诤献约旱慕?jīng)驗(yàn)、技能、感知等條件,結(jié)合自由式探索性測試,用自己積累下來的知識來指導(dǎo)測試。是一種經(jīng)驗(yàn)結(jié)合隨機(jī)性的測試。

(4)基于反饋的探索性測試

反饋指的是當(dāng)測試人員對被測程序做出指令后得到的響應(yīng)結(jié)果。基于這個(gè)結(jié)果,測試人員可以調(diào)整自己的輸入,以期望得到不同的結(jié)果。例如,在基于場景的探索性測試的描述中,輸入電視和輸入電冰箱會(huì)得到不同的結(jié)果,而其中電視的搜索結(jié)果就是對電視這個(gè)輸入的反饋,電冰箱的結(jié)果就是對電冰箱這個(gè)輸入的反饋。

核心知識②:軟件開發(fā)中的各種環(huán)境

1)開發(fā)環(huán)境:就是每個(gè)開發(fā)人員進(jìn)行編程的電腦,包括軟硬件及其配置,為了開發(fā)調(diào)試方便,一般打開全部錯(cuò)誤報(bào)告。

2)測試環(huán)境:測試人員進(jìn)行產(chǎn)品部署,并進(jìn)行功能等測試的環(huán)境。

3)預(yù)生產(chǎn)環(huán)境(非必須):與生產(chǎn)環(huán)境不定期同步,保持和生產(chǎn)環(huán)境的設(shè)置、數(shù)據(jù)的一致性,也是用于測試的環(huán)境。與測試環(huán)境的最大區(qū)別就是它和生產(chǎn)系統(tǒng)同步性最高,有些比如數(shù)據(jù)遷移測試,用這個(gè)環(huán)境測試比測試環(huán)境(一般情況下數(shù)據(jù)較少)更準(zhǔn)確。

4)生產(chǎn)環(huán)境:正式使用的系統(tǒng)環(huán)境,一般會(huì)關(guān)掉錯(cuò)誤報(bào)告,打開錯(cuò)誤日志。

通常情況下,一個(gè)環(huán)境對應(yīng)一個(gè)服務(wù)器,不同環(huán)境代表著系統(tǒng)開發(fā)的不同階段:開發(fā)→測試→部署→上線。

1.3 測試Web Service能否正常提供JSON數(shù)據(jù)

某一天,小蔡所在的項(xiàng)目組剛開發(fā)完成一個(gè)Web Service,服務(wù)的功能是,通過在客戶端調(diào)用時(shí)指定的一個(gè)ID,可以從后臺(tái)數(shù)據(jù)庫中讀取對應(yīng)的房產(chǎn)信息,還有與這個(gè)房產(chǎn)關(guān)聯(lián)的一到多個(gè)房東信息、一到多個(gè)圖片信息,以及地址信息等。Web Service最終把這些信息組合成JSON格式的數(shù)據(jù)返回給調(diào)用方,調(diào)用方可以通過界面來展示相關(guān)信息,也可以通過其他方式去使用這些信息。但是,調(diào)用方具體如何使用這些信息與Web Service服務(wù)本身的測試關(guān)系不大,所以暫且不表了。小蔡需要做的是驗(yàn)證這個(gè)Web Service服務(wù)能否正常地提供JSON數(shù)據(jù)。

1.尋找測試關(guān)鍵點(diǎn)

和開發(fā)人員討論后,小蔡了解到,給Web Service服務(wù)發(fā)送ID后,后臺(tái)系統(tǒng)會(huì)根據(jù)這個(gè)ID去查詢數(shù)據(jù)庫,數(shù)據(jù)庫對應(yīng)的對象模型如圖1-4所示。

圖1-4 生成JSON的對象模型

在這個(gè)對象關(guān)系圖里可以看到,Building對象是圖的核心,其他對象分別和Building對象是一對一或者一對多的關(guān)系。那么小蔡覺得,測試的關(guān)鍵點(diǎn)就是這些數(shù)據(jù)之間的關(guān)系能否正確反映在生成的JSON數(shù)據(jù)里。(特別是要確保生成的JSON數(shù)據(jù)的格式?jīng)]有被破壞,否則解析器就無法解析JSON數(shù)據(jù)了。)

2.爬樓梯開始了

在確定好測試點(diǎn)之后,小蔡測試思路如下。

1)依據(jù)邊界值進(jìn)行測試。由于數(shù)據(jù)庫的數(shù)據(jù)存在多種情況:0條記錄、單條記錄、多條記錄,需要驗(yàn)證根據(jù)這些數(shù)據(jù)條數(shù)生成的JSON文件是否正確。

2)需要關(guān)注對象之間的關(guān)聯(lián)關(guān)系限制。例如一個(gè)Building對應(yīng)0到4個(gè)Callout,那么需要測試當(dāng)多于4個(gè)Callout時(shí),生成的JSON的情況。

3)Web Service允許用戶輸入?yún)?shù),所以需要驗(yàn)證輸入特殊數(shù)據(jù)后,系統(tǒng)是否出現(xiàn)異常或者崩潰的現(xiàn)象,以及是否會(huì)出現(xiàn)SQL注入的問題。

4)Web Service有可能會(huì)被多個(gè)客戶端并發(fā)調(diào)用,因此需要驗(yàn)證其性能是否符合設(shè)計(jì)要求。

根據(jù)測試思路,小蔡設(shè)計(jì)了如下測試用例。

1)Building對象可以有多個(gè)Space,所以可以選取0個(gè)、1個(gè)、6個(gè)Space去看生成的JSON是否正確,這個(gè)可以通過修改數(shù)據(jù)庫數(shù)據(jù)的方式生成假數(shù)據(jù)去完成相關(guān)測試。另外,如圖1-4所示,小蔡還需要測試Building和其他對象的關(guān)系,包括Customer、MediaLink等。小蔡還特別注意了邊界值測試,比如,一個(gè)Building對應(yīng)0~4個(gè)Callout,那么可以用0、1、4、5個(gè)Callout去測試。當(dāng)有5個(gè)Callout的時(shí)候,要去查看返回的JSON數(shù)據(jù)是返回了前4個(gè)Callout,還是返回了前5個(gè),又或者拋出了異常,當(dāng)然,具體哪種結(jié)果是程序設(shè)計(jì)所期望的,需要和開發(fā)人員去溝通。

2)調(diào)用Web Service時(shí)需要指定ID,所以可以測試在ID存在不存在兩種情況下JSON結(jié)果是否返回正常。

3)異常處理,調(diào)用Web Service時(shí)可以把ID換成錯(cuò)誤的參數(shù),例如null、非常長的字符串、空字符串、英文字符、其他文字(例如中文字符)等。接著小蔡就去驗(yàn)證服務(wù)對異常是否做出了正確的處理。

4)安全測試,這個(gè)Web Service會(huì)被外網(wǎng)使用,那就需要在安全性上投入更多的測試。例如,如果URL可以輸入任何參數(shù),這些參數(shù)是否包含危險(xiǎn)數(shù)據(jù)導(dǎo)致SQL注入這類安全問題。還有,因?yàn)閃eb Service被外網(wǎng)使用,那在調(diào)用這個(gè)服務(wù)時(shí)是否需要提供用戶名和密碼。

JSON使用了一種特殊描述數(shù)據(jù)的方式,用“, ”、“[”、“]”、“{”、“}”等分割數(shù)據(jù),小蔡需要測試,如果數(shù)據(jù)庫存儲(chǔ)的數(shù)據(jù)恰好有這些符號,這些數(shù)據(jù)被讀取并生成為JSON后是否會(huì)破壞JSON的格式。

5)性能測試,如何對Web Service進(jìn)行性能測試呢,快速測試方式就是通過一些工具的多線程調(diào)用,或者手工編寫簡單多線程代碼去調(diào)用,然后查看持續(xù)調(diào)用兩小時(shí)之后服務(wù)是否正常,服務(wù)后臺(tái)內(nèi)存曲線是否出現(xiàn)異常,有沒有出現(xiàn)內(nèi)存泄露等問題。另外,查看Web Service是否能在符合性能期望的時(shí)間內(nèi)返回?cái)?shù)據(jù)。

還有一個(gè)邊緣的性能測試路徑是:一個(gè)對象有成千上萬個(gè)關(guān)聯(lián)子對象,能否正常生成對應(yīng)的JSON文件,以及性能是否能達(dá)到期望目標(biāo)。慶幸小蔡這次測試任務(wù)不需要這么做,因?yàn)楹笈_(tái)數(shù)據(jù)明確了不可能存在這種情況,但是在別的測試任務(wù)中可能需要測試。


提示

假設(shè)一種大數(shù)據(jù)量的場景,如果關(guān)聯(lián)的對象有10萬個(gè),我們可以通過工具在數(shù)據(jù)庫中生成10萬條數(shù)據(jù)。這時(shí)候,生成的JSON文件可能會(huì)有幾十兆,那么我們要看需求文檔,對這種場景期待的性能指標(biāo)是多少,例如單個(gè)用戶調(diào)用的話5分鐘之內(nèi)需要生成完畢,20個(gè)用戶并發(fā)情況下10分鐘生成完畢。我們需要驗(yàn)證是否5分鐘或者10分鐘內(nèi)能生成完畢,同時(shí)還要驗(yàn)證,在這個(gè)過程中,后臺(tái)內(nèi)存增長曲線是否出現(xiàn)過于陡峭的現(xiàn)象。


6)查看生成的JSON數(shù)據(jù)中,一些特殊類型的數(shù)據(jù)是否和數(shù)據(jù)庫完全一致。例如,對于float類型,有個(gè)Bug是該類型數(shù)據(jù)精度在數(shù)據(jù)庫中是保存到小數(shù)點(diǎn)后8位,但生成的JSON中只保留小數(shù)點(diǎn)后2位;類似的特殊數(shù)據(jù)還包括非常長的字符串,需要查看是否被截?cái)啵蝗绻跀?shù)據(jù)庫中保存的是0,在JSON中是否會(huì)生成0.00,此外還可以查看空字符串是否正確生成在JSON中。

7)確定服務(wù)是否需要支持HTTPS加密,如果需要,就要去測試返回結(jié)果是否正常。

哈哈!終于爬完樓梯了,小蔡可以松口氣了,走!喝杯啤酒,再來塊炸雞么?

1.4 利用JavaScript加載的漏洞提前購買搶購商品

自從小米手機(jī)推出以來,搶購風(fēng)潮在各類網(wǎng)站上盛行起來,小蔡測試的網(wǎng)站自然也不能免俗,項(xiàng)目組開發(fā)的網(wǎng)站也包含了搶購功能。

對于搶購來說,只有到了特定的時(shí)間后,商品才會(huì)開放并允許搶購,并且搶購網(wǎng)頁的代碼里使用的時(shí)間會(huì)定期和服務(wù)器進(jìn)行同步。

小蔡設(shè)計(jì)了豐富和全面的測試用例,在執(zhí)行基礎(chǔ)測試用例過程中沒有發(fā)現(xiàn)搶購功能的Bug,不過在進(jìn)行多地區(qū)和多語言的性能測試時(shí),她發(fā)現(xiàn)了一個(gè)功能上的漏洞,發(fā)現(xiàn)漏洞的過程是這樣的。

在執(zhí)行性能測試時(shí),需要選取不同國家和地區(qū)的服務(wù)器去模擬用戶的真實(shí)訪問,以驗(yàn)證產(chǎn)品性能是否能滿足用戶體驗(yàn)的要求。顯然,通過這些不同國家和地區(qū)的服務(wù)器訪問網(wǎng)站,會(huì)比小蔡在公司內(nèi)部使用內(nèi)網(wǎng)訪問速度慢,更別提有些國家和地區(qū)網(wǎng)絡(luò)發(fā)展慢,這些區(qū)域的訪問速度就更慢了。

然而正是通過使用這些網(wǎng)速很慢的服務(wù)器,小蔡發(fā)現(xiàn)了這個(gè)功能上的漏洞。

1)在高速或者說正常網(wǎng)速的情況下,當(dāng)用戶打開搶購商品的頁面時(shí),頁面JavaScript會(huì)很快加載并執(zhí)行完成,這時(shí)“加入購物車”的按鈕會(huì)變灰,無法進(jìn)行操作(見圖1-5)。

圖1-5 正常網(wǎng)速,等JavaScript加載完成之后“加入購物車”不能操作

2)而當(dāng)網(wǎng)速很慢時(shí),由于網(wǎng)頁中JavaScript是順序加載執(zhí)行的,所以“加入購物車”按鈕先會(huì)顯示為可以操作的狀態(tài),等JavaScript加載完成后,才會(huì)變灰,不可操作(見圖1-6)。

圖1-6 慢速網(wǎng)絡(luò),在JavaScript加載完成之前“加入購物車”按鈕可以操作

3)所以在慢速網(wǎng)絡(luò)中,當(dāng)頁面JavaScript沒有加載完成時(shí),用戶會(huì)看到“加入購物車”按鈕是可用狀態(tài),因此用戶可以點(diǎn)擊該按鈕,并把搶購商品加入購物車,于是用戶就可以在正式搶購開始之前順利地?fù)尩皆撋唐妨恕?shí)際上甚至在商品無貨的情況下,用戶也可以在JavaScript沒有加載完時(shí)點(diǎn)擊“加入購物車”按鈕,并且成功把無貨商品加入購物車(見圖1-7和圖1-8)。

圖1-7 慢速網(wǎng)絡(luò),無貨的商品也可以添加到購物車

圖1-8 慢速網(wǎng)絡(luò),無貨的商品也可以支付購買

這個(gè)問題是由JavaScript沒有加載完成引起的,但是稍懂技術(shù)的人甚至可以禁用瀏覽器的JavaScript,或者通過查看網(wǎng)絡(luò)訪問的URL后,在按鈕是灰色的狀態(tài)下也有可能提交購買請求。所以,修改這個(gè)Bug時(shí),還需要在提交訂單時(shí)做二次驗(yàn)證,去驗(yàn)證該商品是否有貨,或者是否已經(jīng)處于搶購狀態(tài),當(dāng)狀態(tài)為“是”的時(shí)候,才允許后續(xù)操作。

當(dāng)小蔡把這個(gè)問題提交給開發(fā)人員和產(chǎn)品經(jīng)理后,經(jīng)過大家的討論,發(fā)現(xiàn)如果調(diào)整商品頁面上的JavaScript加載順序,會(huì)涉及很多JavaScript文件的修改,影響范圍會(huì)很廣,包括移動(dòng)頁面上的代碼也需要大幅修正,因此整體工作量比較大。鑒于剛才提到的在提交訂單時(shí)做二次驗(yàn)證也能避免這樣的問題,所以他們一致決定采取做二次驗(yàn)證這種方案來進(jìn)行修復(fù)。

拓展知識:JavaScript的加載與執(zhí)行

瀏覽器的渲染線程和JS執(zhí)行線程是互斥的,并且JavaScript默認(rèn)是阻塞加載的。頁面的下載和渲染都必須停下來等待腳本執(zhí)行完成。JavaScript執(zhí)行過程耗時(shí)越久,瀏覽器等待響應(yīng)用戶輸入的時(shí)間就越長。

(1)加載

不管是script標(biāo)簽直接引入的情況,還是src加載的外部資源,都會(huì)阻塞頁面的渲染。所以一般為了從體驗(yàn)上考慮,我們會(huì)將JS文件放置在body標(biāo)簽閉合之前。不過新版的IE、Firefox、Safari和Chrome都允許并行下載JavaScript文件。但是只是JavaScript文件可以并行下載,渲染還是被阻塞的,頁面仍然必須等待所有JavaScript代碼下載并執(zhí)行完成才能繼續(xù)。

(2)執(zhí)行

每當(dāng)JavaScript文件加載完成后,都會(huì)立刻執(zhí)行該文件。所以你會(huì)看到下一次的請求并不是在上一次請求結(jié)束之后立即開始,中間的耗時(shí)就是上一個(gè)腳本文件的執(zhí)行時(shí)間。

一般對于JavaScript的優(yōu)化建議如下。

1)將script腳本文件放置在body標(biāo)簽閉合之前。

2)減少script請求數(shù)量。

3)無阻塞腳本,在頁面加載完成后才加載JavaScript代碼。這就意味著在window對象的onload事件觸發(fā)后再下載腳本。

▼Defer, async。

▼動(dòng)態(tài)添加script元素。

不過在上面這個(gè)故事中,正是由于對JavaScript的優(yōu)化引發(fā)了搶購頁面先顯示元素可操作,然后在JavaScript加載完成后,JavaScript執(zhí)行使元素不可操作。

1.5 過長的控件名稱造成其他元素顯示錯(cuò)位

小蔡接到一個(gè)公司內(nèi)部在線表單項(xiàng)目的測試任務(wù),這個(gè)項(xiàng)目中有3個(gè)獨(dú)立的角色:管理員A負(fù)責(zé)編輯和布局表單控件,用戶B負(fù)責(zé)填寫表單中控件的內(nèi)容,而審核員C只能查看B操作后的結(jié)果。

這個(gè)需求看上去不難,小蔡快速分析并且記錄了以下幾個(gè)測試點(diǎn),開始了測試工作。

1)A可以正常添加不同類型控件(文本框、富文本框、下拉列表、多選框、單選框等)到頁面中。

2)B可以正常在這些控件中輸入數(shù)據(jù)。

3)C可以正常查看B所有的操作內(nèi)容。

4)針對各個(gè)角色所具有的不同的操作權(quán)限進(jìn)行驗(yàn)證。

5)A更新表單后,B要可以看到對應(yīng)的變化。

6)A未完成操作或者未保存的表單,B是無法看到和使用的。

7)B不保存后者提交操作結(jié)果,C無法看到B的操作內(nèi)容。

8)跨瀏覽器和跨平臺(tái)測試。

在測試過程中,小蔡發(fā)現(xiàn)這個(gè)表單做的類似于我們熟知的Office應(yīng)用的所見即所得的形式,即A在屏幕左上方放置一個(gè)多選框并保存后,B打開頁面后也可以在屏幕左上方看到一個(gè)多選框,最后C登錄后也可以在屏幕左上方看到這個(gè)多選框。這使得整個(gè)功能變得更加容易測試,幾乎是瞥一眼就能看到有沒有問題。

三下五除二就跑完用例,小蔡正準(zhǔn)備結(jié)束測試,偶然間一眼瞥到表單上的多選框選項(xiàng)上,她突然意識到既然多選框和單選框中的選項(xiàng)內(nèi)容都是自己定義的,那在選項(xiàng)內(nèi)容中輸入超長字符串時(shí),會(huì)不會(huì)導(dǎo)致該控件的顯示位置發(fā)生變化呢?

帶著這個(gè)疑問,小蔡重新使用A角色設(shè)置了一個(gè)超長的多選框選項(xiàng)名稱,然后用B角色做了勾選操作,最后再用C去查看結(jié)果。結(jié)果她發(fā)現(xiàn)了問題:C查看到的結(jié)果中,勾選后的內(nèi)容和多選框顯示錯(cuò)位了。

再仔細(xì)重現(xiàn)了一遍問題后,小蔡發(fā)現(xiàn)A在編輯模式給多選框設(shè)置超長的選項(xiàng)名稱的時(shí)候,在界面上多選框的位置被擠到了文本中央,如圖1-9所示。

圖1-9 表單編輯界面

B在操作視圖中看到的這個(gè)多選框又被強(qiáng)制對齊到了文字最左側(cè),如圖1-10所示。

圖1-10 表單操作界面

而C在審核視圖中看到的情況卻是A和C的結(jié)合體,即多選框被重置到了文字中央,而被勾選的位置卻出現(xiàn)在文字的最左端(見圖1-11)。

圖1-11 操作結(jié)果查看頁面

有了小蔡的過程重現(xiàn),開發(fā)人員很快就定位到出現(xiàn)問題的原因:首先是在A用戶使用的過程中(見圖1-9),沒有把操作結(jié)果查看視圖中的多選框強(qiáng)制左對齊。其次是在用戶C使用過程中(見圖1-11),由于使用jQuery定制化多選框中的代碼邏輯錯(cuò)誤,導(dǎo)致勾選狀態(tài)下的可勾選位置和多選框本身出現(xiàn)了分離,最終導(dǎo)致問題出現(xiàn)。

核心知識:常見的HTML元素及常見檢查點(diǎn)

1)<select>標(biāo)簽,可創(chuàng)建單選或多選菜單

常見檢查點(diǎn):下拉列表數(shù)據(jù)的正確性;數(shù)據(jù)被選中是否正確,是否變形,是否只讀,多選/單選是否正確

2)<label>標(biāo)簽,相當(dāng)于一個(gè)展示文本框

常見檢查點(diǎn):文本是否正確;文本字體、大小、顏色、間距是否正確;for屬性是否綁定了正確的元素等

3)<input>標(biāo)簽,用于收集用戶信息。

根據(jù)不同的type屬性值,輸入字段擁有很多種形式。可以是文本字段、復(fù)選框、掩碼后的文本控件、單選按鈕、按鈕等。

4)button可點(diǎn)擊的按鈕,點(diǎn)擊后通常會(huì)觸發(fā)相應(yīng)事件。

常見檢查點(diǎn):點(diǎn)擊按鈕后觸發(fā)的行為和期望不符合;頁面卡死未響應(yīng);點(diǎn)擊后變形等

5)text文本輸入。

常見檢查點(diǎn):是否只讀;SQL注入攻擊;輸入內(nèi)容超過文本框長度是否引起形變等。

6)checkbox多選框

常見檢查點(diǎn):選中/取消勾選是否有效;文本長度過長是否引起形變;頁面刷新后是否被自動(dòng)取消/勾選等

7)radio單選框。

常見檢查點(diǎn):單選是否有效;文本長度過長是否引起形變;頁面刷新后是否被自動(dòng)取消/勾選等

8)image圖片區(qū)域。

常見檢查點(diǎn):圖片加載是否正確;圖片加載失敗或者關(guān)閉時(shí)行為是否符合預(yù)期鼠標(biāo)指針移動(dòng)到圖片上后顯示的文本是否正確;圖片是否可以正確點(diǎn)擊/拖曳等

9)submit提交按鈕,提交當(dāng)前<form>表單信息到指定頁面。

常見檢查點(diǎn):提交信息完整性等

1.6 多次操作本該禁用的頁面組件造成服務(wù)器出錯(cuò)

對頁面上的組件進(jìn)行多次點(diǎn)擊是測試人員經(jīng)常使用的小技巧之一,通常小蔡在執(zhí)行完基本測試用例之后,開始進(jìn)行探索性測試時(shí)會(huì)使用這個(gè)技巧,并且利用這個(gè)測試技巧發(fā)現(xiàn)了不少問題。

這些問題主要集中在用戶提交服務(wù)器請求后服務(wù)器進(jìn)行處理的相關(guān)功能上,例如讀取、保存、提交、刪除等功能(見圖1-12)。

圖1-12 用戶通過“刪除”“保存”等功能和服務(wù)器交互

小蔡發(fā)現(xiàn)如果網(wǎng)絡(luò)速度比較慢或者產(chǎn)品本身性能不夠好,在用戶點(diǎn)擊了這些功能按鈕后,而頁面刷新完成之前這段時(shí)間內(nèi),該功能按鈕仍然可能被用戶繼續(xù)點(diǎn)擊。即使有些頁面上的按鈕處于灰色不可用狀態(tài),但當(dāng)你嘗試點(diǎn)擊這些灰色的按鈕,會(huì)發(fā)現(xiàn)點(diǎn)擊后仍然會(huì)給服務(wù)器端發(fā)送請求(見圖1-13)。

圖1-13 功能按鈕在被置灰后仍然可以使用

這樣帶來了一系列問題,舉例來說,對于保存功能,用戶多次點(diǎn)擊后會(huì)向后臺(tái)發(fā)送多次請求,數(shù)據(jù)庫中也會(huì)產(chǎn)生多條重復(fù)的數(shù)據(jù),這樣不僅會(huì)造成數(shù)據(jù)統(tǒng)計(jì)錯(cuò)誤,更會(huì)給再次使用這些數(shù)據(jù)的人或程序造成很大的麻煩。一個(gè)更極端的例子是免密碼支付的場景,當(dāng)用戶不小心多次點(diǎn)擊支付按鈕后,會(huì)給用戶造成不小的損失;對于刪除功能來說,多次點(diǎn)擊“刪除”按鈕后,實(shí)際上第一個(gè)請求已經(jīng)讓數(shù)據(jù)庫將對應(yīng)的數(shù)據(jù)刪除了,接下來的刪除請求可能會(huì)造成后臺(tái)程序的大量異常。

小蔡發(fā)現(xiàn)解決此類問題也很簡單,只需要開發(fā)人員在編寫代碼時(shí)注意,只允許對該類功能按鈕操作一次,在用戶操作之后,不僅需要把對應(yīng)的功能按鈕置灰,同時(shí)需要取消這些功能按鈕上面綁定的事件響應(yīng)處理機(jī)制。

通常小蔡除了會(huì)在小組的回顧會(huì)議上向開發(fā)人員分析這些問題產(chǎn)生的原因和避免方式,還在每張開發(fā)故事卡上明確地標(biāo)注需要測試多次快速點(diǎn)擊按鈕的場景,這樣可以讓開發(fā)人員從意識上提高對這類缺陷的警惕,從而在編寫代碼時(shí)注意預(yù)防此類問題的發(fā)生。

拓展知識:回顧會(huì)議

無論一個(gè)Scrum團(tuán)隊(duì)有多出色,總有需要改進(jìn)的地方。即使一個(gè)好的Scrum團(tuán)隊(duì)會(huì)不斷尋找需要改進(jìn)的方面,這個(gè)團(tuán)隊(duì)也應(yīng)該做一個(gè)簡單回顧,目的是在每個(gè)迭代的最后來回顧團(tuán)隊(duì)目前做得如何以及找到改進(jìn)的方法。

回顧會(huì)議(Sprint Retrospective)通常發(fā)生在每個(gè)迭代最后一天,用來幫助團(tuán)隊(duì)進(jìn)行自我改進(jìn)。會(huì)議長度通常為1個(gè)小時(shí),團(tuán)隊(duì)成員在一起列出團(tuán)隊(duì)?wèi)?yīng)該做的事情、需要停止做的事情、應(yīng)該保持下去的事情。接著團(tuán)隊(duì)成員對所有提議進(jìn)行投票,這樣可以在有限的時(shí)間里優(yōu)先討論大家最關(guān)心的幾個(gè)問題。通過集思廣益,提出改進(jìn)方法,在緊接著的迭代中進(jìn)行改進(jìn)。

在下個(gè)迭代的回顧會(huì)議一開始,會(huì)首先關(guān)注上一次回顧會(huì)議的結(jié)果是否被落實(shí)。

1.7 頁面跳轉(zhuǎn)后出現(xiàn)HTTP 400錯(cuò)誤

公司網(wǎng)站又升級了!這次升級后網(wǎng)站增加了一個(gè)保險(xiǎn)報(bào)價(jià)功能:客戶先在網(wǎng)站上回答公司設(shè)計(jì)的各種問題(單選題),系統(tǒng)會(huì)把答案匯總起來,傳給后臺(tái)計(jì)算價(jià)格,然后后臺(tái)系統(tǒng)把計(jì)算出的保險(xiǎn)報(bào)價(jià)返回給網(wǎng)站并顯示在頁面上。

從功能上看,小蔡覺得這個(gè)功能需求的關(guān)鍵是網(wǎng)站上設(shè)計(jì)的每一個(gè)問題都會(huì)作為一個(gè)價(jià)格因子并對最終報(bào)價(jià)產(chǎn)生影響。測試的重點(diǎn)應(yīng)該是檢查每個(gè)因子能夠引起的價(jià)格變化是否符合預(yù)期。另外由于每類問題都分布在不同的頁面上,所以需要確保在頁面切換后,系統(tǒng)能保存之前選擇的答案而不丟失。最后性能要求是在后臺(tái)系統(tǒng)返回報(bào)價(jià)的時(shí)間上,根據(jù)業(yè)務(wù)方的需求需要遵守2/5/8原則,最長不能超過8秒,所以還需要增加對應(yīng)的性能測試。

設(shè)計(jì)完用例,小蔡和開發(fā)人員一起進(jìn)行了冒煙測試,結(jié)果每個(gè)功能都符合預(yù)期。于是小蔡在正式測試階段把大部分精力都放到了驗(yàn)證各個(gè)價(jià)格因子對價(jià)格變化的影響上面。

經(jīng)過大量的反復(fù)選擇問題答案和頁面切換操作后,小蔡像之前一樣準(zhǔn)備進(jìn)入到報(bào)價(jià)匯總頁面查看最終價(jià)格,突然發(fā)現(xiàn)頁面出現(xiàn)HTTP 400錯(cuò)誤(見圖1-14)!

圖1-14 HTTP 400異常

小蔡眼睛一亮,趕緊回退到上一個(gè)頁面,重新點(diǎn)擊報(bào)價(jià)匯總按鈕再次進(jìn)入報(bào)價(jià)匯總頁面,反復(fù)試了好幾次,發(fā)現(xiàn)仍然會(huì)碰到HTTP 400這個(gè)問題。于是她關(guān)閉并重新啟動(dòng)瀏覽器,嘗試再次重現(xiàn)這個(gè)問題,準(zhǔn)備整理下出現(xiàn)問題的場景,然后報(bào)給研發(fā)人員修復(fù),結(jié)果這次卻正常進(jìn)入到報(bào)價(jià)匯總頁面。

小蔡覺得挺奇怪的,難道剛才是服務(wù)器“抽風(fēng)”才導(dǎo)致HTTP 400異常?于是她又一連操作了好幾次到匯總頁面的場景,結(jié)果都沒有重現(xiàn)問題。雖然感覺很神奇,但是因?yàn)闆]有能夠重現(xiàn)問題,小蔡也只能暫時(shí)作罷,一邊想著肯定是服務(wù)器抽風(fēng)了吧,一邊繼續(xù)測試價(jià)格因子。

5分鐘以后,當(dāng)她再次準(zhǔn)備進(jìn)入到價(jià)格匯總頁面時(shí),問題又出現(xiàn)了,再次顯示HTTP 400錯(cuò)誤頁面!看著頁面上提示的錯(cuò)誤信息,小蔡突然間有點(diǎn)兒明白了,提示信息說HTTP Request Header長度過長,因此問題應(yīng)該是在HTTP Request Header上。小蔡利用瀏覽器自帶的開發(fā)工具查看了下HTTP的請求頭,結(jié)果瞬間就發(fā)現(xiàn)Cookie看上去似乎比平時(shí)看到的要長好多(見圖1-15)。

圖1-15 從瀏覽器工具中查看Cookie

小蔡懷疑是Cookie有問題,于是就找開發(fā)人員確認(rèn)。在給開發(fā)人員演示了一遍這個(gè)Bug后,開發(fā)人員終于分析出造成這一結(jié)果的直接原因是Cookie長度太長,導(dǎo)致Request Header長度超標(biāo),最后發(fā)生HTTP Error 400。而再深入一層的根本原因是開發(fā)人員為了在切換頁面時(shí)保存前幾個(gè)頁面的答案狀態(tài),把這些狀態(tài)存到了Cookie里面,而每次翻頁的時(shí)候又把答案信息錯(cuò)誤地添加到Cookie已有信息之后,導(dǎo)致隨著小蔡翻頁操作越來越多,Cookie也越來越長,最后當(dāng)Cookie長度超過瀏覽器限制后就產(chǎn)生了錯(cuò)誤。

知道了問題原因,小蔡仔細(xì)回想了下整個(gè)用例設(shè)計(jì)過程,覺得這樣的問題即使通過覆蓋各種用戶使用場景仍然會(huì)不好發(fā)現(xiàn)。但如果測試人員在測試之前能夠?qū)φ麄€(gè)功能的設(shè)計(jì)或者實(shí)現(xiàn)有一些了解的話,就可以注意到這個(gè)點(diǎn),并且加以測試了。例如這次的Cookie超長問題,如果測試人員和開發(fā)人員先進(jìn)行一些溝通,了解到代碼是通過把信息存儲(chǔ)到Cookie中去實(shí)現(xiàn)該功能,那么測試人員會(huì)很自然地想到Cookie長度通常是有限制的,因此會(huì)對這種存儲(chǔ)信息的方式做特定的測試。

核心知識:HTTP Request Header長度限制

Request Header就是往服務(wù)器發(fā)送的請求頭,HTTP協(xié)議中并沒有限制Header的大小。理論上無論我們的Header有多大都是可以的。

但實(shí)際上各個(gè)主流瀏覽器都會(huì)對Header長度進(jìn)行限制,從幾十KB到幾百M(fèi)B不等,基本上能滿足平時(shí)的需求。此外,在服務(wù)端也可以對Heder長度做限制。比如Nginx就可以限制Header的長度。

HTTP Header如果不限制大小會(huì)有什么影響?

如果某個(gè)網(wǎng)站的服務(wù)器是不限制Header大小的,那么它就有可能被黑客利用實(shí)施攻擊,比如DDoS。黑客可以利用這一點(diǎn),發(fā)送一個(gè)非常大(比如幾MB)的請求,會(huì)占用服務(wù)器一個(gè)進(jìn)程來專門處理這個(gè)請求。此類請求數(shù)量過多時(shí),服務(wù)器就無法提供其他對外服務(wù)。

1.8 使用沒有添加時(shí)間戳的緩存使用戶看到過期數(shù)據(jù)

當(dāng)代主流的網(wǎng)站都使用了緩存技術(shù),目的在于減少用戶請求對服務(wù)器的壓力。當(dāng)用戶首次通過瀏覽器請求服務(wù)器的資源時(shí),服務(wù)器會(huì)返回所有的資源;當(dāng)用戶再次請求服務(wù)器資源時(shí),瀏覽器會(huì)判斷資源是否已更新,如果更新了,再向服務(wù)器發(fā)起請求,如果沒有更新,就使用瀏覽器中緩存的資源。

這里有一個(gè)問題,瀏覽器是如何判斷資源是否更新了?一般來說,資源文件在文件名中要么添加時(shí)間戳(見圖1-16),要么添加標(biāo)識符(標(biāo)識符可以是任何一組區(qū)別資源不同版本的數(shù)值,如v1、v2,或者GUID等)來唯一區(qū)分資源的不同版本(見圖1-17)。只要本地緩存的資源文件和服務(wù)器端最新的資源文件名稱不一樣,瀏覽器就要從服務(wù)器端獲取新的資源文件,如果一樣,就使用本地緩存的資源。

圖1-16 帶有時(shí)間戳的資源文件

圖1-17 帶有標(biāo)識符的資源文件

如果資源文件沒有被添加時(shí)間戳或者標(biāo)識符呢?那用戶只能通過手動(dòng)清除瀏覽器的緩存來強(qiáng)制獲取最新的資源文件了,不過這樣等于所有用戶請求的文件都沒有從瀏覽器緩存中讀取,也就沒有為服務(wù)器緩解訪問壓力。并且絕大多數(shù)用戶并不會(huì)去手動(dòng)清除瀏覽器的緩存,這就導(dǎo)致用戶看到網(wǎng)頁的資源文件不是最新的。

最近小蔡測試的商品詳細(xì)信息頁面出現(xiàn)的Bug就屬于這種情況。根據(jù)用戶線上反饋,當(dāng)用戶修改了商品圖片并且發(fā)布之后,不能及時(shí)看到更新后的圖片,而是需要等一段不確定的時(shí)間才能看到更新后的圖片。

經(jīng)過小蔡和開發(fā)人員的調(diào)查,發(fā)現(xiàn)導(dǎo)致這個(gè)問題的原因是緩存資源文件沒有被設(shè)置時(shí)間戳或者標(biāo)識符,導(dǎo)致用戶修改后不能看到更新后的圖片。而之所以會(huì)造成不確定時(shí)間后才能看到更新后的圖片,是由于不同瀏覽器對于沒有設(shè)置時(shí)間戳或者標(biāo)識符的緩存資源文件處理不一致造成的。

例如IE緩存時(shí)間就是一個(gè)Session的時(shí)間,如果用戶打開一個(gè)新的IE窗口時(shí),他們就會(huì)獲取最新的靜態(tài)資源;而其他瀏覽器(例如Firefox),則會(huì)通過HTTP頭文件中Last-Modified參數(shù)的具體定義來判斷是否需要去重新獲取資源。

而小蔡在之前的測試中,為了避免緩存數(shù)據(jù)對測試結(jié)果的影響,她在瀏覽器中設(shè)置了每次退出瀏覽器時(shí)清空緩存(見圖1-18),這反而導(dǎo)致小蔡漏測了緩存沒有及時(shí)刷新的問題。

圖1-18 退出IE時(shí)自動(dòng)刪除緩存

由于緩存在Web產(chǎn)品中是普遍存在的,所以小蔡立刻取消了瀏覽器中清除緩存的設(shè)置,改為使用手工清除緩存的方式。當(dāng)她之后在測試中遇到測試結(jié)果和預(yù)期結(jié)果不同,并且有可能是緩存未清除造成的情況時(shí),她會(huì)手動(dòng)清除緩存,這樣可以更準(zhǔn)確地進(jìn)行測試。

核心知識:Web緩存

瀏覽器本身有緩存機(jī)制,比較常見的是瀏覽器會(huì)緩存訪問過的網(wǎng)頁,當(dāng)再次訪問這個(gè)URL地址的時(shí)候,如果網(wǎng)頁沒有更新,就不會(huì)再次下載網(wǎng)頁,而是直接使用本地緩存中的網(wǎng)頁。只有當(dāng)網(wǎng)站明確標(biāo)識資源已經(jīng)更新,瀏覽器才會(huì)再次下載網(wǎng)頁。

使用Web緩存可以減少網(wǎng)絡(luò)帶寬消耗、降低服務(wù)器壓力、減少網(wǎng)絡(luò)延遲,加快頁面打開速度。同時(shí)我們也可以使用代理服務(wù)器,在代理過程中做緩存處理,也可以使用CDN網(wǎng)絡(luò)提供的緩存能力。

除了上述提到的軟件之外的緩存方式,服務(wù)器端軟件內(nèi)部也經(jīng)常使用各種緩存,例如使用數(shù)據(jù)庫進(jìn)行緩存,或者使用內(nèi)存進(jìn)行緩存,也可以提高用戶訪問網(wǎng)頁的速度。

1.9 代理服務(wù)器過度緩存文件導(dǎo)致讀取錯(cuò)誤的賬號信息

緩存不僅僅是Web產(chǎn)品為了緩解用戶訪問帶給服務(wù)器的壓力而設(shè)置的,而且用戶(例如企業(yè))為了減少多用戶訪問同一個(gè)網(wǎng)站占用過多帶寬,也可以設(shè)置自己內(nèi)部的緩存服務(wù)器。

小蔡的公司就為大家設(shè)置了這樣一組緩存服務(wù)器。這些緩存服務(wù)器的原理和瀏覽器的緩存原理類似,當(dāng)大家訪問網(wǎng)頁時(shí),首先請求的是這些服務(wù)器上的資源,如果沒有命中,也就是說這些資源不在公司內(nèi)部的緩存服務(wù)器上,這些服務(wù)器才向公司外部真實(shí)的服務(wù)器發(fā)送請求,等請求返回后,緩存服務(wù)器還需要把這些資源保存在本地,以便于其他用戶對同一網(wǎng)頁的再次訪問,然后才把這些資源發(fā)送回最開始發(fā)送請求的用戶(見圖1-19)。

圖1-19 企業(yè)內(nèi)部緩存服務(wù)器

當(dāng)然我們這里只是簡單地介紹一下內(nèi)部緩存服務(wù)器進(jìn)行緩存的過程,很多例如緩存如何過期這些細(xì)節(jié)在這里就不詳述了。

小蔡在測試網(wǎng)站的過程中,發(fā)現(xiàn)自己登錄測試賬號后,首先會(huì)看到其他測試賬號信息(而且這個(gè)賬號不固定),如果這時(shí)候進(jìn)行任何操作,很有可能出現(xiàn)錯(cuò)誤頁面,尤其是與賬戶信息相關(guān)的操作,所以小蔡只有強(qiáng)制刷新或者退出后,再次登錄才能看到剛才登錄的賬號信息,并且正常地進(jìn)行測試。這個(gè)問題在早上一般不會(huì)發(fā)生,而其他時(shí)間出現(xiàn)的頻率就要高很多。

發(fā)生幾次之后,小蔡覺得很好奇,就詢問了其他的測試人員,發(fā)現(xiàn)大家都有同樣的問題,在和老牛一起分析后,他們覺得有可能是公司內(nèi)部緩存服務(wù)器機(jī)制導(dǎo)致了這個(gè)問題,但是至于為什么早上這個(gè)問題不容易發(fā)生,還是不太了解。

帶著這個(gè)問題還有他們的懷疑,小蔡和老牛找到了公司信息維護(hù)的相關(guān)人員。經(jīng)確認(rèn),確實(shí)是他們緩存了測試服務(wù)器的資源,而且還緩存了登錄用戶的Cookie文件。

所以當(dāng)測試人員訪問測試服務(wù)器時(shí),緩存服務(wù)器將輸入的用戶名和密碼以及Cookie文件一起發(fā)送給了測試服務(wù)器。雖然服務(wù)器接收了新的登錄用戶名和密碼,但是顯示卻使用的是Cookie里面的信息。所以,在進(jìn)行賬戶相關(guān)操作時(shí),服務(wù)器并不知道應(yīng)該對哪個(gè)賬號進(jìn)行操作,于是出現(xiàn)了錯(cuò)誤頁面。

那為什么早上這個(gè)問題出現(xiàn)的幾率會(huì)小很多呢?根據(jù)小蔡他們的猜測,很可能是因?yàn)樵缟险介_始執(zhí)行測試的人員比較少,時(shí)間間隔長,導(dǎo)致Cookie文件雖然被發(fā)送,但是過期了,所以服務(wù)器很少會(huì)出現(xiàn)錯(cuò)誤頁面。

最后,經(jīng)過公司信息維護(hù)的相關(guān)人員的重新配置,取消了對登錄用戶Cookie文件的緩存,小蔡他們再也沒有遇到這個(gè)賬號顯示錯(cuò)亂的問題。

拓展知識:Session和Cookie

由于HTTP是一個(gè)無狀態(tài)協(xié)議,客戶端每次發(fā)出請求時(shí),本次請求無法得知上一次請求的狀態(tài)信息。在常見的網(wǎng)站中,服務(wù)端需要在多次HTTP請求間共享數(shù)據(jù),例如用戶在購物網(wǎng)站登錄后,跳轉(zhuǎn)到商品頁面,這時(shí)候服務(wù)器端需要知道該用戶是否已經(jīng)登錄過。在技術(shù)上可以使用Session和Cookie去做這件事情。

簡單來說,Session是在服務(wù)端保存的數(shù)據(jù),Cookie是在客戶端瀏覽器中保存的數(shù)據(jù),它們一起合作,來實(shí)現(xiàn)跨HTTP請求的數(shù)據(jù)共享。例如,當(dāng)服務(wù)器第一次創(chuàng)建Session時(shí),在內(nèi)存中記錄了用戶的信息,同時(shí)會(huì)在HTTP協(xié)議中告訴客戶端,需要在Cookie里面記錄一個(gè)Session ID,以后每次請求都會(huì)把這個(gè)Session ID發(fā)送到服務(wù)器,服務(wù)器就可以知道這個(gè)用戶是誰了,從而能從服務(wù)器端查詢出此用戶的各種相關(guān)信息。

1.10 多余的空格造成服務(wù)器被刪除

在敏捷測試中,測試工作不僅包括設(shè)計(jì)和執(zhí)行測試用例、編寫測試報(bào)告,以及測試計(jì)劃和策略的制定,還有測試部署腳本等工作。這次小蔡在執(zhí)行部署腳本的測試過程中發(fā)現(xiàn)了一個(gè)嚴(yán)重的問題,這個(gè)Bug會(huì)導(dǎo)致整個(gè)測試服務(wù)器被刪除,事情的緣由是這樣的。

小蔡根據(jù)開發(fā)人員提交的部署腳本和執(zhí)行步驟,一步步在測試環(huán)境中進(jìn)行部署,同時(shí)去驗(yàn)證部署腳本中是否有遺漏和錯(cuò)誤。當(dāng)執(zhí)行完部署腳本中刪除臨時(shí)文件的步驟后,小蔡發(fā)現(xiàn)后續(xù)步驟都不能執(zhí)行了!經(jīng)過調(diào)查發(fā)現(xiàn)原因是測試服務(wù)器已經(jīng)被格式化了。

雖然測試服務(wù)器都是虛擬化的,可以很快在測試環(huán)境重新建立一臺(tái)測試服務(wù)器,但是,如果這個(gè)Bug出現(xiàn)在生產(chǎn)環(huán)境,那將會(huì)是非常大的災(zāi)難!

小蔡找到了剛才執(zhí)行過程中出現(xiàn)問題的語句,是“rm -rf / tmp”。她仔細(xì)檢查了整個(gè)語句,發(fā)現(xiàn)測試服務(wù)器被格式化的原因是在tmp前面多了一個(gè)空格,這個(gè)空格不仔細(xì)看還看不出來(業(yè)內(nèi)也有同樣的知名例子:Bumblebee誤刪用戶文件夾,如圖1-20所示,在最后一行的/usr /lib…語句中在usr后就被多寫了一個(gè)空格)。

圖1-20 Bumblebee誤刪用戶文件夾

不過在Linux系統(tǒng)中,即使輸入了災(zāi)難性的操作語句,但如果沒有管理員的權(quán)限也是無法執(zhí)行的,因?yàn)樵趫?zhí)行這條語句的時(shí)候,只會(huì)出現(xiàn)權(quán)限不足,無法操作的提示,不會(huì)把服務(wù)器整個(gè)刪除。如圖1-21所示,執(zhí)行刪除語句的用戶由于沒有管理員權(quán)限而被拒絕執(zhí)行了。

圖1-21 刪除文件需要相應(yīng)的權(quán)限

所以小蔡下一步需要在腳本中找出是哪里賦予了管理員權(quán)限,導(dǎo)致后來刪除語句被允許執(zhí)行的。再仔細(xì)查找之前的部署腳本,果然不出所料,之前有一個(gè)操作步驟需要用管理員權(quán)限來復(fù)制幾個(gè)不同的文件到管理員文件夾。通常做此類操作時(shí),會(huì)只針對這條語句賦予權(quán)限,例如使用sudo命令的這條語句:“sudo cp xxx.zip /var/xxx/xxx/”,但開發(fā)人員在這里為了簡化腳本的書寫,把每一句最開始的sudo轉(zhuǎn)換成單獨(dú)的一條“su-root”,這種改變造成之后執(zhí)行的所有語句都被賦予管理員權(quán)限進(jìn)行執(zhí)行,最終導(dǎo)致格式化測試服務(wù)器的命令也被執(zhí)行了。

小蔡把這一發(fā)現(xiàn)告訴了開發(fā)人員后,開發(fā)人員修改了兩處代碼:一是刪除“su-root”命令,改為針對每次執(zhí)行需要特定權(quán)限的語句時(shí)單獨(dú)添加sudo的方式,確保腳本執(zhí)行的權(quán)限是正確的;第二是刪除了導(dǎo)致測試服務(wù)器被格式化的那個(gè)空格。

核心知識①:sudo和su

sudo用于類UNIX操作系統(tǒng)(如BSD)、Mac OS X,以及GNU/Linux,以允許用戶通過安全的方式使用特殊的權(quán)限去運(yùn)行程序,例如使用系統(tǒng)的超級用戶權(quán)限去運(yùn)行程序。

su命令可以讓操作者在虛擬控制臺(tái)切換當(dāng)前用戶賬戶,使用su的缺點(diǎn)之一是必須要先獲取超級用戶的密碼。

核心知識②:Linux文件權(quán)限

Linux系統(tǒng)中的文件和目錄通過使用訪問許可權(quán)限,來確定誰能通過何種方式進(jìn)行訪問與操作。文件或目錄的訪問權(quán)限分為只讀、只寫和可執(zhí)行3種。

確定了文件的訪問權(quán)限后,用戶能使用Linux系統(tǒng)自帶的chmod命令來重新設(shè)定訪問權(quán)限,也能利用chown命令來更改文件或目錄的所有者,或者使用chgrp命令來更改文件或目錄的用戶組。

拓展知識:虛擬化

在計(jì)算機(jī)技術(shù)中,虛擬化(virtualization)是一種資源管理技術(shù),將計(jì)算機(jī)的各種實(shí)體資源,如服務(wù)器、網(wǎng)絡(luò)、內(nèi)存及存儲(chǔ)等,予以抽象、轉(zhuǎn)換后呈現(xiàn)出來,供多個(gè)用戶共享使用。

1.11 IE 9不支持占位符導(dǎo)致搜索行為異常

對于瀏覽器兼容性測試,一直都是Web測試中重要的一環(huán),小蔡在測試產(chǎn)品中自然也不能漏掉。

由于小蔡測試的產(chǎn)品是面向普通用戶的,所以小蔡選擇進(jìn)行測試的瀏覽器,也是開發(fā)團(tuán)隊(duì)選擇優(yōu)先支持的瀏覽器,是基于市場占有率最高的幾款瀏覽器:Chrome、Firefox、Safari和IE。這些瀏覽器的版本也很多,如果全部支持也是不可能的,所以開發(fā)團(tuán)隊(duì)選擇支持最新版本的Chrome、Firefox和Safari,以及IE 9~I(xiàn)E 11,還有IE EDGE。

Chrome和Safari都是基于WebKit核心的,所以差別不大。Firefox雖然基于Gecko,但是對于絕大多數(shù)Web標(biāo)準(zhǔn)協(xié)議都是支持的,所以和Chrome及Safari的差別也很小。IE因?yàn)槭褂玫氖俏④涀约旱膬?nèi)核,所以和其他瀏覽器的差別會(huì)大不少,尤其是版本較早的IE 9~I(xiàn)E 11,不過微軟在IE EDGE上已經(jīng)開始兼容WebKit,并且兼容最新的Web標(biāo)準(zhǔn)協(xié)議,所以和其他瀏覽器的差別也不大了。

小蔡根據(jù)搜集到的這些瀏覽器差異的信息,決定兼容性測試的重點(diǎn)放在測試Chrome和IE 9兩個(gè)瀏覽器上面。

由于產(chǎn)品是大型購物網(wǎng)站,所以用戶需要使用搜索特定商品來查看商品詳細(xì)信息。而在搜索框中,業(yè)務(wù)方希望推廣一些暢銷產(chǎn)品,所以使用了占位符(Placeholder)的方式,使用戶在點(diǎn)擊搜索框之前,在搜索框的搜索關(guān)鍵字部分,看到的是通過占位符設(shè)置的推廣產(chǎn)品的信息。

小蔡在執(zhí)行瀏覽器兼容性測試時(shí)發(fā)現(xiàn),由于添加了占位符,導(dǎo)致Chrome和IE 9瀏覽器上搜索功能的行為不一致(見圖1-22)。

圖1-22 IE 9的占位符會(huì)被當(dāng)作搜索關(guān)鍵字

▼在Chrome上當(dāng)用戶點(diǎn)擊搜索框時(shí),占位符會(huì)消失,用戶輸入的字符會(huì)被當(dāng)作搜索關(guān)鍵字進(jìn)行搜索。

▼在IE 9上當(dāng)用戶點(diǎn)擊搜索框時(shí),占位符并不會(huì)消失,用戶輸入的字符以及占位符的內(nèi)容會(huì)一起被當(dāng)作搜索關(guān)鍵字進(jìn)行搜索。

這就導(dǎo)致用戶在兩個(gè)瀏覽器上使用相同的操作步驟進(jìn)行搜索時(shí)的搜索結(jié)果不一致。想要解決這個(gè)問題,用戶只有一個(gè)一個(gè)字符地刪除IE 9瀏覽器中搜索框里的占位符,這對用戶來說并不友好。

經(jīng)過開發(fā)人員調(diào)查發(fā)現(xiàn),這個(gè)問題的原因是IE 9瀏覽器本身就不支持占位符,所以對于占位符的操作也是有問題的。開發(fā)人員只好對IE 9上的搜索框單獨(dú)處理,給搜索框先添加一組灰色的默認(rèn)文字,來展示暢銷商品,等用戶點(diǎn)擊搜索框時(shí)再清除這些字符。

小蔡慶幸IE 9是支持的最低版本的IE,如果需要再兼容IE 6~I(xiàn)E 8,那瀏覽器之間的差異更多更復(fù)雜,也會(huì)讓開發(fā)和測試工作的難度加大不少。同時(shí)她決定定期查看用戶的瀏覽器使用率和使用量,等大量用戶不再使用IE 9時(shí),就可以不用再做現(xiàn)在這種針對特定瀏覽器編寫代碼和測試某項(xiàng)功能了。

拓展知識:瀏覽器內(nèi)核

排版引擎負(fù)責(zé)解析標(biāo)記式內(nèi)容(如HTML、XML、CSS、XSL及圖像文件等),并將排版后的內(nèi)容輸出至顯示器或打印機(jī)。Chromium/Chrome(iOS版除外)與Opera使用的瀏覽器引擎是基于Blink,是WebKit的一個(gè)分支,F(xiàn)irefox網(wǎng)頁瀏覽器使用了Gecko網(wǎng)頁瀏覽器引擎,Internet Explorer使用的是Trident網(wǎng)頁瀏覽器引擎。

1.12 小結(jié)

本章我們介紹了由特定技術(shù)引起的功能測試問題,下一章我們會(huì)接觸到由于測試覆蓋導(dǎo)致的問題。

主站蜘蛛池模板: 东乌珠穆沁旗| 渭源县| 福贡县| 五峰| 九台市| 大新县| 张北县| 琼中| 新营市| 左权县| 沁源县| 图们市| 闸北区| 北京市| 凤台县| 潮安县| 台中市| 中超| 阳东县| 黑龙江省| 改则县| 景德镇市| 赣州市| 宕昌县| 桦南县| 汶上县| 蒲城县| 长宁区| 龙里县| 武夷山市| 锦州市| 南靖县| 星子县| 泗洪县| 和平区| 昭觉县| 沈丘县| 上犹县| 武山县| 苍溪县| 抚松县|