qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          軟件測試工具設計中的協作

           做平臺性的測試工具,通常涉及到各個角色,接觸最多的就是測試工程師和開發工程師。

            和用戶溝通

            普通用戶抱怨質疑多,方案建議少;但是測試工具的大部分用戶是測試工程師和開發工程師。

            他們一般都明白自己所需并具備清楚表達的能力,有明確的價值目標,有良好的方向感和情境感,有些自己本身就獨立開發過優秀的工具,所以在整個工具開發的生命周期中,他們能承擔更多角色,參與更多過程。

            測試人員提前介入需求,甚至擔任某些模塊的PD,參與到產品開發中來,對工具的順利推廣也很有幫助。畢竟,是自個兒親生的。這批同學是工具最早的用戶,他們的工作模式能影響和帶動一批用戶。

            對設計師的要求

            測試工具和一般互聯網產品有所不同。

            傳統頁面以導航和內容為主,測試工具內容并不復雜,重功能和交互。

            區別于導航和內容的羅列, 作為管理和幫助性工具,一個頁面通常會集中很多功能;工具所爭取減少的每一步操作都是在節約工程師的時間,出于工作效率考慮,需要更豐富便捷的交互操作。

            在實際開發過程中,大部分前端問題也是在交互方面。從用戶反饋來看,用戶對功能性和交互性的要求遠遠遠遠高于界面樣式。

            這就要求設計師必須對系統需求有所了解,包括業務流程、理解專業術語和每一步操作的目的,否則就是盲人摸象。

            不懂測試的設計師很難做出符合期望的界面設計。一般這類工具的設計師角色都是由測試或者開發本身承擔。缺點就是產出的界面稍遜美觀。不過根據我的經驗,人民群眾其實是不畏懼界面丑陋的,真正能使用的工具才能長久生存下來。

            和開發溝通

             關于工具交互,用戶有很多優秀的建議和想法,不過最終落實還是到開發頭上。可惜的是,好的交互一般開發起來都挺費事兒。大家知道,想把用戶體驗做到極 致,讓用戶輕松,開發就要“受罪”,要額外做很多在他們看來價值不大的細節工作。程序員有一個信念,這個世界上,沒有代碼實現不了的事情。如果他說無法實 現,一定是他不想。設計師對于開發工作所用到的知識有所涉獵,不用成為行家,但至少“略懂略懂”,最好有自己動手的能力,能預估開發投入。這樣,才能與開 發工程師建立平等對話,提出的需求和設計才不會被人一略而過。《越光寶盒》里面諸葛亮不是有句臺詞么,什么都懂一點,生活才能更多彩。

            說著容易,實際很難,很多事除非開發自己想明白,勸是沒用的。團隊里最好有個能一語定乾坤的權威人物,實在和開發溝通不了了,找他定奪。

            工具開發的過程中,在很多情況下,開發本身就是PD,會傾向于簡化項目,盡量少做、做自己熟悉的,使得項目順利完成,并且bug很少,做出來的也許體驗不好,但是絕對“夠用”。

            其實協同,是你去協同別人,而不是別人來協同你。主動一點,獲得更多。

          posted @ 2012-05-07 09:49 順其自然EVO 閱讀(206) | 評論 (0)編輯 收藏

          重載頁面后Web對象的重用

          測試中經常會出現在兩個頁面中的使用同一個對象,出現這樣的情況我們一定是使用同一個對象來處理,這樣才不會出現重復對象,就比如我們使用百度搜索,當我們打開百度時有一個搜索框,在輸入一些內容提交后,頁面會重載并且搜索框這個對象仍然存在,這個時候如果我們需要再次控制搜索框這個對象我們一定會想到直接使用之前對象庫里的那個搜索框對象,因為它們其實就是同一個對象。

          SystemUtil.Run "iexplore.exe"
           Set oBrowser = Browser("micClass:=Browser")
           Set oEdit = oBrowser.Page("micClass:=Page").WebEdit("name:=wd","index:=0")
           oBrowser.Navigate www.baidu.com
           
           With oEdit
           .Set "zzxxbb112"
           .Submit
           End With

           oEdit.Set http://blog.csdn.net/zzxxbb112

            我們可以看到在運行以上腳本后,QTP首先是輸入搜索內容然后提交,在提交的瞬間也就是頁面還有跳轉完成時就提前輸入了另一個值,而這并不是我們想要的效果,我們需要的是等頁面跳轉完成之后再輸入另一個搜索內容。解決這個問題的辦法是添加同步函數sync。

          SystemUtil.Run "iexplore.exe"
           Set oBrowser = Browser("micClass:=Browser")
           Set oEdit = oBrowser.Page("micClass:=Page").WebEdit("name:=wd","index:=0")
           oBrowser.Navigate www.baidu.com
           
          With oEdit
           .Set "zzxxbb112"
           .Submit
           End With

           oBrowser.Sync
           oEdit.Set http://blog.csdn.net/zzxxbb112

            在添加同步之后,QTP就會等待頁面緩沖完成之后,才對搜索框進行輸入操作,但是問題又來了,我們運行以上腳本后卻碰到了另一個問題。QTP無法對重載頁面后的搜索框對象進行操作,但其實他們是一個對象,腳本提示:oEdit參數不正確。

            這個問題的原因其實是因為當頁面同步完成時,測試對象還沒有被同步,因此導致我們無法對其進行操作,而報出了以上的錯誤。不過幸好QTP提供了一個方法可以解決此問題。

          SystemUtil.Run "iexplore.exe"
           Set oBrowser = Browser("micClass:=Browser")
           Set oEdit = oBrowser.Page("micClass:=Page").WebEdit("name:=wd","index:=0")
           oBrowser.Navigate www.baidu.com
           
          With oEdit
           .Set "zzxxbb112"
           .Submit
           End With

           oBrowser.Sync
           oEdit.init
           oEdit.Set http://blog.csdn.net/zzxxbb112

            執行以上腳本后成功做到了在WEB頁面加載后對象的復用。

            obj.init —- 此方法為QTP的隱藏方法,在幫助文檔中都沒有任何的介紹,用于重新同步頁面上的測試對象。我們可以通過使用VS2008改裝過的DEBUG引擎來查看此方法。

          posted @ 2012-05-07 09:47 順其自然EVO 閱讀(236) | 評論 (0)編輯 收藏

          自動化測試ROI實踐

            自動化測試是一項“一旦開始,就需要持續投入”的工作,所以它一直是測試領域的一塊雞肋。不做吧,好像手工測試重復得讓人有些厭倦,而且手工測試時間也縮短不了。做吧,害怕投入的比回報要多。

             沒實施自動化的團隊有各種各樣的困擾。有的說:“項目有太多的老代碼需要補充自動化測試腳本,補不起!”有的說:“項目開發太緊張,如果同時還要自動 化,等不起!”還有的說:“自動化測試工具太貴了!買不起!”確實,各種各樣的“傷不起”使得大量的組織在“要不要自動化”這個問題上總在了解和觀望,躊 躇不前。

            我們閱讀了一些關于自動化測試ROI的文章, 發現大多都是介紹各種不同的計算方法,但來自實際的數據分享比較少。所以,2011年當我們組織想推行自動化測試的時候,為了打消大家(尤其是管理層)對 于自動化測試的投入和產出方面的疑慮,計算我們自己的自動化測試投資回報率ROI(Return on Investment)成了我們啟動時就考慮的問題。本文將分為四部分介紹我們的實踐方法和結果。

            第一部分:業界計算自動化測試ROI的方法

            簡言之,ROI = 收益/投入。但收益如何計算,投入包括哪些,眾說紛紜,并沒有一個定論。

            在Dion Johnson的“test automation ROI”中給出了三種計算自動化測試ROI的方法。第一種方法“簡單ROI”著重從“錢”的方面去看。它考慮了工具、培訓、機器等各種費用,并把測試時間 的投入通過單位時間的工資轉化成為錢。第二種方法“效率ROI”與第一種方法不同的是從測試效率的角度,只考慮了時間投入所產生的收益,而沒有考慮其它如 購買工具方面的投入。這個方法比較適合測試人員計算收益。第三種方法“降低風險ROI”著重計算自動化測試與手工測試相比在降低風險方面的收益。它會假設 不做某種自動化測試,相關的風險一旦成為事實所帶來的損失,從而計算ROI。這個方法比較適合管理人員從整體考量自動化的收益。

            那么,目前我們的團隊期望自動化測試能帶來哪些收益,尤其是哪些收益是目前不能奢望的?我們的經理愿意提供多少資源投入自動化測試呢?帶著這些問題,我們開始了自己對自動化測試ROI的定義和度量。

            第二部分:我們計算自動化測試ROI的方法

            在度量自動化測試的收益方面,角度很多。我們選擇的是從“多、快、好、省”四個方面去看。

            更多

             鑒于我們處于自動化測試的初級階段,我們打算暫時先不去追求“更多”。即我們不奢望一年之內整個項目組在一個版本里做更多的工作,因為在自動化投入初期 難以提高團隊的生產力。我們也不奢望測試人員馬上能有更多時間去做更有價值的工作(相對于一次測試的多次重復執行)。因為測試人員通過自動化測試從測試執 行上節約出來的時間需要投入到自動化工具和技能的學習上去。

            更快

             在時間維度上,我們希望能夠更快地發現和修復穩定的主流程上的明顯的嚴重缺陷。如果一個測試人員手工測試多個功能,那么測試執行的并行度總有個上限。而 多個并行執行的自動化測試腳本可以更快速地驗證版本,一次性地報告問題。這尤其在測試初期版本不穩定,或者是每日構建的時候有用。有時,甚至是在我們不覺 得有測試必要的時候,自動化測試可以及時報告剛引入的問題。另一方面,更快地發現缺陷也意味著可能可以更快地修復缺陷。

            更好

            我們希望自動化測試可以幫助我們實現對“更好”的追求,包括質量、信心、士氣三個方面。

            1、更好的質量

             更好的質量最容易被理解成為更少的缺陷。但這里需要強調的是“更少的缺陷個數并不僅僅能依靠我們基于界面的自動化測試來達到”。我們這里希望自動化測試 能夠幫助我們減少生產環境中某種特定類型的缺陷。這些缺陷包括環境或者配置相關的缺陷、在主流程上本來正常但因為后期修改影響到的功能、以及容易被忽略的 地方(如:同一功能的多個入口、不常使用的功能)等。

            2、更強的質量信心

            在內部 測試中,我們希望借助自動化測試來提升的是對質量的信心。這主要體現在:(1)對于小版本和并行版本的質量更好地把關。小版本通常要求更快速的響應。并行 版本通常要求測試人員頻繁切換環境和被測對象。而人在壓力下也更容易犯錯。所以,我們常碰到的是匆忙中由于疏忽,一些比較重要或者明顯的問題沒有被及時發 現。(2)對缺陷修復的質量更好地把握。根據統計,大約7%的缺陷修復會產生新的缺陷,而這些新缺陷有時會出現在前面已經測試過并且不會再手工測試的地 方。對于如上兩種情況,重復利用自動化測試腳本可以不需要額外的投入,快速得到關于整個版本穩定性的信息和質量信心。

            3、更高的士氣

             對于測試團隊,我們希望自動化測試可以喚起更高的工作熱情。這一方面來自于可以部分地將測試人員從大量重復的測試執行中解放出來,另一方面來自于新技 術、新工具帶來的新鮮感。開發團隊和終端用戶會是自動化測試的間接受益者,因為開發團隊能感到問題會更快地暴露出來,終端用戶會感到應用程序更穩定了。甚 至在不遠的將來,如果測試時間可以借力自動化而縮短,那么用戶希望的功能也能更快地交付使用了。

          posted @ 2012-05-07 09:38 順其自然EVO 閱讀(455) | 評論 (0)編輯 收藏

          MySQL數據庫性能優化之索引優化

          大家都知道索引對于數據訪問的性能有非常關鍵的作用,都知道索引可以提高數據訪問效率。

            為什么索引能提高數據訪問性能?他會不會有“副作用”?是不是索引創建越多,性能就越好?到底該如何設計索引,才能最大限度的發揮其效能?

            這篇文章主要是帶著上面這幾個問題來做一個簡要的分析,同時排除了業務場景所帶來的特殊性,請不要糾結業務場景的影響。

            這是 MySQL數據庫性能優化專題 系列的第三篇文章:MySQL 數據庫性能優化之索引優化

            系列的第二篇文章:MySQL 數據庫性能優化之表結構優化

            系列的第一篇文章:MySQL 數據庫性能優化之緩存參數優化

            索引為什么能提高數據訪問性能?

            很多人只知道索引能夠提高數據庫的性能,但并不是特別了解其原理,其實我們可以用一個生活中的示例來理解。

             我們讓一位不太懂計算機的朋友去圖書館確認一本叫做《MySQL性能調優與架構設計》的書是否在藏,這樣對他說:“請幫我借一本計算機類的數據庫書籍, 是屬于 MySQL 數據庫范疇的,叫做《MySQL性能調優與架構設計》”。朋友會根據所屬類別,前往存放“計算機”書籍區域的書架,然后再尋找“數據庫”類存放位置,再找 到一堆講述“MySQL”的書籍,最后可能發現目標在藏(也可能已經借出不在書架上)。

            在這個過程中: “計算機”->“數據庫”->“MySQL”->“在藏”->《MySQL性能調優與架構設計》其實就是一個“根據索引查找數 據”的典型案例,“計算機”->“數據庫”->“MySQL”->“在藏” 就是朋友查找書籍的索引。

            假設沒有這個 索引,那查找這本書的過程會變成怎樣呢?朋友只能從圖書館入口一個書架一個書架的“遍歷”,直到找到《MySQL性能調優與架構設計》這本書為止。如果幸 運,可能在第一個書架就找到。但如果不幸呢,那就慘了,可能要將整個圖書館所有的書架都找一遍才能找到我們想要的這本書。

            注:這個例子 中的“索引”是記錄在朋友大腦中的,實際上,每個圖書館都會有一個非常全的實際存在的索引系統(大多位于入口顯眼處),由很多個貼上了明顯標簽的小抽屜構 成。這個索引系統中存放這非常齊全詳盡的索引數據,標識出我們需要查找的“目標”在某個區域的某個書架上。而且每當有新的書籍入庫,舊的書籍銷毀以及書記 信息修改,都需要對索引系統進行及時的修正。

            下面我們通過上面這個生活中的小示例,來分析一下索引,看看能的出哪些結論?

            索引有哪些“副作用”?

            圖書的變更(增,刪,改)都需要修訂索引,索引存在額外的維護成本

            查找翻閱索引系統需要消耗時間,索引存在額外的訪問成本

            這個索引系統需要一個地方來存放,索引存在額外的空間成本

            索引是不是越多越好?

            如果我們的這個圖書館只是一個進出中轉站,里面的新書進來后很快就會轉發去其他圖書館而從這個館藏中“清除”,那我們的索引就只會不斷的修改,而很少會被用來查找圖書

            所以,對于類似于這樣的存在非常大更新量的數據,索引的維護成本會非常高,如果其檢索需求很少,而且對檢索效率并沒有非常高的要求的時候,我們并不建議創建索引,或者是盡量減少索引。

           如果我們的書籍量少到只有幾本或者就只有一個書架,索引并不會帶來什么作用,甚至可能還會浪費一些查找索引所花費的時間。

            所以,對于數據量極小到通過索引檢索還不如直接遍歷來得快的數據,也并不適合使用索引。

            如果我們的圖書館只有一個10平方的面積,現在連放書架都已經非常擁擠,而且館藏還在不斷增加,我們還能考慮創建索引嗎?

            所以,當我們連存儲基礎數據的空間都捉襟見肘的時候,我們也應該盡量減少低效或者是去除索引。

            索引該如何設計才高效?

            如果我們僅僅只是這樣告訴對方的:“幫我確認一本數據庫類別的講述 MySQL 的叫做《MySQL性能調優與架構設計》的書是否在藏”,結果又會如何呢?朋友只能一個大類區域一個大類區域的去尋找“數據庫”類別,然后再找到 “MySQL”范疇,再看到我們所需是否在藏。由于我們少說了一個“計算機類”,朋友就必須到每一個大類去尋找。

            所以,我們應該盡量讓查找條件盡可能多的在索引中,盡可能通過索引完成所有過濾,回表只是取出額外的數據字段。

            如果我們是這樣說的:“幫我確認一本講述 MySQL 的數據庫范疇的計算機叢書,叫做《MySQL性能調優與架構設計》,看是否在藏”。如果這位朋友并不知道計算機是一個大類,也不知道數據庫屬于計算機大 類,那這位朋友就悲劇了。首先他得遍歷每個類別確認“MySQL”存在于哪些類別中,然后從包含 “MySQL” 書籍中再看有哪些是“數據庫”范疇的(有可能部分是講述PHP或者其他開發語言的),然后再排除非計算機類的(雖然可能并沒有必要),然后才能確認。

            所以,字段的順序對組合索引效率有至關重要的作用,過濾效果越好的字段需要更靠前。

            如果我們還有這樣一個需求(雖然基本不可能):“幫我將圖書館中所有的計算機圖書借來”。朋友如果通過索引來找,每次都到索引柜找到計算機書籍 所在的區域,然后從書架上搬下一格(假設只能以一格為單位從書架上取下,類比數據庫中以block/page為單位讀取),取出第一本,然后再從索引柜找 到計算機圖書所在區域,再搬下一格,取出一本… 如此往復直至取完所有的書。如果他不通過索引來找又會怎樣呢?他需要從地一個書架一直往后找,當找到計算機的書,搬下一格,取出所有計算機的書,再往后, 直至所有書架全部看一遍。在這個過程中,如果計算機類書籍較多,通過索引來取所花費的時間很可能要大于直接遍歷,因為不斷往復的索引翻閱所消耗的時間會非 常長。(延伸閱讀:這里有一篇以前寫的關于Oracle的文章,索引掃描還是全表掃描(Index Scan Or Full Table Scan))

            所以,當我們需要讀取的數據量占整個數據量的比例較大抑或者說索引的過濾效果并不是太好的時候,使用索引并不一定優于全表掃描。

            如果我們的朋友不知道“數據庫”這個類別可以屬于“計算機”這個大類,抑或者圖書館的索引系統中這兩個類別屬性并沒有關聯關系,又會怎樣呢?也 就是說,朋友得到的是2個獨立的索引,一個是告知“計算機”這個大類所在的區域,一個是“數據庫”這個小類所在的區域(很可能是多個區域),那么他只能二 者選其一來搜索我的需求。即使朋友可以分別通過2個索引檢索然后自己在腦中取交集再找,那這樣的效率實際過程中也會比較低下。

            所以,在實際使用過程中,一次數據訪問一般只能利用到1個索引,這一點在索引創建過程中一定要注意,不是說一條SQL語句中Where子句里面每個條件都有索引能對應上就可以了。

            看完這些分析,我想大家應該了解索引優化的一些基本思路了吧。

          posted @ 2012-05-07 09:27 順其自然EVO 閱讀(167) | 評論 (0)編輯 收藏

          Java集合框架總結:TreeSet類的排序問題

               摘要: 程序運行結果:true [TreeSet.Z@1fb8ee3, TreeSet.Z@1fb8ee3] 9  說明:  程序中把同一個對象添加了兩次,因為z1對象的equals()方法總是返回false,而且compareTo(Object obj)方法總是返回1。這樣TreeSet會認為z1對象和它自己也不相同,因此TreeSet中添加兩個z1對象。而TreeSet對象保存的兩...  閱讀全文

          posted @ 2012-05-04 11:51 順其自然EVO 閱讀(311) | 評論 (0)編輯 收藏

          常用數據結構:線性結構

            數據結構是計算機存儲、組織數據的方式。常見的數據結構分類方式如下圖:

            常用的線性結構有:線性表,棧,隊列,循環隊列,數組。線性表中包括順序表、鏈表等,其中,棧和隊列只是屬于邏輯上的概念,實際中不存在,僅僅是一種思想,一種理念;線性表則是在內存中數據的一種組織、存儲的方式。

            順序表

            順序表將元素一個接一個的存入一組連續的存儲單元中,在內存物理上是連續的。如下圖:

            順序表存儲密度較大,節省空間;但需要事先確定容量,在時間性能方面,讀運算較快,時間復雜度為O(1);查找運算為O(n/2),和鏈表同樣;插入運算和刪除運算如果要操作中間一個元素,比如3,那么就需要把3后面的元素全部進行移動,因此時間復雜度相對鏈表要大一些,插入時間復雜度最好為O(0)或最壞為O(n);刪除時間復雜度為O([n-1]/2);

            鏈表

            鏈表擁有很多結點,每個結點前半部分是數據域,后半部分是指針域,指針域指針指向下一個結點;鏈表可分為單鏈表、循環鏈表和雙鏈表。

            單鏈表:

            從上圖可以看出,單鏈表的上一個結點指針指向下一個結點,最后一個結點的指針域為null。

            結點的刪除:

            刪除一個結點,如刪除上圖中q結點,只需將p結點中的指針域指向a3,然后將a2釋放掉(free)即可。

            結點的插入:

            插入一個結點,如插入上圖中s結點,首先將s的指針域指向a2(也就是把s的next賦值為p的next),然后將p結點的指針域指向x即可(p的next指向x)。

          循環鏈表

            循環鏈表與單鏈表唯一不同之處是,循環鏈表的最后一個結點指針不為空,而是指向頭結點。結點的插入和刪除和單鏈表非常相似,就不再示范了。

            雙鏈表

            雙鏈表擁有一前一后兩個指針域,從兩個不同的方向把鏈表連接起來,如此一來,從兩個不同的方向形成了兩條鏈,因此成為雙鏈表。因此,雙鏈表的靈活度要大于單鏈表。

            結點的刪除:

            雙鏈表的操作比單鏈表要稍顯復雜(按照單鏈表思路來做其實也不難),如上圖,要刪除p節點,首先需要將a1的后驅指向a3,然后將a3的前驅指向a1,最后將p節點釋放掉即可。

            結點的插入:

            如上圖,插入q結點,首先要按照方向,將步驟拆分,首先將q節點的前驅指向p結點后驅,緊接著將x后驅指向a2;然后按照順序完成圖中所示的3、4步即可。

            從空間性能來看,鏈表的存儲密度要差一些,但在容量分配上更靈活一些。從時間性能來看,查找運算與順序存儲相同,插入運算和刪除運算的時間復雜度為O(1),要更優于順序存儲,但讀運算則弱一些,為O([n+1]/2),最好為1,最壞為n。

            棧

            上面提到棧屬于一個邏輯概念,棧的實現可以用順序也可以用鏈式。它遵循先進后出原則,如下圖:

            Java中測試代碼如下:

          1. package com.snail.test;  
          2.  
          3. import java.util.Stack;  
          4.  
          5. public class TestStack {  
          6.  
          7.     public static void main(String[] args) {  
          8.           
          9.         Stack<String> stack = new Stack<String>();  
          10.         stack.push("NO1");  
          11.         stack.push("NO2");  
          12.         stack.push("NO3");  
          13.           
          14.         System.out.println("初始數量:" + stack.size());  
          15.  
          16.         while(!stack.isEmpty()){  
          17.             System.out.println(stack.pop());  
          18.         }     
          19.           
          20.         System.out.println("取完后的數量:" + stack.size());  
          21.     }  
          22. }



            隊列

            隊列遵循先進先出的原則,如下圖:

            Java中測試代碼如下:

          1. package com.snail.test;  
          2.  
          3. /**  
          4.  *  
          5.  * @author Zang XT  
          6.  */ 
          7. import java.util.Queue;  
          8. import java.util.LinkedList;  
          9. public class TestQueue {  
          10.     public static void main(String[] args) {  
          11.         Queue<String> queue = new LinkedList<String>();  
          12.           
          13.         queue.offer("NO1");  
          14.         queue.offer("NO2");  
          15.         queue.offer("NO3");  
          16.           
          17.         System.out.println("初始數量" + queue.size());  
          18.         String str;  
          19.         while((str=queue.poll())!=null){  
          20.             System.out.println(str);  
          21.         }  
          22.         System.out.println("取出后數量" + queue.size());  
          23.     }  
          24. }

            運行結果順序為:初始數量3,NO1,NO2,NO3,取出后數量0。

            隊列還有一種形式為循環隊列,如下圖:

            循環隊列有兩個指針,頭指針head和尾指針tail,尾指針一般指向的不是隊尾元素實際地址,而是指向實際地址的下一個空地址,因此,循環隊列一般犧牲最后一個空間,用來計算該隊列是否滿了,判斷方式是tail+1 = head,既該隊列已滿。

            為了盡可能的說清楚,插了大量圖片,希望理解。以后有時間將繼續分析樹、圖等數據結構。

          posted @ 2012-05-04 11:49 順其自然EVO 閱讀(253) | 評論 (0)編輯 收藏

          軟件測試團隊學習的三種形式

           團隊學習不但可以促進個人成長,還有利于提高團隊的核心競爭力。因此,團隊學習在構建學習型組織的過程中是非常重要的一個方面。牛根生曾提出:必須堅持團隊學習,學相同才能思相近(共識),思相近才能言相和(共鳴),言相和才能行相輔(共振)。我們測試團隊在近5年內每年都在組織大家進行團隊學習。本文將介紹我們經歷的三種不同的組織形式。

            一、興趣小組

            愛因斯坦說過“興趣是最好的老師。”在原本就繁重的工作之外,喚起學習欲望的最佳切入點可能就是興趣了。但團隊學習必須找到大家共同的興趣。所以,我們先每個人列舉出幾個自己感興趣的關鍵字,然后看看它們交叉最集中的地方,從中再討論并選取兩到三個作為本年團隊學習的方向。定好主題后,每個人選擇參加其中的一到兩個小組,并自由推舉一個小組協調員,分頭開展學習,定期交流。

            興趣很重要,但有趣的是,實踐下來我們發現很多人并不是真正有興趣,或者準確地說是沒有意識到自己并不是真正有興趣。讓我們一起來看看你認為你感興趣的東西是否經得起以下兩個問題的檢驗。

            問題一:你愿意投入么?我所指的投入是真金白銀哦!它包括你的金錢、時間和精力。如果要占用你的一些業余時間,你樂意么?如果要你自己花些錢參加一次活動,你愿意么?別在那想著心儀的姑娘,說你感興趣,卻連一頓飯都舍不得和她吃。別在那看著財經節目熱血沸騰,說你想理財,卻連一個投資都不做。

            問題二:你能堅持多久?即使你愿意付出,但時光荏苒,環境變遷,當別人質疑你的選擇,重重的困難阻礙你的追求,你的付出并沒有期盼的回報,你還能夠堅持多久?興趣如果不伴隨著承諾,將難以持久。

            當然,在興趣小組里,即使你剛開始并沒有太大的興趣,也不見得加入興趣小組就是一件沒有意義的事情。比如,存在一種可能:你覺得自己找不到能象你想象中那么感興趣的東西而感到懊惱和茫然。就象我們曾經熱血澎湃地說要學習行業知識,但收集了一些專業名詞后就無疾而終。我們也曾經組織過對同一行業領域軟件的學習,但最終因為配置過于復雜而擱淺。其實我很理解工作相關的興趣并不那么容易讓你愿意投入,因為比起購物或者宅在家里這樣的興趣愛好,對工作技能或者知識的興趣在開始的階段,更多的時候意味著付出、困惑、挫敗。其實,感到懊惱和茫然并不可怕。相反,我覺得這是重新思考自己真正感興趣的新開始。也許你會感到自己需要一個更小的關注點,也許你會意識到自己的學習還需要和實踐多一些結合。這些否定過去的經歷會帶領你下一步走向一個更明確的方向,正如我們也是這樣一路摸索著走來。還存在另外一種可能:置身同一個興趣小組中,你的身邊有幾位特別執著于此的同事。他們的熱情感染了你;他們的見解啟發了你;和他們在一起,你擁有獨自學習無法獲取的資源。所以我感到,最差的情況,通過加入興趣小組至少可以幫助你了解自己是否真的對某件事情有興趣。比較好的情況,你的興趣能在一群志趣相投的人的帶動下中得到更多的培養和發揮。

            二、學習小組

            學習小組和興趣小組大同小異。我理解的不同之處在于:學習小組的學習內容可能是大家并不了解和感興趣,但有學習的必要的。比如,一個新的技術(如云計算)或者軟件開發模式(如敏捷開發)。

            當大家沉浸學習的熱情中,因為眾多的資料和分享而感到充實欣喜時,我不禁要擔憂:有多少知識真的能改變我們的思維模式?有多少的技能能運用到我們的工作中去?幾年前,我們曾經組織過對經典書籍的集體學習,但最終發現由于難以和工作相結合,不到半年那些知識也大都淡忘了。

            為了團隊學習能取得更好的實際效果,如果說興趣小組更多的是靠個人的熱情和持續投入,學習小組更多的是靠基層管理人員的引導。因為高層肯定強烈反對光學不練,弄不好可能在一定程度上打擊了大家學的熱情;而個人大多根據喜好進行學習,追求個人發展,不大容易把個人需要和公司的需要聯系起來。對于那些分享就是結束的學習活動,基層管理人員應該盡量控制其比例,并引導團隊了解:學習的氣氛很重要,但對于職場人士,學習只是手段,幫助公司和客戶實現價值才是目標。

            三、實踐社區(Community of Practice)

            何為“實踐社區”?簡而言之,就是一群有類似職業/技能/興趣的人非正式地聚集在一起形成的交流實踐經驗的虛擬社區。

            與興趣小組和學習小組不同的是,實踐社區更注重實戰,因而其對人的影響也從認知層面到了操作層面。由于軟件開發的唯一性、獨特性,即使是別人總結的最佳實踐,也是建立在特定的前提基礎上。所謂“紙上得來終覺淺,覺知此事要躬行”。比如,大家都在進行團隊學習,為什么他們會采用這樣的方法?為什么我們采用了類似的方法效果卻相差甚遠?為什么我們的最佳實踐在別的地方卻行不通?了解了背后的原因后,就可以更客觀和全面地比較多個做法,從而摸索出特定情況下的最佳實踐。

            我們對于實踐社區的做法是細分測試的流程,定義其主要輸出物。然后每個項目都在這些共同的環節提供各自的實際樣本。在有差異之處進行充分討論,最終形成大家的共識,流程整理為指導文檔,輸出物整理為模板,都設立基線。以后大家共同工作以此為基礎,并定期回顧和修改。我們追求的并不是統一,而是不統一處有一個可以接受的理由。我們追求的也不是規范,而是特定情況下最適用的方法。除了已有實踐的分享,我們也少量吸納了一些外部的最佳實踐,在個別項目中先試行,然后從實踐社區中推動到更多的項目中去。比如缺陷正交分析法、測試覆蓋率度量和持續集成等。另外,我們還在考慮借鑒開發團隊的代碼道場,組織一些測試執行道場。我們感到與其它兩種團隊學習方法相比較,實踐社區最容易在組織級別產生實際效果,因而也更容易得到項目和管理團隊的支持。

            無論你的團隊采取哪種學習組織形式,熱情、承諾、務實是我們實踐過程中總結下來的三個要素。無論你走到哪里,找到屬于你的圈子,和大家一起學習和成長吧!

          posted @ 2012-05-04 10:16 順其自然EVO 閱讀(240) | 評論 (0)編輯 收藏

          MySQL數據庫性能優化之表結構優化

            很多人都將<數據庫設計范式>作為數據庫表結構設計“圣經”,認為只要按照這個范式需求設計,就能讓設計出來的表結構足夠優化,既能保證性能優異同時還能滿足擴展性要求。殊不知,在N年前被奉為“圣經”的數據庫設計3范式早就已經不完全適用了。這里我整理了一些比較常見的數據庫表結構設計方面的優化技巧,希望對大家有用。

            這是MySQL數據庫性能優化專題系列的第二篇文章:MySQL 數據庫性能優化之表結構優化

            系列的第一篇文章:MySQL 數據庫性能優化之緩存參數優化

            由于MySQL數據庫是基于行(Row)存儲的數據庫,而數據庫操作 IO 的時候是以 page(block)的方式,也就是說,如果我們每條記錄所占用的空間量減小,就會使每個page中可存放的數據行數增大,那么每次 IO 可訪問的行數也就增多了。反過來說,處理相同行數的數據,需要訪問的 page 就會減少,也就是 IO 操作次數降低,直接提升性能。此外,由于我們的內存是有限的,增加每個page中存放的數據行數,就等于增加每個內存塊的緩存數據量,同時還會提升內存換中數據命中的幾率,也就是緩存命中率。

            數據類型選擇

            數據庫操作中最為耗時的操作就是 IO 處理,大部分數據庫操作 90% 以上的時間都花在了 IO 讀寫上面。所以盡可能減少 IO 讀寫量,可以在很大程度上提高數據庫操作的性能。

            我們無法改變數據庫中需要存儲的數據,但是我們可以在這些數據的存儲方式方面花一些心思。下面的這些關于字段類型的優化建議主要適用于記錄條數較多,數據量較大的場景,因為精細化的數據類型設置可能帶來維護成本的提高,過度優化也可能會帶來其他的問題:

            1、數字類型:非萬不得已不要使用DOUBLE,不僅僅只是存儲長度的問題,同時還會存在精確性的問題。同樣,固定精度的小數,也不建議使用DECIMAL,建議乘以固定倍數轉換成整數存儲,可以大大節省存儲空間,且不會帶來任何附加維護成本。對于整數的存儲,在數據量較大的情況下,建議區分開 TINYINT / INT / BIGINT 的選擇,因為三者所占用的存儲空間也有很大的差別,能確定不會使用負數的字段,建議添加unsigned定義。當然,如果數據量較小的數據庫,也可以不用嚴格區分三個整數類型。

            2、字符類型:非萬不得已不要使用 TEXT 數據類型,其處理方式決定了他的性能要低于char或者是varchar類型的處理。定長字段,建議使用 CHAR 類型,不定長字段盡量使用 VARCHAR,且僅僅設定適當的最大長度,而不是非常隨意的給一個很大的最大長度限定,因為不同的長度范圍,MySQL也會有不一樣的存儲處理。

            3、時間類型:盡量使用TIMESTAMP類型,因為其存儲空間只需要 DATETIME 類型的一半。對于只需要精確到某一天的數據類型,建議使用DATE類型,因為他的存儲空間只需要3個字節,比TIMESTAMP還少。不建議通過INT類型類存儲一個unix timestamp 的值,因為這太不直觀,會給維護帶來不必要的麻煩,同時還不會帶來任何好處。

            4、ENUM & SET:對于狀態字段,可以嘗試使用 ENUM 來存放,因為可以極大的降低存儲空間,而且即使需要增加新的類型,只要增加于末尾,修改結構也不需要重建表數據。如果是存放可預先定義的屬性數據呢?可以嘗試使用SET類型,即使存在多種屬性,同樣可以游刃有余,同時還可以節省不小的存儲空間。

            5、LOB類型:強烈反對在數據庫中存放 LOB 類型數據,雖然數據庫提供了這樣的功能,但這不是他所擅長的,我們更應該讓合適的工具做他擅長的事情,才能將其發揮到極致。在數據庫中存儲 LOB 數據就像讓一個多年前在學校學過一點Java的營銷專業人員來寫 Java 代碼一樣。

            字符編碼

            字符集直接決定了數據在MySQL中的存儲編碼方式,由于同樣的內容使用不同字符集表示所占用的空間大小會有較大的差異,所以通過使用合適的字符集,可以幫助我們盡可能減少數據量,進而減少IO操作次數。

            1、純拉丁字符能表示的內容,沒必要選擇 latin1 之外的其他字符編碼,因為這會節省大量的存儲空間。

            2、如果我們可以確定不需要存放多種語言,就沒必要非得使用UTF8或者其他UNICODE字符類型,這回造成大量的存儲空間浪費。

            3、MySQL的數據類型可以精確到字段,所以當我們需要大型數據庫中存放多字節數據的時候,可以通過對不同表不同字段使用不同的數據類型來較大程度減小數據存儲量,進而降低 IO 操作次數并提高緩存命中率。

            適當拆分

            有些時候,我們可能會希望將一個完整的對象對應于一張數據庫表,這對于應用程序開發來說是很有好的,但是有些時候可能會在性能上帶來較大的問題。

            當我們的表中存在類似于 TEXT 或者是很大的 VARCHAR類型的大字段的時候,如果我們大部分訪問這張表的時候都不需要這個字段,我們就該義無反顧的將其拆分到另外的獨立表中,以減少常用數據所占用的存儲空間。這樣做的一個明顯好處就是每個數據塊中可以存儲的數據條數可以大大增加,既減少物理 IO 次數,也能大大提高內存中的緩存命中率。

            上面幾點的優化都是為了減少每條記錄的存儲空間大小,讓每個數據庫中能夠存儲更多的記錄條數,以達到減少 IO 操作次數,提高緩存命中率。下面這個優化建議可能很多開發人員都會覺得不太理解,因為這是典型的反范式設計,而且也和上面的幾點優化建議的目標相違背。

            適度冗余

            為什么我們要冗余?這不是增加了每條數據的大小,減少了每個數據塊可存放記錄條數嗎?

            確實,這樣做是會增大每條記錄的大小,降低每條記錄中可存放數據的條數,但是在有些場景下我們仍然還是不得不這樣做:

            1、被頻繁引用且只能通過 Join 2張(或者更多)大表的方式才能得到的獨立小字段。

            2、這樣的場景由于每次Join僅僅只是為了取得某個小字段的值,Join到的記錄又大,會造成大量不必要的 IO,完全可以通過空間換取時間的方式來優化。不過,冗余的同時需要確保數據的一致性不會遭到破壞,確保更新的同時冗余字段也被更新。

            盡量使用 NOT NULL

            NULL 類型比較特殊,SQL 難優化。雖然 MySQL NULL類型和 Oracle 的NULL 有差異,會進入索引中,但如果是一個組合索引,那么這個NULL 類型的字段會極大影響整個索引的效率。此外,NULL 在索引中的處理也是特殊的,也會占用額外的存放空間。

            很多人覺得 NULL 會節省一些空間,所以盡量讓NULL來達到節省IO的目的,但是大部分時候這會適得其反,雖然空間上可能確實有一定節省,倒是帶來了很多其他的優化問題,不但沒有將IO量省下來,反而加大了SQL的IO量。所以盡量確保 DEFAULT 值不是 NULL,也是一個很好的表結構設計優化習慣。

          posted @ 2012-05-04 10:11 順其自然EVO 閱讀(153) | 評論 (0)編輯 收藏

          WP刷機

          http://www.wpkong.com/thread-8247-1-1.html

          posted @ 2012-05-04 10:08 順其自然EVO 閱讀(172) | 評論 (0)編輯 收藏

          軟件測試缺陷處理注意事項

            一、針對nobug的缺陷

            1、產品經理針對產品建議類的缺陷若本版本暫時不修改,可以將bug進行nobug處理,但需要讓其將缺陷提交到jira作為產品建議記錄,并且在缺陷備注說明jira id。同時測試人員將缺陷的summary前加上【jira建議】以便測試分析時篩選。

            2、針對系統集成類的缺陷,所謂系統集成類的缺陷是本項目無法修改,需要其他項目才能修改的缺陷。這類缺陷產品經理可以將缺陷nobug處理。測試人員需將缺陷的summary前加上【系統集成】以便測試分析時的篩選,同時測試人員還需將缺陷拷貝一份到相應項目的TD-單元集成測試中,并發送郵件通知相應項目的項目經理、產品經理并跟進缺陷處理情況。

            3、針對無法重現的缺陷,若確實無法找到規律并解決,產品經理可以nobug處理;但測試人員仍需進行進行缺陷驗證,若重現此缺陷將缺陷open起來并修改相應的缺陷描述;若下一循環驗證確實沒有重現,在缺陷的summary前加上【無法重現】一遍測試分析時篩選。

            4、針對描述不同但可能產生原因是同一個缺陷,開發人員解決缺陷若判定為重復缺陷將缺陷nobug,測試人員驗證nobug缺陷時若該缺陷仍然存在則將該缺陷進行reopen操作,并說明reopen原因。

            5、針對修改需求的缺陷,產品經理、開發人員若有進行修改需求則不能讓其將缺陷nobug處理;需要修改用需、軟需后將缺陷fixed處理。若開發人員將此類缺陷nobug,測試人員可以將缺陷open起來重新修改。

            二、針對reopen的缺陷

            1、上一循環發現功能未實現的缺陷,在這一循環已實現但實現的功能存在某一功能錯誤,此時測試人員可以將上一循環的缺陷closed,并重新提交一個新缺陷,無需進行reopen操作。

            2、測試人員reopen缺陷時需在comments說明這個缺陷reopen的原因再進行操作reopen。

            3、原則上我們提出的缺陷沒有修改而開發人員將缺陷fixed處理了,我們驗證缺陷時均采用reopen操作。但測試負責人可以自己把握這個度,可以視項目情況、開發人員等情況適當放松,比如一些很小的缺陷,比如提示信息修改不完全,或者一些很小的需求問題修改不完全,可以跟缺陷解決人說明并讓其修改,將缺陷closed處理。

            4、驗證缺陷時因為其他缺陷的影響導致此缺陷無法驗證,此時仍判定為缺陷無修改將缺陷reopen處理。

            三、針對deffred的缺陷

            原則上這些缺陷我們可以不用進行處理,但部分項目存在產品經理忘記將deffred的比較嚴重或影響項目結項的缺陷open起來處理,導致項目最后一個循環才來著急的處理這些缺陷。測試負責人可以在每個循環測試前關注deffred的缺陷,若判定這些缺陷較為影響產品質量需提醒產品經理或項目經理及時對這些缺陷進行處理。

            當然,各個項目仍存在一些特殊的情況可能會需要特殊處理的,以下幾個問題請各測試人員務必答復(尤其是測試負責人);

            1、測試過程中還遇到哪些處理缺陷時不知如何操作或糾結的情況,可舉例說明?

            2、針對以上處理缺陷的流程和方法有何意見或建議?

            3、針對缺陷處理的流程有何補充,或者在你所接觸的項目還有其他處理缺陷的流程嗎?

          posted @ 2012-05-03 10:06 順其自然EVO 閱讀(388) | 評論 (0)編輯 收藏

          僅列出標題
          共394頁: First 上一頁 330 331 332 333 334 335 336 337 338 下一頁 Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 兴海县| 阿尔山市| 定陶县| 融水| 庆城县| 乌鲁木齐县| 合江县| 安义县| 五台县| 仙游县| 蒲城县| 精河县| 虞城县| 罗山县| 石渠县| 乌兰县| 社会| 浦江县| 洮南市| 东山县| 兰溪市| 清新县| 武定县| 朔州市| 张家口市| 康保县| 根河市| 泽普县| 德昌县| 万山特区| 浦县| 南宁市| 娄烦县| 罗江县| 龙胜| 宁海县| 博罗县| 辽中县| 涞水县| 焦作市| 巫溪县|