qileilove

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

          Java和.NET使用DES對稱加密的區(qū)別

           Java和.NET的系統(tǒng)類庫里都有封裝DES對稱加密的實現(xiàn)方式,但是對外暴露的接口卻各不相同,甚至有時會讓自己難以解決其中的問題,比如Java加密后的結果在.NET中解密不出來等,由于最近項目有跨Java和.NET的加解密,經過我的分析調試,終于讓它們可以互相加密解密了。

            DES加密

            DES是一種對稱加密(Data Encryption Standard)算法,以前我寫過一篇文章:.NET中加密解密相關知識,有過簡單描述。

            DES算法一般有兩個關鍵點,第一個是加密算法,第二個是數(shù)據(jù)補位。

            加密算法常見的有ECB模式和CBC模式:

            ECB模式:電子密本方式,這是JAVA封裝的DES算法的默認模式,就是將數(shù)據(jù)按照8個字節(jié)一段進行DES加密或解密得到一段8個字節(jié)的密文或者明文,最后一段不足8個字節(jié),則補足8個字節(jié)(注意:這里就涉及到數(shù)據(jù)補位了)進行計算,之后按照順序將計算所得的數(shù)據(jù)連在一起即可,各段數(shù)據(jù)之間互不影響。

            CBC模式:密文分組鏈接方式,這是.NET封裝的DES算法的默認模式,它比較麻煩,加密步驟如下:

            1、首先將數(shù)據(jù)按照8個字節(jié)一組進行分組得到D1D2......Dn(若數(shù)據(jù)不是8的整數(shù)倍,就涉及到數(shù)據(jù)補位了)

            2、第一組數(shù)據(jù)D1與向量I異或后的結果進行DES加密得到第一組密文C1(注意:這里有向量I的說法,ECB模式下沒有使用向量I)

            3、第二組數(shù)據(jù)D2與第一組的加密結果C1異或以后的結果進行DES加密,得到第二組密文C2

            4、之后的數(shù)據(jù)以此類推,得到Cn

            5、按順序連為C1C2C3......Cn即為加密結果。

            數(shù)據(jù)補位一般有NoPadding和PKCS7Padding(JAVA中是PKCS5Padding)填充方式,PKCS7Padding和PKCS5Padding實際只是協(xié)議不一樣,根據(jù)相關資料說明:PKCS5Padding明確定義了加密塊是8字節(jié),PKCS7Padding加密快可以是1-255之間。但是封裝的DES算法默認都是8字節(jié),所以可以認為他們一樣。數(shù)據(jù)補位實際是在數(shù)據(jù)不滿8字節(jié)的倍數(shù),才補充到8字節(jié)的倍數(shù)的填充過程。

            NoPadding填充方式:算法本身不填充,比如.NET的padding提供了有None,Zeros方式,分別為不填充和填充0的方式。

            PKCS7Padding(PKCS5Padding)填充方式:為.NET和JAVA的默認填充方式,對加密數(shù)據(jù)字節(jié)長度對8取余為r,如r大于0,則補8-r個字節(jié),字節(jié)為8-r的值;如果r等于0,則補8個字節(jié)8。比如:

            加密字符串為為AAA,則補位為AAA55555;加密字符串為BBBBBB,則補位為BBBBBB22;加密字符串為CCCCCCCC,則補位為CCCCCCCC88888888。

            .NET中的DES加密

            對于.NET,框架在System.Security.Cryptography命名空間下提供了DESCryptoServiceProvider作為System.Security.Cryptography.DES加密解密的包裝接口,它提供了如下的4個方法:

          1. public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)  
          2. public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)  
          3. public override void GenerateIV()  
          4. public override void GenerateKey()

            從.NET類庫封裝情況,加解密需要傳入一個Key和IV向量。而且Key必須為8字節(jié)的數(shù)據(jù),否則會直接拋異常出來,當使用ECB模式下,不管傳入什么IV向量,加密結果都一樣。示例代碼如下:

          1. public static string EncryptWithJava(string key, string str)  
          2. {  
          3.     if (key.Length < 8 || string.IsNullOrEmpty(str))  
          4.     {  
          5.         throw new Exception("加密key小于8或者加密字符串為空!");  
          6.     }  
          7.     byte[] bKey = Encoding.UTF8.GetBytes(key.Substring(08));  
          8.     byte[] bIV = IV;  
          9.     byte[] bStr = Encoding.UTF8.GetBytes(str);  
          10.     try 
          11.     {  
          12.         DESCryptoServiceProvider desc = new DESCryptoServiceProvider();  
          13.         desc.Padding = PaddingMode.PKCS7;//補位 
          14.         desc.Mode = CipherMode.ECB;//CipherMode.CBC 
          15.         using (MemoryStream mStream = new MemoryStream())  
          16.         {  
          17.             using (CryptoStream cStream = new CryptoStream(mStream, desc.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write))  
          18.             {  
          19.                 cStream.Write(bStr, 0, bStr.Length);  
          20.                 cStream.FlushFinalBlock();  
          21.                 StringBuilder ret = new StringBuilder();  
          22.                 byte[] res = mStream.ToArray();  
          23.                 foreach (byte b in res)  
          24.                 {  
          25.                     ret.AppendFormat("{0:x2}", b);  
          26.                 }  
          27.                 return ret.ToString();  
          28.             }  
          29.         }  
          30.     }  
          31.     catch 
          32.     {  
          33.         return string.Empty;  
          34.     }  
          35. }




           由于為ECB模式,因此IV這里設置什么值都是可以的,當為CBC模式下,則需要設置為其他值,比如:public static byte[] IV = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },才能正常加密解密。

            JAVA中的DES加密

            JAVA的javax.crypto.Cipher包下,提供了加密解密的功能,它的靜態(tài)getInstance方法,可以返回一個Cipher對象,一般有public static final Cipher getInstance(String transformation)方法,transformation為:algorithm/mode/padding,分別表示算法名稱,比如DES,也可以在后面包含算法模式和填充方式,但也可以只是算法名稱,如為:"DES/CBC/PKCS5Padding","DES"等。JAVA中默認的算法為ECB,默認填充方式為PKCS5Padding。Cipher的Init方法用來初始化加密對象,常見的有:

          1. public final void init(int opmode, Key key, AlgorithmParameterSpec params)  
          2. public final void init(int opmode,Key key, SecureRandom random)

            用SecureRandom時,一般用于不需要IV的算法模式,示例代碼如下:

          1. public static String encrypt2(String src) throws Exception {  
          2.        SecureRandom sr = new SecureRandom();  
          3.        DESKeySpec ks = new DESKeySpec(KEY.getBytes("UTF-8"));  
          4.        SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");  
          5.        SecretKey sk = skf.generateSecret(ks);  
          6.        Cipher cip = Cipher.getInstance("DES/CBC/PKCS5Padding");//Cipher.getInstance("DES");  
          7.        IvParameterSpec iv2 = new IvParameterSpec(IV);  
          8.        cip.init(Cipher.ENCRYPT_MODE, sk, iv2);//IV的方式  
          9.        //cip.init(Cipher.ENCRYPT_MODE, sk, sr);//沒有傳遞IV  
          10.        String dest = byteToHex(cip.doFinal(src.getBytes("UTF-8")));  
          11.        return dest;  
          12.     }

            當默認用DES,JAVA會用ECB模式,因此這里IV向量沒有作用,這里,但當用CBC模式下,如果還是用SecureRandom,則每次加密的結果都會不一樣,因為JAVA內部會用隨機的IV來初始化Cipher對象,如示例代碼,由于Cipher.getInstance("DES/CBC/PKCS5Padding")使用了CBC,因此我這里用的javax.crypto.spec.IvParameterSpec包下的IvParameterSpec來初始化向量IV:

          Private final static byte[] IV = new byte[] {0x010x010x010x010x010x010x010x01};

            總結

            對于.NET和JAVA在使用DES對稱加密時,需要大家指定一樣的算法和填充模式,并且JAVA在寫DES加解密算法時,還需要根據(jù)創(chuàng)建Cipher對象的不同,正確使用IV向量。在不同系統(tǒng)需要互相數(shù)據(jù)時,必須要明確的是加密算法,Key和算法模式,再根據(jù)不同模式是否需要IV向量,最后是填充模式。

            本文是經過自己翻閱資料和反復調試代碼而出來的,如有問題,請指正。

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

          性能測試新手誤區(qū)(三):用戶數(shù)與壓力

          同樣的項目、同樣的性能需求,讓不同的測試人員來測,會是相同的結果么?

            假設有這樣一個小論壇,性能測試人員得到的需求是“支持并發(fā)50人,響應時間要在3秒以內”,性能測試人員A和B同時開始進行性能測試(各做各的)。

            只考慮發(fā)帖這個操作,A設計的測試場景是50人并發(fā)發(fā)帖,得到的測試結果是平均完成時間是5秒。于是他提出了這個問題,認為系統(tǒng)沒有達到性能期望,需要開發(fā)人員進行優(yōu)化。

            B設計的測試場景是,50個人在線,并且在5分鐘內每人發(fā)一個帖子,也就是1分鐘內有10個人發(fā)帖子,最后得到的測試結果是平均完成時間2秒。于是他的結論是系統(tǒng)通過性能測試,可以滿足上線的壓力。

            兩個人得到了不同的測試結果,完全相反的測試結論,誰做錯了?

            或許這個例子太極端,絕對并發(fā)和平均分布的訪問壓力當然是截然不同的,那我們再來看個更真實的例子。

            還是一個小論壇,需求是“100人在線時,頁面響應時間要小于3秒”。A和B又同時開工了,這時他們都成長了,經驗更加豐富了,也知道了要設計 出更符合實際的測試場景。假設他們都確認了用戶的操作流程為“登錄-進入子論壇-(瀏覽列表-瀏覽帖子)×10-發(fā)帖”,即每個用戶看10個帖子、發(fā)一個 帖子。于是他們都錄制出了同樣的測試腳本。

            A認為,每個用戶的操作,一般間隔30s比較合適,于是他在腳本中的每兩個事務之間加上了30秒的等待(思考時間)。

            B想了想自己看論壇時的情景,好像平均每次鼠標點擊要間隔1分鐘,于是他在腳本中的每兩個事務之間加上了1分鐘的等待。

            他們都認為自己的測試場景比較接近實際情況,可惜測試結果又是不同的,很顯然A場景的壓力是B的兩倍。那誰錯了呢?或者有人說是需求不明確導致的,那么你需要什么樣的需求呢?

            看看我隨手在網上(51testing)找的提問吧,和上面的內容如出一轍。一定有很多的性能測試人員每天接到的就是這種需求,又這樣就開展了測試,結果可想而知。

            這里我想問幾個問題,希望各位看完了上面的小例子后想一想:

            如果有另一個人和你測同樣的系統(tǒng),你們的測試結果會一致么?
            如果不一致,那么誰是正確的?
            如何證明測試結果是有效的?

            如果你有了一些疑惑,對之前的測試結果少了一些自信,那么請繼續(xù)。

          服務器視角 vs. 用戶視角

            性能測試中非常重要的一塊內容就是模擬預期的壓力,測試系統(tǒng)運行在此壓力下,用戶的體驗是什么樣的。

            那么壓力是什么?壓力是服務器在不斷的處理事情、甚至是同時處理很多事情。壓力是服務器直接處理的“事情”,而不是遠在網絡另一端的用戶。

            下圖中,每一個顏色的線段代表一種操作。在任意一個時刻,服務器都知道它有10個事務需要處理,這10個事務也是有10個用戶產生的。但它不知道的是,整個時間段內的所有事務,是由多少個用戶與系統(tǒng)交互而產生的。

            這句話好像有點繞,我再試著更形象的解釋一下。時刻1,10個當前事務是由10個用戶發(fā)起的。時刻2,依然是10個正在進行的事務,但可能是完 全不同的10個人發(fā)起的。在這段時間內,服務器每一個時刻都在處理10個事務,但是參與了這個交互過程(對服務器產生壓力)的人可能會達到上百個,也可能 只有最開始的10個。

            那么,對于服務器來說,壓力是什么呢?顯然只是每時刻這10個同時處理的事務,而到底是有10個人還是1000個人,區(qū)別不大(暫不考慮session等問題)。

            下面再從用戶的視角來看看。實際的情況中,不可能出現(xiàn)很多用戶同一時刻開始進行操作的場景,而是有一定的時間順序的。正如下圖所示,在這個時間段內,一共有23個用戶進行了操作。

            但是服務器能看到這些用戶么?它知道的只是某一個時間點上,有多少個正在執(zhí)行的事務。大家可以數(shù)一下,此圖中任意時刻的并發(fā)事務依然是10個。

            其實這兩個圖描述的本來就是同一個場景,只不過觀察者的視角不同罷了。

            那么大家想想,在性能需求中最常見到的“并發(fā)用戶”到底是指的什么呢?

          并發(fā)用戶

            很多使用“并發(fā)用戶”這個詞的人,并沒有從服務器視角進行考慮。他們想的是坐在電腦前使用這個系統(tǒng)、對系統(tǒng)產生壓力的人的個數(shù)。基于這個原因, 我很少使用這個容易讓人誤解的詞匯,而是進行了更細的劃分。主要有這么幾個:系統(tǒng)用戶數(shù)(注冊用戶數(shù))、在線用戶數(shù)(相對并發(fā)用戶數(shù))、絕對并發(fā)用戶數(shù)。

            上面幾個例子中所說的“并發(fā)用戶”,實際就是在線用戶數(shù)。其實我更喜歡叫做相對并發(fā)用戶數(shù),因為這個詞更容易讓人感受到“壓力”。相對并發(fā)用戶 數(shù)指的是,在一個時間段內,與服務器進行了交互、對服務器產生了壓力的用戶的數(shù)量。這個時間段,可以是一天,也可以是一個小時。而需求人員必須要描述的, 也正是這個內容。

            而絕對并發(fā)用戶,主要是針對某一個操作進行測試,即多個用戶同一時刻發(fā)起相同請求。可以用來驗證是否存在并發(fā)邏輯上的處理問題,如線程不安全、 死鎖等問題;也可提供一些性能上的參考信息,比如1個用戶需要1秒,而10個用戶并發(fā)卻需要30秒,那很可能就會有問題,需要進行關注,因為10個用戶請 求排隊處理也應該只需要10秒啊。但這種絕對并發(fā)的測試,同實際壓力下的用戶體驗關系不大。

            再回到相對并發(fā)這個概念上來,它與服務器的壓力到底是什么關系呢?如果你理解了前面的所有內容,那么就會知道這兩者其實沒有直接聯(lián)系(當然了,同一個測試用例中,肯定是用戶數(shù)越多壓力越大)。也就是說,你得到的這種性能需求,是無法知道服務器到底要承受多大壓力的。

            那么如何開展性能測試?

          如何模擬壓力

            既然我們知道了所謂的壓力其實是從服務器視角來講的,服務器要處理的事務才是壓力,那么我們就從這出發(fā),來探尋一下性能測試需要的信息。依然用之前的小論壇為例,我們需要測試活躍用戶為500人時,系統(tǒng)的性能是否能還能提供良好的用戶感受。

            假設現(xiàn)在的活躍用戶有50個人(或者通過另一個類似的系統(tǒng)來推算也行),平均每天總的發(fā)帖量是50條、瀏覽帖子500次,也就是每人每天發(fā)一個 帖子、瀏覽十個帖子(為了方便講解,假設論壇只有這兩個基本功能)。那么我們就可以推算,活躍用戶達到500時,每天的業(yè)務量也會成比例的增長,也就是平 均每天會產生500個新帖子、瀏覽帖子5000次。

            進一步分析數(shù)據(jù),又發(fā)現(xiàn)。用戶使用論壇的時間段非常集中,基本集中在中午11點到1點和晚上18點到20點。也就是說每天的這些業(yè)務,實際是分布在4個小時中完成的,如下圖(隨便找了個圖意思一下,數(shù)不一致)。

            那我們的測試場景,就是要用500個用戶在4小時內完成“每人發(fā)一個帖子、瀏覽十個帖子”的工作量。

            注意上面的兩處,“平均每天……”、“分布在4個小時……”。敏感的測試人員應該能發(fā)現(xiàn),這個場景測的是平均壓力,也就是一個系統(tǒng)最平常一天的使用壓力,我喜歡稱之為日常壓力。

            顯然,除了日常壓力,系統(tǒng)還會有壓力更大的使用場景,比如某天發(fā)生了一件重要的事情,那么用戶就會更加熱烈的進行討論。這個壓力,我習慣叫做高峰期壓力,需要專門設計一個測試場景。

            這個場景,需要哪些數(shù)據(jù)呢,我們依然可以從現(xiàn)有的數(shù)據(jù)進行分析。比如上面提到的是“平均每天總的發(fā)帖量……”,那么這次我們就要查到過去最高一 日的業(yè)務量。“分布在4個小時”也需要進行相應的修改,比如查查歷史分布圖是否有更為集中的分布,或者用更簡單通用的80-20原則,80%的工作在 20%的時間內完成。根據(jù)這些數(shù)據(jù)可以再做適當?shù)恼{整,設計出高峰期的測試場景。

            實際工作中可能還需要更多的測試場景,比如峰值壓力場景。什么是峰值壓力呢,比如一個銀行網站,可能會由于發(fā)布一條重磅消息使訪問量驟增,這個突發(fā)的壓力也是性能測試人員需要考慮的。

            需要注意高峰期壓力和峰值壓力的區(qū)別,高峰期壓力是指系統(tǒng)正常的、預期內壓力的一個高峰。而峰值壓力是指那些不在正常預期內的壓力,可能幾年才出現(xiàn)一次。

            這里只是舉了個最簡單的例子,實際工作遠比這復雜的多。需要哪些數(shù)據(jù)、如何獲取,很可能要取得這些數(shù)據(jù)就要花費很大的功夫。這其實就涉及到了一個很重要的內容,用戶模型和壓力模型的建立,以后會有專門的文章進行講述。

            為什么要花這么大的精力來收集這些信息呢?是因為只有通過這些有效的數(shù)據(jù),才能準確的去模擬用戶場景,準確的模擬壓力,獲取到更加真實的用戶體驗。只有這樣,“不同的測試人員,測出相同的結果”才會有可能實現(xiàn),而且結果都是準確有效的。

          要點回顧

            最后通過幾個小問題來總結回顧一下:

            你真的理解“并發(fā)用戶”的意義么?
            什么是用戶視角和服務器視角?
            什么是壓力?
            如何模擬預期壓力?

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

          性能測試新手誤區(qū)(二):為什么我模擬的百萬測試數(shù)據(jù)是無效的?

           

            測試環(huán)境的重要性無需多說,大家都知道測試環(huán)境要盡量的模擬生產環(huán)境,當然也包括數(shù)據(jù)。這樣測試的結果才會更加準確的反應真實的性能。就連開發(fā)過程,都已經開始在大數(shù)據(jù)量下加壓開發(fā)了。那么,關于測試數(shù)據(jù),你了解多少呢?

            通常說的測試數(shù)據(jù)可以分為兩類:

            一是為了測試性能而準備的數(shù)據(jù),這是用來模擬“壓力”的數(shù)據(jù)。也就是常說的數(shù)據(jù)量、歷史數(shù)據(jù)等。一般都會根據(jù)需求或者經驗很容易估算出來,比如案件年增長量為5%,去年數(shù)據(jù)量為100W,測試需要保證3年后系統(tǒng)仍可正常運行,那么就需要計算并模擬出3年后的總數(shù)據(jù)量,在這個基礎上進行測試。

            二是用來輔助測試使用的數(shù)據(jù)。比如有一個對案件進行打分的功能,只有符合一定條件的案件才會出現(xiàn)在打分列表 中。那么我們要測這個打分的操作,首先就要保證有可用的案件,這就需要去生成測試數(shù)據(jù),該數(shù)據(jù)可能一經使用就失效了(已經打過分就不能再打了)。這樣,每 次測試這個功能,就需要準備這樣一批數(shù)據(jù)。這里的測試數(shù)據(jù),更多的是和測試流程有關,是為了能夠正常的進行測試,而不是涉及到性能的。

            我們這里要說的是第一類,對性能測試結果產生直接影響的數(shù)據(jù)。

            先看兩個小案例,涉及到了案件表(T_AJ)和法院編號列(N_FY)、立案日期列(D_LARQ)。案件表中模擬了一百萬測試數(shù)據(jù),測試簡單的查詢操作,根據(jù)經驗,預期響應時間在2秒之內。

            案例1. 查詢本院案件列表,相應的SQL如下:

          select * from T_AJ
          where N_FY=10
          order by D_LARQ desc
            執(zhí)行這個操作耗時近10s,顯然達不到正常預期。

            經排查,生成的100W測試數(shù)據(jù)中,所有的N_FY列值都為10。這樣,最明顯的問題就是,查詢的結果集數(shù)量完全偏離了正常范圍。如果實際有 100家法院,正常分布下,每家法院只有1W的案件,但測試數(shù)據(jù)的FY只有一個值,通過這個查詢,查出了原來100家法院的數(shù)據(jù)。無論是在數(shù)據(jù)庫處理中 (如本例的排序),還是在程序的處理中(如展現(xiàn)或者是對數(shù)據(jù)做進一步處理),兩者的性能差異都是很顯著的。所以這個測試結果是無效的。

            有人說,這個例子太弱了,結果集差了100倍,性能當然不一樣了。那是不是數(shù)據(jù)總量和結果集大小都一致,測試結果就是有效了呢?

            案例2. 查詢本院一個月內收的案件,相應SQL如下:

          select * from T_AJ
          where N_FY=10 and D_LARQ between '20110101' and '20110201'

            這個操作,查出來的結果只有一千條數(shù)據(jù),屬于正常范圍。但查詢的時間還是超過5秒,依然超出了我們的預期。

            查看數(shù)據(jù)發(fā)現(xiàn),N_FY=10的數(shù)據(jù)有近50萬,占了總數(shù)據(jù)量的一半,D_LARQ在一月份的數(shù)據(jù)也占了差不多一半。但是同時符合兩個條件的數(shù)據(jù)還是一千條左右。那么這里的問題就不在于結果集了,而是是否能利用索引進行查詢,看如下兩個圖就能很好理解了。

            在正常數(shù)據(jù)中,每家法院的數(shù)據(jù)可能占總數(shù)據(jù)量的1%,一個月時間段內的數(shù)據(jù)可能占總數(shù)據(jù)量更少,假設是0.5%。那么這時我們通過N_FY和 D_LARQ兩個條件進行查詢,數(shù)據(jù)庫會進行估算:符合D_LARQ查詢條件的數(shù)據(jù)大概有5000條,符合N_FY查詢條件的數(shù)據(jù)大概有1萬條,那么用 D_LARQ上的索引進行查詢是最快的,可以迅速的將查詢范圍縮小到5000條,然后在這5000條中去檢查N_FY是否也符合條件。

            過程如圖一所示(手繪草圖^_^)。

            

          圖一

            注:數(shù)據(jù)按行存儲,小方塊表示符合該列查詢條件的數(shù)據(jù),陰影表示符合所有查詢條件,也就是最終的結果集。箭頭線段表示為了完成查詢,需要掃描的數(shù)據(jù)量,本圖中即符合LARQ查詢條件的數(shù)據(jù)。下同。

            但在本例中不正常的數(shù)據(jù)條件下,數(shù)據(jù)庫會知道:符合N_FY查詢條件的數(shù)據(jù)有50萬條,符合D_LARQ的也有近50萬條,如果使用其中一列的 索引將一百萬的范圍縮減到50萬,比從頭到尾掃描整個表做的工作還要多(為什么呢?需要了解索引的結構和原理),那還是不要用索引了吧。于是數(shù)據(jù)庫會依次 檢查每一條數(shù)據(jù),判斷N_FY和D_LARQ是否符合條件。

            如圖二所示。

          圖二

          注:本圖中實際掃描的數(shù)據(jù)量就是整張表的數(shù)據(jù),但結果集和圖一是一樣大的。

            這樣,就可以知道,總數(shù)據(jù)量一樣,結果集大小一樣,為什么性能差了很多了。就是因為數(shù)據(jù)分布不合理,導致數(shù)據(jù)庫無法正常使用索引,從而進行了全 表掃描。當然,這個數(shù)據(jù)分布,我們依然可以歸類到結果集中去,那就是要保證每一個查詢條件“單獨的結果集”都要符合真實情況,而不僅僅是整個查詢最終的 “總結果集”。

            看個這兩個簡單的小例子,我們再來總結一下關于測試數(shù)據(jù),需要注意的內容:

          1. 最根本、也是大家都知道的就是數(shù)據(jù)量,性能測試必須保證能在預期的數(shù)據(jù)量下進行測試。在一萬條記錄中查詢,和在一百萬數(shù)據(jù)中查詢,顯然是大大不同的,可以把數(shù)據(jù)量看做一種“壓力”,這個就不用再解釋了。

            但是在比較大型的系統(tǒng)中,這一點可能也不是很容易做好,因為這類系統(tǒng)往往有著復雜的數(shù)據(jù)庫,上百張的數(shù)據(jù)表。對每張表都進行數(shù)據(jù)模擬顯然是不現(xiàn)實 的,也是沒有意義的,因為不是每張表都涉及到大數(shù)據(jù)量。那么如何選取不容易遺漏呢?通常通過兩種方式:從設計和業(yè)務角度分析表間關系、從現(xiàn)有實際數(shù)據(jù)量進 行分析推測。

          2. 確保結果集在正常范圍內。結果集的大小直接影響后續(xù)很多工作的性能,如數(shù)據(jù)排序分組、分頁、程序中的邏輯校驗或者是展現(xiàn)。

          3. 數(shù)據(jù)分布必須合理,盡量接近真實。數(shù)據(jù)的分布,其實也就是數(shù)據(jù)的真實性,它直接決定了數(shù)據(jù)庫是否使用索引、選用哪個索引,也就是常說的查詢計劃。不同的查詢計劃也就是不同的數(shù)據(jù)訪問路徑,性能差別可能會很大。

            這里主要涉及到的是索引的問題,需要大家對索引的原理有一定的了解,索引如何工作、數(shù)據(jù)庫如何選擇索引、和索引有關的一寫重要概念如區(qū)分度(selectivity)等等。

          4. 最好的數(shù)據(jù)來自生產環(huán)境。這是顯而易見的,使用真實的數(shù)據(jù)測出來的結果才是最準確的。但是絕大多數(shù)情況下,我 們沒有這樣的好運,可能是客戶禁止、也可能是生產環(huán)境數(shù)據(jù)量比較小。那就只好自己想辦法來模擬了,需要注意的也就是上面說到的幾點。這里再推薦一種方法, 數(shù)據(jù)翻倍。比如已經有了真實的數(shù)據(jù)十萬條,但我們需要一百萬條,那就可以通過寫一些SQL或者存儲過程,將現(xiàn)有的數(shù)據(jù)不斷翻倍(簡單的說,復制到臨時表, 根據(jù)需要修改一些列,再插回到原表),這樣的數(shù)據(jù)真實性還是比較高的。

            關于測試數(shù)據(jù),我想說的就是以上幾點了。另外再補充上一些相關內容,也是性能測試人員需要關注的。

          • 重點了解IO的概念,更準確的說應該是物理IO。一般來講,數(shù)據(jù)庫的瓶頸或者查詢的主要耗時就是IO。所以,數(shù)據(jù)庫優(yōu)化的一個重要方向就是盡量減小IO。

            IO是不是只和數(shù)據(jù)量(行數(shù))有關呢?舉一個例子:

            select co1, col2, col3, col4, col5 from T_AJ 
            where condition...

            T_AJ數(shù)據(jù)量有100萬,表中有近200列,此查詢耗時大于10秒。而另一種實現(xiàn)方式,首先將col1-col5以及查詢條件中的幾個列的數(shù)據(jù)抽取到一張臨時表(#T_AJ)中。然后,

            select co1, col2, col3, col4, col5 
            from #T_AJ where condition...

            臨時表#T_AJ和原數(shù)據(jù)表有同樣的數(shù)據(jù)量(行數(shù)),但是此查詢卻只需要1秒(暫不考慮抽取到臨時表的耗時),這就是不同IO引起的差異。通常我們 使用的數(shù)據(jù)庫都是行式存儲的,可以簡單的理解為,一行數(shù)據(jù)從頭讀到尾,才能進入到下一行。這樣,不管一行中的200列,你只讀取其中的一列還是幾列,其余 的190多列仍然需要一定的IO。在大數(shù)據(jù)量下,這個性能差異就很明顯了。所以上面的這個例子就是一種典型的優(yōu)化手段,索引覆蓋也是處理類似問題的典型方 法,各位自行了解吧。列式存儲數(shù)據(jù)庫(如Sybase IQ)之所以性能這么高,也是同樣的道理。

          • 盡量深入了解這些概念,如執(zhí)行計劃,基于開銷的估算,統(tǒng)計信息等等。我用一句話來簡單描述:數(shù)據(jù)庫通過統(tǒng)計信息來估計查詢開銷,統(tǒng)計信息不準時,開銷估計就可能不準確,從而導致選擇了錯誤的執(zhí)行計劃。

          • 測試過程中數(shù)據(jù)的清理。性能測試過程中可能又會生成大量的數(shù)據(jù),積累到一定程度又會對性能結果造成影響,所以每一輪測試時都應該清理掉之前測試過程中產生的數(shù)據(jù),保證每次測試是在相同的條件下進行的。

          • 性能測試過程中,如果定位到了某一個查詢或SQL有問題,首先要確認的是數(shù)據(jù)是否合理。通過查詢計劃來判斷是否按預期進行了查詢,如果不是,查看數(shù)據(jù)的分布是否真實。一般數(shù)據(jù)庫會提供很多種手段來進行驗證。

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

          性能測試新手誤區(qū)(一):找不到測試點,不知為何而測

           有過一些性能測試經驗的人很容易進入此狀態(tài),他們已經熟悉了性能測試的基本流程,能夠比較熟練的使用測試工具開展工作。我大概從事性能測試一年左 右時遇到了這個問題,那時我覺得性能測試的過程沒有太多挑戰(zhàn),遇到的每一個系統(tǒng),仿佛都可以用同樣的流程完成。半天時間填寫測試方案,一天時間來準備測試 環(huán)境,一天時間準備測試腳本,一到兩天來完成各種測試用例(基準測試、日常壓力測試、峰值壓力測試、絕對并發(fā)測試、穩(wěn)定性測試等),然后就是調優(yōu)、問題復 測和完成測試報告。在我看來,性能測試好像變成了用一些工具去執(zhí)行一個個固定的用例。

            這樣的工作持續(xù)了一段時間后,我感到有些不對勁,一定是哪里出了問題。性能測試難道真的這么簡單,簡單到把任何一個系統(tǒng)套入標準的流程中就可以 了?于是我開始思考測試的意義,為什么要進行性能測試?是因為性能測試可以提供關于瓶頸、缺陷、效率等等我們認為有價值的信息。那僅僅通過一個工具,或者 是一個固定的流程,就可以發(fā)現(xiàn)不同系統(tǒng)的這些信息么?這顯然是不可能的。

            我開始嘗試盡量深入的去理解被測系統(tǒng),這個系統(tǒng)的目的是什么,用戶是如何使用系統(tǒng)的,用戶對哪些業(yè)務的性能比較敏感,系統(tǒng)的一些關鍵業(yè)務實現(xiàn)邏 輯是怎么樣的,從設計實現(xiàn)的角度來看哪些業(yè)務的性能可能存在隱患。這些很少是技術層面上的問題,需要做的只是思考,再深入思考。慢慢的我有了些收獲,開始 了解為什么要測這個系統(tǒng),針對這個特定的系統(tǒng)哪些內容是最重要的,為了獲得需要的信息我需要從哪幾個方面進行測試,為了實現(xiàn)我的想法又需要哪幾種方法或者 工具。(現(xiàn)在我的性能測試過程中,用于理解被測系統(tǒng)、理解用戶、整理測試思路的時間投入大大增加了。你呢,投入了多大比例?)

             要做好這些其實很難,每一個被測系統(tǒng)對我來說,仿佛就變成了一個新的挑戰(zhàn)。但是逐漸的我發(fā)現(xiàn)自己思考問題更全面了、可以更快的抓住系統(tǒng)的重 點、找到更重要的BUG、對系統(tǒng)的實際性能有了更準確的評估。這里提一個簡單的問題,如何確保你的測試結果和生產環(huán)境的性能表現(xiàn)是一致的,也就是說測試結 果能夠真正的反應實際的性能,而不僅僅是代表了你選取的幾個測試場景的性能。話說起來比較繞,但是請認真想一想,你有多大的把握呢?

             上面只是寫了一些個人的感想,我覺得如果在“思想”上沒有辦法上到一個新的臺階,你的性能測試生涯可能也就達到“瓶頸”了。如何突破這個瓶 頸,那就需要努力改變自身,多思考多學習,最核心的能力恐怕不是能培訓出來的。一定會有一些人認為性能測試的重點在于“技術”上,于是他們不斷的記住各種 調優(yōu)配置參數(shù),以為自己掌握了性能的精髓,仿佛什么系統(tǒng)到了他們手上,只要改幾個參數(shù)就會出現(xiàn)奇跡。我也經歷了這個階段,也有過幾次自以為挺高明的調優(yōu)經 歷,也為自己會各種中間件數(shù)據(jù)庫的配置調優(yōu)而有些小得意。但現(xiàn)在想想,那還真是一個比較低的層次,思想上抓不住重點、看不全大局,技術上其實也只是一點皮 毛。面對這類人,只要問幾個為什么就會讓他們無法回答,為什么要調優(yōu)?為什么要調這個參數(shù)?如何證明這次調整的效果?

             將上文簡單的總結成幾點,希望能給性能測試新手提供一丁點的幫助吧:

          1. 性能測試的難點在于對被測系統(tǒng)的理解,在于對測試點的分析。為了實現(xiàn)測試的思想,可以有多種方法,手段永遠只是輔助的,只有思想才是根本的。工具 (如LR)更不等于性能測試,不要以為會用LR就懂了性能測試,那只是最低級的測試執(zhí)行。也不要以為會調幾個參數(shù)就懂了性能測試,那同樣是個比較低的層 次。
          2. 調優(yōu)等技術不是性能測試的主要目的,好的性能也不是調出來的。測試人員一定要明白自己存在的價值所在,所謂的“技術”只是為了達成自己測試目的的一些手段,同開發(fā)人員、DBA相比,你在這些技術上永遠是外行。
          3. 不要照著文檔模板,填入測試方案。每一個系統(tǒng)都是不同的,要真正的認識到這一點,為每個系統(tǒng)設計出有針對性的測試方案。思考你每一步工作的意義和目的。
          4. 如何證明測試結果的有效性,其實是個很難的問題,值得花費時間去認真思考。這個過程涉及到一些很重要的內容,如用戶模型的建立,后續(xù)會有專門的文章。
          5. 性能測試是一個需要不斷改進的過程,每一次只需盡量的做到更好,多做一點點以前沒有想到的東西。經過不斷的積累,你會發(fā)現(xiàn)自己對性能測試有了更深的認識。

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

          性能測試淺談

          本文主要針對WEB系統(tǒng)的性能測試。不涉及具體的執(zhí)行操作,只是本人對性能測試的一點理解和認識。

            性能測試的目的,簡單說其實就是為了獲取待測系統(tǒng)的響應時間、吞吐量、穩(wěn)定性、容量等信息。而發(fā)現(xiàn)一些具體的性能相關的缺陷(如內存溢出、并發(fā) 處理等問題),我認為只是一種附加結果。從更高的層次來說,性能測試最想發(fā)現(xiàn)的,是瓶頸。如何能得到所需要的信息,就需要從多方面進行測試。

            性能測試的內容

            性能測試種類的劃分與定義這里就不說了,各有各的說法,比如性能測試、負載測試、壓力測試這三個詞,在網上能找到N個版本的定義,大體理解就行 了,沒必要在文字層面上較這個真。以下的內容也只是我個人的理解,一些名詞的定義可能和其他資料有所不同,但在我的工作中,這樣是比較形象和容易理解的。

            在實際工作,一般的應用系統(tǒng)會從這么幾個方面進行性能測試。 

            1.基準測試
            Benchmark或者Baseline測試。一般為單用戶測試,或者是零數(shù)據(jù)量環(huán)境下的測試。目的在于建立一個可度 量的參考標準,為其他測試場景或者調優(yōu)過程提供對比參考。也可認為是最基礎的性能測試,如果基準測試的結果都不能達到預期要求,那么后續(xù)場景也就沒必要測 試了。

            2.日常壓力測試
            在基準測試通過后,應該先進行較小壓力下的測試,首先對系統(tǒng)在日常壓力下的表現(xiàn)進行測試。此壓力需要根據(jù)系統(tǒng)使用相關數(shù)據(jù)得出,如系統(tǒng)平均每天訪問量、平均在線人數(shù)、每日完成事務數(shù)等。通過此測試,發(fā)現(xiàn)一些較表面的性能問題并進行處理。

            3.峰值壓力測試
            在日常壓力測試通過后,需要進行更大壓力的測試。此處壓力同樣需要相關數(shù)據(jù)的支持,一般為未來幾年后的預期壓力。 可根據(jù)歷史日均壓力、日最高壓力等信息,估算出未來幾年的日均以及日最高壓力。再通過一些通用估算方法、如二八原則(80%的工作在20%時間內完成,相 當于2小時完成一天8小時的工作量),將日壓力轉換成峰值壓力。
            峰值壓力為可預期到的最大負載壓力,通過了此測試,則認為系統(tǒng)有能力滿足未來增長的壓力。

            4.容量測試
            驗證了系統(tǒng)是否可滿足預期的壓力后,還需要知道系統(tǒng)能夠承受的最大壓力,也就是容量。一般通過“拐點法”進行測試,逐步增大系統(tǒng)的壓力,直到性能指標不可接受或者出現(xiàn)了明顯的拐點。如下圖,拐點在哪?

            5.穩(wěn)定性測試
            驗證系統(tǒng)是否可長期穩(wěn)定的運行,是否存在一些短時間內可能無法發(fā)現(xiàn)的缺陷(如內存溢出、數(shù)據(jù)庫連接不釋放等)。為了 縮短測試工期,一般可將預期一天的壓力集中在2小時內完成(二八原則),這樣持續(xù)加壓10小時,便相當于系統(tǒng)運行5天。注意監(jiān)控各種性能指標是否平穩(wěn),有 無下降。

            以上幾種類型的測試,是性能測試過程中最多用到的。當然也也其他一些比較常用的類型,如絕對并發(fā)測試,測試多用戶對某一功能的瞬時請求,主要用 于驗證系統(tǒng)是否存在并發(fā)邏輯上的處理問題。此測試也可劃分到不同的壓力測試場景中去,根據(jù)不同的用戶壓力,測試相應的絕對并發(fā),一般取在線用戶數(shù)的10% 進行測試;突發(fā)壓力測試,對一些不在預期內的突然壓力進行測試(其實既然想到了,就應該是在預期內了)。以銀行門戶網站為例,可能會由于發(fā)布了一條重要消 息(政策調整)而導致訪問量激增,這種壓力是否會導致系統(tǒng)宕機或者暫時無法提供服務,就是突發(fā)壓力測試需要考慮的了。也有人將此壓力定義為峰值壓力,這就 無所謂了,只要考慮到會有這么一個問題就夠了。

            性能測試的階段

            上面主要說的是測試內容的劃分,也就是說做性能測試時要考慮到的幾個方面。從實際執(zhí)行層面來看,測試的過程一般分為這么幾個階段:

            1.測試確認
            理解被測系統(tǒng)、尋找測試點、確認測試范圍、測試環(huán)境等。一些重要信息需要同PM、需求人員、設計人員討論確認,如用戶最常用哪些功能、最關注哪的性能,程序上哪可能是壓力點,哪些數(shù)據(jù)需要模擬到真實的量級,大體上需要使用哪種測試方法。

            2.確定通過標準
            性能是好是壞、測試是否通過,必須有明確的標準。這個標準,主要從客戶的期望和業(yè)務上的需求兩方面來考慮,客戶的 期望一般指頁面上的響應時間,業(yè)務需求則是系統(tǒng)的處理能力,一般為吞吐量或TPS(每秒完成事務數(shù))。標準制定的不合理,測試結果可能無法反映系統(tǒng)真實的 性能表現(xiàn),或者會讓客戶無法接受我們認為通過的軟件。
            至于具體如何去設定,是需要同業(yè)務負責人(一般為PM)和技術負責人(一般為設計人員)共同確認的,業(yè)務負責人了解用戶的實際需求和期望,技術負責人了解具體的實現(xiàn),可以判斷哪些是不可達到的要求。
            一旦達成了共識,那么測試就要嚴格的按照標準去執(zhí)行。

            3.測試設計
            主要從上面提到的幾個方面進行分析,針對系統(tǒng)的特點設計出合理的測試場景。為了讓測試結果更加準確,這里需要很細致的 工作。如建立用戶模型,只有知道真實的用戶是如何對系統(tǒng)產生壓力,才可以設計出有代表性的壓力測試場景。這就涉及到很多信息,如用戶群的分布、各類型用戶 用到的功能、用戶的使用習慣、工作時間段、系統(tǒng)各模塊壓力分布等等。只有從多方面不斷的積累這種數(shù)據(jù),才會讓壓力場景更有意義。最后將設計場景轉換成具體 的用例。
            測試數(shù)據(jù)的設計也是一個重點且容易出問題的地方。生成測試數(shù)據(jù)量達到未來預期數(shù)量只是最基礎的一步,更需要考慮的是數(shù)據(jù)的分布是否合 理,需要仔細的確認程序中使用到的各種查詢條件,這些重點列的數(shù)值要盡可能的模擬真實的數(shù)據(jù)分布(數(shù)據(jù)統(tǒng)計信息、執(zhí)行計劃相關的內容,此處就不細說了), 否則測試的結果可能是無效的。
            此外,性能測試執(zhí)行過程中,需要監(jiān)控收集的各種指標數(shù)據(jù),也需要明確下來。

            4.測試環(huán)境準備
            部署測試環(huán)境,生成測試數(shù)據(jù),環(huán)境預調優(yōu)等等。預調優(yōu)指根據(jù)系統(tǒng)的特點和自己的經驗,提前對系統(tǒng)的各個方面做一些優(yōu)化調整,避免測試執(zhí)行過程中的無謂返工。比如一個高并發(fā)的系統(tǒng),10000人在線,連接池和線程池的配置還用默認的,顯然是會測出問題的。

            5.測試執(zhí)行、監(jiān)控
            準備測試腳本,執(zhí)行之前設計好的各個用例,監(jiān)控并收集需要的數(shù)據(jù)。出現(xiàn)問題時,切記要全面的保留事故現(xiàn)場、或者是能進行分析的數(shù)據(jù)。比如TOMCAT不再響應,不能只把這個現(xiàn)象記錄下來,這對問題的排查定位是沒有意義的,要保留所有相關的日志,導出線程轉儲和堆轉儲。

            6.問題分析定位、調優(yōu)
            發(fā)現(xiàn)問題或者性能指標達不到預期,及時的分析定位,處理后重復測試過程。
            性能問題通常是相互關聯(lián)相互影響的,表面上看到的現(xiàn)象很可能不是根本問題,而是另一處出現(xiàn)問題后引起的反應。這就要求監(jiān)控收集數(shù)據(jù)時要全面,從多方面多個角度去判斷定位。
            調優(yōu)的過程其實也是一種平衡的過程,在系統(tǒng)的多個方面達到一個平衡即可。

            7.性能報告
            將測試過程中記錄的各種數(shù)據(jù)匯總成報告,將各方面需要的結果清楚的展現(xiàn)出來。

            上面所有內容中,如果排除技術上的問題,性能測試中最難做好的,就是用戶模型(或者叫系統(tǒng)使用模型)的分析。它直接決定了壓力測試場景是否能夠 有效的模擬真實世界壓力,而正是這種對真實壓力的模擬,才使性能測試有了更大的意義。可以說,性能測試做到一定程度,差距就體現(xiàn)在了模型建立上。

            至于性能問題的分析、定位或者調優(yōu),很大程度是一種技術問題,需要多方面的專業(yè)知識。數(shù)據(jù)庫、操作系統(tǒng)、網絡、開發(fā)都是一個合格的性能測試人員需要擁有的技能,只有這樣,才能從多角度全方位的去考慮分析問題。

            當然,對于測試人員來說,技術能力只能排在第二號,測試思想才是最根本的。敏銳的嗅覺、嚴謹?shù)倪壿嫛⒑侠淼耐茰y、大膽的實踐是一個合格測試工程師的必備要素。

            模擬演練

            寫了一大堆,新手還是不知道如何去做。其實寫本文的目的也不是講具體操作,而是思想,思想。新手學性能測試,建議找一本從LOADRUNNER開講的書比較好。如51TESTING上有連載的《性能測試從零開始》。

            不過還是盡量說點具體些的內容吧。

            普通BS架構的系統(tǒng),一般都采用測試工具(如LR)直接錄制手工操作的方式進行測試。這種方式簡單有效,對測試人員要求不高。但在一些情況下, 這種基于錄制的方法可能無法完成,比如頁面上有特殊控件、系統(tǒng)是CS架構、或者通訊的協(xié)議無法捕獲等。這時就需要更復雜的測試方法,如手動編寫模擬客戶端 的JAVA代碼,而把測試工具當作一個調度控制臺,去調度大量的虛擬用戶線程執(zhí)行編寫好的代碼。

            現(xiàn)在假設有一個簡易版的12306網站,JAVA實現(xiàn),中間件為TOMCAT,數(shù)據(jù)庫為SYBASE,沒有集群處理(一切從簡,只有查詢和訂票功能)。如何對它進行性能測試呢?

            按照上面的幾個步驟來想一想吧,這里只簡單寫幾點。

            第一步,測試確認。海量并發(fā),數(shù)據(jù)也應該是海量的,但基本都是簡單查詢,沒有復雜的統(tǒng)計,所以主要困難還是在海量并發(fā)事務的處理上。中間件、數(shù) 據(jù)庫上都會承受巨大壓力。此類高并發(fā)系統(tǒng)還需要對一些功能特別注意,比如一個車次有10張票,5個人同時購票,如何處理?如果是12個人同時點購票,又是 如何處理?

            第二步,通過標準。無非是系統(tǒng)能夠滿足多少人同時在線,一分鐘內能處理多少訂單,用戶最大等待時間是幾分鐘。注意這個標準一定要是經過各方面確認過實際可行的啊,定一個訂單響應時間不超過5秒有意義么?確認了以后,就要按著這個目標來設計測試和執(zhí)行。

            另一個需要注意的問題,按照預期的壓力測試通過了以后,是不是就高枕無憂了?答案是否定的,因為很可能這個預期或者標準是不合理的,這個是非常 可能的,只有長期的數(shù)據(jù)積累,才會一點點走向精確。想想奧運訂票系統(tǒng),開通后短短五分鐘,網站就癱瘓了,你們以為這種系統(tǒng)沒有經過專業(yè)的性能測試么?據(jù)我 所知,奧運訂票系統(tǒng)性能測試時制定的標準是每分鐘處理四百萬訪問(具體數(shù)據(jù)記不住了,就假設是這個數(shù)吧),出事后的檢查發(fā)現(xiàn),每分鐘的訪問量超過了八百 萬。這種事故責任在誰呢?測試機構敢拍胸脯保證,每分鐘處理四百萬就是沒問題的。而奧組委自己設定的每分鐘四百萬目標,和實際出現(xiàn)偏差也是正常的,畢竟這 種系統(tǒng)是第一次上線。最后的處理方法就是,壓力達到了預期最大值以后,再后來的訪問就被排隊了。好好體會這個案例吧,會有收獲的。

            第三步,測試設計。設計用戶模型,設計測試場景,設計測試用例。一個典型的用戶是如何使用系統(tǒng)的?登錄、查詢車次余票、訂票、付款,這是理想化 的情況。實際更可能是這樣的,登錄(一次登不進去,重復多次)、查詢A車次(未到放票時間、不斷重試,時間到無票)、查詢B車次(無票)、查詢C車次(有 票)、訂票、付款、查詢訂單。兩種交互方式對系統(tǒng)產生的壓力,差別是很大的。

            將多個用戶行動整合到一起,也就是用戶模型,或者叫系統(tǒng)使用模型,是壓力場景設計的依據(jù)。假設系統(tǒng)一天的訪問量是一萬個用戶,這一萬訪問量是在 24小時內平均分布的,還是分布在8小時內,還是在某一時間點上集中訪問?這些具體到用例中也就是虛擬用戶的加載策略,直接決定了壓力的大小。

            除了這個壓力場景,針對此系統(tǒng)還需要進行絕對并發(fā)測試,參考第一步的分析。

            第四、五步就不細說了,準備環(huán)境、數(shù)據(jù),針對大量用戶的并發(fā)進行一些預調優(yōu)。按照第三步設計好的各個測試用例準備腳本、執(zhí)行測試。

            第六步,發(fā)現(xiàn)問題了怎么辦?比如1000人的壓力下,系統(tǒng)響應就比較慢了,查詢車次需要1分鐘,下訂單需要2分鐘,接下來要做什么?能把這些作 為一個性能缺陷提起么?顯然是不可以的,這只是通過你的壓力測試場景產生的一個現(xiàn)象,可能是測試腳本有問題、也可能是測試環(huán)境有問題。作為一個性能測試人 員,需要盡量深入的定位到問題產生的原因。就像這個響應慢,只是一個表面現(xiàn)象,慢在哪?是中間件還是數(shù)據(jù)庫?一些簡單的測試方法就可以進行判斷,如在頁面 上進行一些數(shù)據(jù)庫無關的操作,如果依然比較慢,說明在中間件上壓力就已經比較大了。還可以部署另一套中間件測試環(huán)境,連接之前相同的數(shù)據(jù)庫,在壓力測試出 現(xiàn)問題的同時,手動訪問新部署的應用(只有一個用戶),如果同樣很慢,那說明慢在了數(shù)據(jù)庫端的處理上。還可以通過日志的方式更準確的進行判斷,如應用日志 和數(shù)據(jù)庫SQL執(zhí)行日志。總之方法是多種多樣的,但目的只有一個,就是不斷的排除無關部分、縮小問題范圍。

            定位到了中間件和數(shù)據(jù)庫之一,然后又該怎么辦?此時恐怕就需要一些相關方面的專業(yè)知識了,但其實最常見的還是那些。中間件相關的一般是線程池、 JVM、數(shù)據(jù)庫連接池等,數(shù)據(jù)庫相關的有鎖、緩存、IO(一般就是SQL語句的問題)等。要進行全面的監(jiān)控和分析,再做一些合理的調優(yōu)并重復測試。

            問題定位到什么程度才行?我認為是要讓人看了知道改哪就可以了。比如提一個“這個SQL語句進行了大量的物理IO,性能不好”,這就不是個好問 題,物理IO是什么?怎么改?如果這么說就好多了“這個SQL語句沒有使用索引,導致了全表掃描,進行了大量的物理IO,性能不好。如果要避免全表掃描, 需要調整SQL語句或者添加XX索引”,這才是定位問題。

            當然了,上面只是一個非常簡陋的舉例,真實的性能測試要比這復雜的多。

            總的來說,我認為,性能測試的難度主要不在技術手段上,互聯(lián)網時代技術都是共享的,要善于去搜索利用他人的成果。即使自己搞不定,團隊內一定還 有專業(yè)的開發(fā)工程師、數(shù)據(jù)庫管理員、系統(tǒng)管理員可以幫你搞定。真正的難點在于,你要想出來如何去測是有效的、有保障的,這才是測試工程師最重要的能力。 

            還是那個觀點,思想才是根本。

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

          自動化測試:功能測試設計七技巧

           自動化功能測試,或用戶界面(UI)測試,以難以維護而著稱,而且沒有足夠的能力找出缺陷。然而,在大多數(shù)情況下出現(xiàn)故障的原因不是測試工具或者測試框架,而是個別測試本身跟蹤設計不良。

            下面有七個功能測試設計技巧,讓UI測試更加可維護和更強力。

            不要只是點擊 要檢查后續(xù)狀態(tài)

            很多自動化測試工具包含一個特性,就是可以自動記錄一系列動作,然后回放。盡管這樣的記錄/回放功能在創(chuàng)建測試時容易駕馭,但是單純的記錄/回放動作會導致不良測試。具體而言,記錄/回放測試并不會檢測應用中操縱元素后的應用狀態(tài)。

            點擊、鍵入、選擇以及其他的功能都會以某種方式改變應用的狀態(tài)。好的測試會在應用中操作元素后檢查本身的結果。如果自動化測試跟隨一個鏈接,就要讓測試檢查結果頁是否正確。如果測試生成一個報告,就要檢查報告內容是否正確。

            等待,請勿停止

             通常,一個應用在結果可以用測試檢查之前需要一些時間。這一點在Ajax在Web瀏覽器調用中尤為普遍。簡單地進行測試停止或者在檢查這樣的結果之前休 眠幾秒是很吸引人的,但是停止或者休眠是不良實踐,如果應用用過長時間返回,然后測試就會生成錯誤失敗。如果應用更快地返回,然后測試在轉移的過程中就是 浪費時間。

            取代停止或者休眠,讓測試等待應用的具體方面出現(xiàn)了。這不僅僅讓測試減少錯誤失敗的傾向,而且也導致了更強的測試,因此測試根據(jù)生成的測試等待方面,實際等待檢查應用結果。

            使用分離定位 不是索引

            做測試的時候要是像“點擊這個頁面上的第三個鏈接”或者“選擇列表上的第五個元素”這樣就更好了。代替根據(jù)索引操縱應用的具體方面,為這樣的元素找出或者創(chuàng)建唯一識別符值得努力。

            如果命令鏈接改變了,或者命令列表改變了,測試就會導向一種預期外的路徑,維護這樣不可預知的測試相當難。

            用正則表達式檢查排列次序

            應用以正確的序列顯示給用戶非常重要。無論是表格的列數(shù)還是列表的元素,或者是頁面本身的文本,自動化測試檢測事物正確的排列很重要。

            這有一堆事情應該以“一”、“二”、“三”的順序出現(xiàn)。測試可以使用類似的正則表達式檢查出這些事情序列。下面是一個使用簡化的正則表達式“glob”的例子,“glob”在Selenium以及其他自動化測試工具中可用:

          以下是引用片段:
          | getText | glob:one*two*three |
          | click | sort_thing |
          | getText | glob:three*two*one |

             這個測試檢查的第一步是輸入文本“one”,隨后是文本“two”,然后是“three”。“*”表明測試允許“one”"two""three"之間 任意的字符。測試第二步點擊導致“one”“two”“three”倒序排列,然后測試第三步檢查這個排列是否成功了。

            一次且僅一次

             正如上面所指出的,在應用中等待一個元素出現(xiàn)是較好的實踐。通常這樣的例子中一旦元素出現(xiàn),測試會希望操作這個元素,實例就是點擊。這是抽象通用動作到 期自己的方法或者模型的最佳實踐,然后測試按需調用這些動作。下面是一個例子,在Fitnesse和Selenium語法中wait-for-and- click抽象。

          以下是引用片段:
          !| scenario | Wait for and click | elementLocator |
          | waitForElementPresent | @elementLocator |
          | click | @elementLocator |
          So from a test itself we need only write:
          | open | www.foo.com |
          | Wait for and click | link=Welcome to Foo! |
           這個例子中僅節(jié)省了一行鍵入,如果“Wait for and click”在測試套件中執(zhí)行了數(shù)百次或者數(shù)千次,可維護性和可讀性。另一個動作例子就是抽象到期自己可能登陸的模型,選擇列表中的所有元素,為一系列錯誤做檢查。

            不要使用條件語句

            有時,測試環(huán)境具有不可預見性。在這樣的案例中,在測試中使用條件語句很誘人,例如“if this element exists, click it, if it does not exist, do something else.”這種方法會存在很多問題。一個問題就是類似使用索引代替具體定位器導致的問題:如果應用測試改變,自動化測試將會以完全不可預期和位置路徑傳 下去,導致錯誤失敗(或者更糟糕的是錯誤成功),讓維護更加困難。另一個問題是條件語句聲明的一個分支(錯誤地)出現(xiàn)在一起,測試在引入時從未顯示一個缺 陷。

            使用Javascript創(chuàng)建可重用隨機數(shù)據(jù)

            最后,下面是使用Selenium和Fitnesse,進行具體的測試數(shù)據(jù)最佳實踐的例子。在這個例子中,測試需要輸入唯一的Social Security Number,然后檢查SSN是否實際上輸入到應用中:

          以下是引用片段:
          | type; | ssn | javascript{RN =Math.floor(Math.random()*9999999);while (String(RN).length < 8) { RN=RN+'0';}} |
          | $SSN= | getValue | ssn |
          | click | link=Save |
          | type; | search | $SSN |
          | GET SEARCH RESULTS CONTAINING THE SSN |

            Selenium會內嵌評估Javascript。這種測試的首行鍵入域ID值為“ssn”,在運行中生成隨機的9個數(shù)字,通過評估 Javascript作為type()動作的證據(jù)。第二行使用Fitnesse功能來存儲來自“ssn”域的9個數(shù)字,稱之為“$SSN”。然后測試輸入 九個相同數(shù)字到這個域,其ID值為“search”。在測試本身解決數(shù)據(jù)需求是唯一的時候,這是一種高雅有用的方法,在任何合理的測試工具或者框架中同樣 的方法應該有效。

            優(yōu)良測試的優(yōu)良設計

            這些只是一些例子,協(xié)助確保自動化測試強力并可維護。很多其他的例子也存在,每一種自動化測試工具或者框架都有優(yōu)良的設計實踐單獨針對工具。

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

          軟件測試的13項原則

            軟件測試過 程中,我們應注意和遵循一系列的具體原則,在ISTQB 軟件測試基礎認證大綱上,列出了7 項原則,但其中最后一項原則“不存在缺陷(就是有用系統(tǒng))”的謬論不能算是一項合格的原則,所以可以認可的原則是6 項。除此之外,在這里還列出作者認為比較重要的7 項原則,合起來共13 項原則。

            1、ISTQB 的6 項原則

            1)原則1——測試顯示缺陷的存在,但不能證明系統(tǒng)不存在缺陷。測試可以減少軟件中存在未被發(fā)現(xiàn)缺陷的可能性,但即使測試沒有發(fā)現(xiàn)任何缺陷,也不能證明軟件或系統(tǒng)是完全正確的。

            2)原則2——窮盡測試是不可能的。由于有太多的輸入組合、有太多的路徑,而且時間是有限的,無法做到完全的測試(100%測試覆蓋率)。通過運用風險分析和不同系統(tǒng)功能的測試優(yōu)先級,來確定測試的關注點,從而替代窮盡測試。

            3)原則3——測試盡早介入。軟件項目一啟動,軟件測試就應開始,也就是從項目啟動的第一天開始,測試人員就應參與項目的各種活動和開展對應的測試活動。測試工作進行得越早,軟件開發(fā)的劣質成本就越低,并能更好地保證軟件質量。例如,在代碼完成之前,可以進行各種靜態(tài)測試,主導或積極參與需求文檔、產品規(guī)格說明書等的評審,將問題消滅在萌芽階段。

            4)原則4——缺陷集群性。版 本發(fā)布前進行測試所發(fā)現(xiàn)的大部分缺陷和軟件運行失效是由于少數(shù)軟件模塊引起的。一段程序中發(fā)現(xiàn)的錯誤數(shù)越多,意味著這段程序的質量越不好。錯誤集中發(fā)生的 現(xiàn)象,可能和程序員的編程水平、經驗和習慣有很大的關系,也可能是程序員在寫代碼時情緒不夠好或不在狀態(tài)等。如果在同樣的測試效率和測試能力的條件下,缺 陷發(fā)現(xiàn)得越多,漏掉的缺陷就越多。這也就是著名的Myers 反直覺原則:在測試中發(fā)現(xiàn)缺陷多的地方,會有更多的缺陷沒被發(fā)現(xiàn)。假定測試能力不變,通過測試會發(fā)現(xiàn)產品中90%的缺陷。如果在模塊A 發(fā)現(xiàn)了180 個缺陷,在模塊B 發(fā)現(xiàn)了45 個缺陷,意味著模塊A 還有20 個缺陷沒被發(fā)現(xiàn),而模塊B 只有5個缺陷未被發(fā)現(xiàn)。所以,對發(fā)現(xiàn)錯誤較多的程序段,應進行更深入的測試。

            5)原則5——殺蟲劑悖論。采用同樣的測試用例多次重復進行測試,最后將不再能發(fā)現(xiàn)新的缺陷。為了克服這種“殺蟲劑悖論”,測試用例需要進行定期評審和修改,同時需要不斷地增加新的不同的測試用例來測試軟件或系統(tǒng)的不同部分,從而發(fā)現(xiàn)潛在的更多的缺陷。

            6)原則6——測試活動依賴于測試背景。針對不同的測試背景,進行的測試活動也是不同的。比如,對要求安全放在第一位的軟件進行測試,與對一般的電子商務軟件的測試是不一樣的。

            2、其他重要的7 項原則

            1)持續(xù)地測試、持續(xù)地反饋。軟件測試貫穿著整個軟件開發(fā)生命周期,隨時發(fā)現(xiàn)需求、設計或代碼中問題,及時將發(fā)現(xiàn)的問題反饋給用戶、產品設計人員、開發(fā)人員等,主動、積極地交流,持續(xù)提高軟件產品質量,這在敏捷測試中更為重要。

            2)80/20 原則。在 有限的時間和資源下進行測試,找出軟件中所有的錯誤和缺陷是不可能的,因此測試總是存在風險的。測試的一個重要目標是盡量減少風險,抓住重點進行更多的測 試。根據(jù)80/20 原則,即帕累托法則(Pareto Principle),用戶80%的時間在使用軟件產品中20%的功能。“重點測試”就是測試這20%的功能,而其他80%的功能屬于優(yōu)先級低的測試范 圍,占測試20%的資源。

            3)建立清晰的階段性目標。飯要一口一口地吃,不能一口就吃成胖子。測試的目標也要逐步達到,不可能在某一瞬間就達到。根據(jù)軟件開發(fā)生命周期的不同階段性任務,我們要決定相應的測試目標和任務。如在需求分析階段,要參與需求評審以全面理解用戶需求、發(fā)現(xiàn)需求的問題;在功能測試執(zhí)行階段,測試人員不僅要對新功能進行測試,而且要有效地完成回歸測試。

            4)測試獨立性。測試在一定程度上帶有“挑剔性”,心理狀態(tài)是測試自己程序的障礙。同時,對于需求規(guī)格說明的錯誤理解也很難在程序員本人進行測試時被發(fā)現(xiàn)。程序員應避免測試自己的程序,為達到最佳的效果,應由獨立的測試小組、第三方來完成測試。

            5)確保可測試性。事先定義好產品的質量特性指標,測試時才能有據(jù)可依。有了具體的指標要求,才能依據(jù)測試的結果對產品的質量進行客觀的分析和評估,才能使軟件產品具有良好的可測試性。例如,進行性能測試前,產品規(guī)格說明書就已經清楚定義了各項性能指標。同樣,測試用例應確定預期輸出結果,如果無法確定所期望的測試結果,則無法進行正確與否的校驗。

            6)計劃是一個過程。雖 然通過文檔來描述軟件測試計劃,并最后歸檔,但計劃是一個過程,是指導各項軟件測試活動的持續(xù)過程。在項目開始時很難將所有的測試點、測試風險等都了解清 楚,隨著時間推移,通過需求和設計的評審和探索式測試,對產品的理解越來越深,對測試的需求和風險越來越了解,可以進一步細化、不斷豐富測試計劃。其次, 計劃趕不上變化,軟件產品的需求常會發(fā)生變化,測試計劃不得不因此做出調整。所以,測試計劃是適應實際測試狀態(tài)不斷變化而進行調整的一個過程。

            7)一切從用戶角度出發(fā)。在 所有測試活動的過程中,測試人員都應該從客戶的需求出發(fā),想用戶所想。正如我們所知,軟件測試的目標就是驗證產品開發(fā)的一致性和確認產品是否滿足客戶的需 求,與之對應的任何產品質量特性都應追溯到用戶需求。測試人員要始終站在用戶的角度去思考、分析產品特性,多問問類似下面這樣的問題:

            這個新功能對客戶的價值是什么?

            客戶會如何使用這個新功能?

            客戶在使用這個功能時,會進行什么樣的操作?

            按目前設計,用戶覺得方便、舒服嗎?

            如果發(fā)現(xiàn)缺陷,去判斷軟件缺陷對用戶的影響程度,系統(tǒng)中最嚴重的錯誤是那些導致程序無法滿足用戶需求的缺陷。軟件測試,就是揭示軟件中所存在的邏輯錯誤、低性能、不一致性等各種影響客戶滿意度的問題,一旦修正這些錯誤就能更好地滿足用戶需求和期望。

          相關鏈接:

          從1個中心到5個要素——金字塔與軟件測試

          軟件測試中的8組關系

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

          進入軟件測試行業(yè)的六年感悟

           來淘寶測試部三年了,也就是意味著我進入測試行業(yè)也快到六年的時間了。或多或少也有自己的一些感悟,而且不同階段的感悟會一樣。自己在淘寶的每一年的紀念日的時候都會寫篇個人總結來慰問下自己。

            關于這次在淘三年的內容,我自己也是思索了好久,不知道要寫什么,測試感悟的、測試技術的、測試方法的各個方面都想寫,又都不想寫。

            都想寫的理由就是本身測試行業(yè)就是個比較工程和系統(tǒng)性的行業(yè),自然有自己的一些領域知識,說太少了,怕有些人真的以為測試就是點點鼠標而已。

            都不想寫的理由就是怕說太多了,就復雜了,就更讓人摸不著頭腦了;而且很多觀點和事情不是說說就能明白的,只有自己親身經歷了才有深刻的體會。也所謂 如人飲水,冷暖自知。

            最后還是決定好好回顧下這幾年的測試想法,因為這幾年測試行業(yè)發(fā)生了很大的變化,不僅僅是敏捷測試、新測試技術、開發(fā)自測等等,都會影響我自己個人在測試行業(yè)的發(fā)展和能力的提升。真的怕自己走過彎路,所以需要不停的反省自己,這個能力是不是必須的、這個技術是不是應該需要了解的等等。

            介于北京的崔啟亮的建議,還是確定了自己的部分寫作思路,也大致分成幾個部分吧。

            遇到的困難以及解決辦法

            第一個三年:

            在06年畢業(yè)后的測試三年中,遇到了一些基礎困難,幸好自己在觀察和學習的同時,很快就能解決這些問題。 由于之前寫過一個blog介紹了部分問題,大家可以參考下:http://www.51testing.com/html/70/n-807570.html

            但是這邊我還想發(fā)表下自己的觀點,是針對于黑盒測試方法來說的。 記得幾天前討論是否需要QA的時候,段念 寫個一篇blog來說明 一個正常的工程師 都能在一個下午學會和理解大部分的黑盒測試方法。 對此觀點,我是不敢茍同的,這就討論到這些黑盒測試方法的深度的問題了。

             (0)學會和理解測試方法的使用步驟是很簡單的,但是真正的在項目需求中應用起來可不是一朝一夕的。這就好比給你一張撲克一樣,高手就能拿它殺人,一般 的人能做到什么程度呢。 這個也很像有些人能發(fā)現(xiàn)你不能發(fā)現(xiàn)的bug一樣。至于原因有很多,具體看在淘兩年的blog。

            (1)談談我自己的感想吧,我自己在工作前 兩年也是認為這個黑盒測試方法一下午就可以學會的,找?guī)讉€例子試著使用下,感覺自己掌握到這些黑盒測試方法,但是后來我看過很多這些測試方法的背景以及應 用的注意點后。我發(fā)現(xiàn)自己真的是了解了一些皮毛,沒有深入的了解。對于個項目需求,如何快速且完整的應用這些黑盒測試方法設計出不多不少的測試用例,這個需要的經驗的積累,也就是你測試價值的核心體現(xiàn)。

             (2)去年在成都MPD時,很多學員說自己都說自己是工作2-3年的人,已經遇到瓶頸了,感覺測試很單調和無味。我給的建議其實很簡單,那就是真正的理 解和掌握所有的黑盒測試方法。怎么來驗證呢,我自己就是這樣:給你一個白板,你能把所有測試方法的5W2H(What、Why、When、Where、 Who、How、How Much)都能非常清晰明了的演講出來,記住是不需要參考ppt或其他資料的情況下。

            就像火影里面的鳴人一樣,他只會螺旋丸這個核心的攻擊忍術,但是在擴展其他忍術之前,他會把這個忍術的深度發(fā)揮到機制,從而研究出威力更強的超大螺旋丸、超大玉螺旋丸、風遁螺旋丸等等。

            在淘寶的這幾年也越到了很多的困惑,而且隨著年齡的成長,考慮的問題就會越來越猶豫,需要權衡利益的去提升自己和學習。主要考慮的就是測試的深 度和廣度問題。自己畢竟在測試行業(yè)待了那么長時間了,周圍其他測試同仁的發(fā)展、國外測試行業(yè)的發(fā)展、自身利益和環(huán)境的影響等等,這些都會影響自己對某些測 試問題存在個人極端的想法。

            個人認為了解一個人測試的水平,需要考慮其測試行業(yè)中的深度和廣度的知識。

            測試的廣度:主要就是測試相關類型的了解。具體包括如下:需求分析、測試流程、測試管理、開發(fā)流程、開發(fā)技術、測試模型、基礎測試方法和測試技 術、功能測試、性能測試、自動化測試(頁面自動化、API)、安全測試、可靠性測試、易用性測試、穩(wěn)定性測試,探索式測試(ET)、基于風險的測試 (RBT)、兼容性測試等等。

            測試的深度:也就是對廣度說到的某一項你了解到的深度。當然這個深度,每個人都有自己的定位和看法,關鍵還是看自己是如何來對待的,這邊我說下自己對自動化測試的深度的看法吧。

            基礎:了解簡單的測試腳本/代碼的編寫,了解不完整的測試框架架構。

            進階一:快速編寫測試腳本/代碼,解決部分代碼編寫的問題,了解完整的測試框架架構。

            進階二:理解和了解自動化測試設計,自動化測試在項目中的融入和實施策略問題,了解其他類似的測試工具,并能做出正確的判斷。

            進階三:快速編寫合理的測試腳本/代碼(體現(xiàn)在測試設計和測試數(shù)據(jù)設計上),指導他人編寫可維護性的測試腳本,深入了解測試框架的實現(xiàn)細節(jié)和開發(fā)技術。

            高級:整體上來解決自動化測試效率和價值的問題,找到測試框架的問題或困難,并能解決它,或提出有效的建議,深入了解其他類似測試框架或工具,并了解其功能技術細節(jié)。提升測試框架的應用性和實效性和效率。

            就我個人而言,我一直也在擴大自己的測試廣度,也在提升自己的測試深度。在淘寶的這幾年,淘寶測試部的發(fā)展非常的快速,自己也從中學到了很多,我也慶幸自己在來淘寶之前就把某些的深度問題給解決了,從而可以提高自己其他的廣度。

            一開始來淘寶,就選擇 自動化測試這個廣度,并在頁面自動化測試和API接口測試方向 提升自己的深度(這是個長期的過程)。另外也選擇了兼容性測試這個 廣度,不過這個進展筆記緩慢。接著根據(jù)自己的方向和優(yōu)勢,選擇了 探索式測試 這個廣度,從而在這個領域學習到了更多的知識,從而影響其他廣度的選擇。接著不停的提升自己在需求分析、測試流程、測試模型、性能測試方面的深度,也會接 觸安全測試這個廣度等。 最近選擇了 前端測試和無線測試領域,這也是擴大自己的廣度,不斷的學習和了解該領域的測試特點和工具。

            給大家的建議是根據(jù)公司測試技術的發(fā)展策略,有針對性的選擇某幾個測試廣度,然后在其上提升自己的深度。你的測試能力就是 你的廣度 * 你的深度。

            不管我去擴大其他的測試廣度,有幾個測試領域我是必須要求自己,也強烈建議其他測試同仁需要達到的較高深度的。也就是我自己一直深信的測試理 念,我是一個測試工程師,你可以說我level不高,考慮不到高層想要的東西。但是我是會追求自己所相信的,那就是測試設計能力:也就是不同測試類型的測 試方法的應用能力。不僅僅是有這個能力,而是 更快、更準、更狠的 測試設計。

            個人測試感悟

            0、時刻牢記自己的狀態(tài)和目標

            你需要確定你目前所在的廣度有哪些,和深度是怎么樣的。根據(jù)自己的特點和測試信念和公司情況,選擇深度和廣度,然后指定計劃和目標,執(zhí)行下去。這個可以整體上解決 你的瓶頸問題。

            1、開發(fā)和測試是亦敵亦友的關系

            以前一個測試同仁說過,沒有和開發(fā)吵過架的測試不是一個好測試。我雖然不是很認可,但是他還是有一定的道理,本身開發(fā)和測試的立場和思維邏輯就 不一樣,短時間較難改變,那這里就需要表現(xiàn)測試的價值。但是測試需要開發(fā)的幫助才能更好的理解設計和代碼,才能更好的設計用例,才能更好的保證質量,才能 更好的提升自己的技能。這是個平衡,測試和開發(fā)走的太近不好,走的太遠也不好。不要說開發(fā)和測試共享質量、共同承擔責任啥的,目前國內是這樣,以后可能會 不一樣。

            2、測試需求分析時多問為什么

            需求評審和需求分析,對應大多數(shù)測試同仁來說是個不易提高的地方,也是很難傳承經驗的地方,這里還是需要去學習一些需求分析方法,總體上就是建議你凡是多問問什么、為啥會這樣、還有沒有更好的。

            3、驗證bug時多看看code change

            記得在華為和微軟Onsite測試的時候,就討論過了很多次,我還是很喜歡在驗證bug時看code change。看不懂的地方直接問開發(fā),不斷的提升自己在代碼方面的經驗和敏感度,那段時間真的很快樂。后來我還會參與bug fix,這些都是多看code change的后期提升,讓自己更加有價值,不僅僅能發(fā)現(xiàn)bug,還能fix bug。

            4、持續(xù)優(yōu)化你的測試設計

            不管是項目還是產品,你只要是負責人,一定要保證該產品或項目的測試設計是最新狀態(tài),并且在不同的信息輸入期間都有新版本的測試設計產出,特別是測試執(zhí)行后期,那些未通過測試用例發(fā)現(xiàn)bug的用例,一定要保證測試設計的時效性和完整性和最新性。

            5、沒事多看看其他人提的bug

            線下bug場景和線上故障的場景都是非常好的案例,不是單純的由某個黑盒測試方法能發(fā)現(xiàn)的,所以我們需要關注這些場景案例,總結起來,并轉換為自己所用。這個經驗積累不是那么容易看出來,而且經驗也不是那么容易show出來,但是不要低估它,關鍵時刻就靠他了。

           6、 控制自動化和它的價值

            這里讓大家理解自動化測試的價值和目的是沒有任何問題,關鍵是控制它。根據(jù)自己產品的特點要找到一個平衡點,不要盲目的自動化。一定要控制手工測試用例、自動化測試用例的比例(UI級別、API級別的)。不要讓它成為你的累贅,不要讓你每次的腳本排查成為慣例現(xiàn)象。

            7、堅持自己選擇的測試信念

            之前很早就提到過test school,建議每個人根據(jù)自己的個人信仰和特點來選擇某個test school。因為一旦你選擇是某個school的人物,你就會學習這個school的很多測試理念和測試想法,堅信它們并在自己的團隊中應用起來。我個 人就是屬于context-driven school。

            8、用戶體驗和代碼完美性是王道

            很多人都應該說過測試人員測試就是應該站在用戶角度去思考問題,多去考慮用戶體驗,的確這是個能幫助測試人員研究用戶和提升易用性測試的一個途 徑,另外可以多看看用戶提供的反饋意見,完善自己的測試思路和需求分析思路。另外一點就是,我們很多bug開發(fā)都會說用戶不會這么去做,幾乎不可能的,所 以這個bug是invalid的。我們不僅僅是考慮用戶應該做什么,我們還要考慮用戶不應該做什么,有可能做什么,能夠做什么。這些都是不一樣的,多從代 碼健壯性和容錯性考慮代碼的完美性。

            9、享受測試帶來的一切

            不管你是畢業(yè)就從事測試工作,還是先干開發(fā)再轉測試,不管你做測試的原因和動機是什么,個人建議你只要還在測試行業(yè),試著去發(fā)現(xiàn)測試的美,不要 人云亦云,也不要固步自封。測試會讓你開心、會讓你單調、會讓你憤怒、會讓你痛苦、會讓你瘋狂、會讓你無味。不要擔心自己會不會失業(yè)或沒有價值,不管怎 樣,提升自己的廣度和深度,逐步的享受測試帶來的一切。

            測試的發(fā)展趨勢和職業(yè)發(fā)展

            看這幾年,國內的測試發(fā)展還是不錯的。不過相比較國外來說,我還是比較悲觀的,測試和開發(fā)一樣還是至少落后于國外10年。我們這幾年在不停的學 習和實踐自動化測試、探索式測試、敏捷測試、基于模型的測試等等。很多國外走過的彎路,國內的我們還是在走,這似乎就是歷史的輪轉。

            個人認為測試的多元化發(fā)展還是一個主要的方向,也就是測試本身所提供的價值。測試手段的多樣性和深度是必須要經過的環(huán)節(jié)。個人認為沒有一到兩種 測試方法、技術、手段能夠解決被測產品的所有測試任務,我們需要不斷的從不同角度去測試,去工具SUT,最近流行的分層測試、敏捷測試其實都是基于這個認 可。對于持續(xù)集成,個人認為只要自動化測試不消失,事實上他的價值還是不錯的,也應該不會出現(xiàn)這個情況,那持續(xù)集成就還是基礎的測試底層框架搭建。只是這 個持續(xù)集成的作用,我們現(xiàn)在還只用到了不到五成,接下來大家應該會在這方面有所突破,不過這方面還是有難度的,且不好考核。

            另外個就是提升開發(fā)自測,提升開發(fā)自測的質量對測試來說,實在是太重要了,但是不意味著測試可以掉以輕心。目前的開發(fā)自測狀況是開發(fā)人員發(fā)現(xiàn) 20%的bug后,到時間了,開始提測。測試這邊發(fā)現(xiàn)70%的bug,到時間了,該上線了。那么開發(fā)自測的目標就是開發(fā)人員發(fā)現(xiàn)60%的bug,fix 后,提測。測試這邊發(fā)現(xiàn)35%的bug,fix后上線。表面上看總體上只多發(fā)現(xiàn)了5%的bug,而測試發(fā)現(xiàn)bug也減少了,但是從開發(fā)整體進度和項目進度 上來說,可是個非常大的進步,絕對的快速發(fā)布了,測試人力成本也會減少較多。

            由于答應了某位測試同仁,這里大致說下探索式測試的發(fā)展。個人是在09年底開始了解ET,目前淘寶在ET方面并沒有大范圍的展開,還是在某些測 試組、某些項目實施了不同形式的ET方式(部分項目是Freestyle形式,部分是ET輔助或bug bash的,主要是我這邊來把控的,我個人時間有限,你懂的),至于結果,仁者見仁智者見智。大家也可以我個人其他的blog里面看到,至于工具使用的是 Freemind和Session tester。個人認為ET應該是未來測試發(fā)展的某個重要的方向,幾乎可以和自動化測試齊步,特別在ROI上,自動化測試肯定會低于ET的,但是事物都有 兩面性,ET必然有它不完整、不成熟的階段,這個階段需要大家一起去完善,一起去堅持自己的測試信念。

            關于職業(yè)發(fā)展,我是想走技術的,但是我自己也迷茫了很多次,做到什么樣的程度呢,我的測試廣度和深度到底要達到什么樣的程度呢?公司需要我這個 測試廣度嗎?公司需要我這個測試廣度下面的這個深度嗎?是不是還需要再深入一點呢?我心里有很多這樣的迷惘。比如開發(fā)技術就是一個矛盾點,這個深度真的不 是那么容易把握的,大家都知道了解開發(fā)知識、懂開發(fā)知識對做好測試是有益的,但是到底應該懂得啥程度呢,能帶來多大的好處呢,啥情況下呢,開發(fā)自己都痛苦 的學來學去,測試真的一定要跟著后面嗎?這個精力我是否應該多了解下兼容性測試呢?是不是應該多了解下RBT呢?我心里確實有很多的矛盾,很多次我都不知 道怎么過來的。不過我還是有自己的決定,我會盡量地去尋找自己的平衡,時刻的去review自己的狀態(tài),自己的這個測試廣度達到了什么樣的深度了,是不是 可以暫停下,去提升下其他測試廣度的深度了。

            想走管理的,就是測試管理了,多考慮一線測試工程師的生活,他們是如何進行測試的,他們遇到什么問題,解決問題才是王道,解決他們的痛苦,提升 他們的效率,讓大家快速的干完,可以去做些自己感興趣的事情。另外就是多考慮下國外的測試新技術,有些不一定現(xiàn)在有用,以后呢,做些儲備是必要的,就像軍 隊一樣,平時沒事做,關鍵還要用的,特別是特種部隊了,各方面要求都很高,做這些儲備更需要管理層的覺悟和想法了。

            想走技術的路線,就是盡最大的努力提升開發(fā)技術,另外就是多擴展自己的測試廣度吧,爭取在幾個核心的測試廣度上達到最深的深度,成為真正的測試專家。

            另外就是可以考慮走產品經理或其他路線的,比如SQA等。另外提一下,我也喜歡叫tester,不喜歡被叫QA。

            廢話說的有點多,期望對大家有幫助,大家有任何不同的觀點,歡迎提出。

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

          流媒體服務器的自動測試系統(tǒng)

           摘要:隨著網絡帶寬的日益增加,流媒體應用的規(guī)模與范圍也日益擴大,如何測試評 價流媒體服務器的功能性與性能就成為一個亟待解決的問題。本文設計與實現(xiàn)了一種流媒體服務器的自動測試系統(tǒng)。該系統(tǒng)通過輸入的測試任務,利用測試服務器與 測試客戶端的兩層架構對流媒體服務器進行測試。該系統(tǒng)能夠測試流媒體服務器對于RTSP協(xié)議的支持情況,接收和分析RTP包中幀數(shù)據(jù)的準確性,并且可以測 試流媒體服務器的性能。實驗表明,該系統(tǒng)具有良好的可用性,可以實現(xiàn)高效靈活的測試需求。

            引言

            目前,隨著移動增值業(yè)務的快速發(fā)展和第三代數(shù)字通信技術的實施,移動增值業(yè)務已經不再僅僅局限于短信、彩信、彩鈴等窄帶業(yè)務,用戶對于在移動網絡環(huán)境下點播和觀看視頻的需求越來越迫切。流媒體技術作為在互聯(lián)網上實時傳輸音、視頻的主要方式,成為一種在數(shù)據(jù)網絡上傳遞多媒體視頻數(shù)據(jù)的主流技術。如此,流媒體服務系統(tǒng)對于作為承載多媒體基本業(yè)務的流媒體服務器的評估也顯得由為重要。

             當前的流媒體系統(tǒng)包含了多種網絡接入方式,多種軟件體系架構,及多種應用場景如電視會議系統(tǒng)、網絡電視(IPTV)系統(tǒng)等。如何有效的測量各種系統(tǒng)所提 供的視頻業(yè)務支撐能力就成為一個有待研究的問題,此類問題直接關系到各流媒體系統(tǒng)的優(yōu)越性、實用性以及其重大革新意義的展現(xiàn)。并且當前的各個流媒體系統(tǒng)都 面臨不斷升級的需求,對于系統(tǒng)升級前后的兼容性、一致性也需要給出評價。

            由于音頻、視頻信號很難量化表示,目前對流媒體服務器的測試方法一般還是通過人工“察言觀色”的方式完成,即測試人員通過STB (Set-Top-Box,機頂盒) 或Web頁面與流媒體服務器建立連接,由測試人員發(fā)起測試,并對測試結果進行主觀判斷,分析系統(tǒng)的工作情況。但是由人工來測試工作量將非常大,并且人工測試也很難提取服務器的各種性能響應參數(shù),驗證檢查力度不夠,測試有效性低,不夠全面,可維護和可擴展性差,測試效果不理想。

            這里列舉幾個常見的問題實例:

            1、手工測試過程中,大量的精力花在輸入數(shù)據(jù)、執(zhí)行測試用例,監(jiān)聽觀看系統(tǒng)的音視頻輸出是否正常上,無法集中精力到關鍵問題,如提高測試的有效性,編寫更多更好的測試用例等。

            2、由于采用人工判斷的方式,所以無法對系統(tǒng)的性能指標進行量化分析。

            3、測試工作中許多操作是重復性的、非智力性的和非創(chuàng)造性的,并要求準確細致地完成,對于重復性手工測試很難保證每一次測試的效率與有效性。

            4、如果有大量(如幾千)的測試用例,需要在短時間內(如1天)完成,手工測試幾乎不可能做到

            為解決手工測試存在的問題,我們很自然的就想到了自動化測試。自動化測試的優(yōu)點有很多,如快速、可靠、可重復性、可重用性等等,這些優(yōu)點使得自動化測試在流媒體服務器測試過程中的地位不斷提高,成為評價流媒體服務器的重要方法。

            本文研究的主題就是如何設計實現(xiàn)針對流媒體服務器的自動化測試系統(tǒng),達到快速量化的判定流媒體系統(tǒng)的目的。該測試系統(tǒng)包括以下內容:

            ● 流媒體操作功能測試

            ● 流媒體數(shù)據(jù)有效性正確性驗證;

            ● 流媒體系統(tǒng)性能測試

            流媒體技術概述及研究現(xiàn)狀

             在流媒體(Streaming Media)技術出現(xiàn)之前,人們若想從網絡上觀看影片,必須先將影視文件下載到本地,然后才可進行播放。流媒體技術的出現(xiàn)客服了這個限制,它可以讓用戶不 需要將整個影音文件下載到用戶機器,而是一邊下載一邊播放。所以流媒體是指在數(shù)據(jù)網絡上按時間先后次序傳輸和播放的連續(xù)音、視頻數(shù)據(jù)流。流媒體數(shù)據(jù)流具有 3個特點:連續(xù)性、實時性、時序性,即其數(shù)據(jù)流具有嚴格的前后時序關系。這種提供一邊下載一邊播放的服務系統(tǒng)稱為流媒體服務系統(tǒng)。所以對于流媒體服務系統(tǒng) 的評價需要測試系統(tǒng)的數(shù)據(jù)延時,丟包率,比特率等指標;不僅如此為不斷提升移動環(huán)境下流媒體業(yè)務的服務質量,需要通過不斷提升服務器能力,提升終端能力, 增加傳輸和編碼效率等辦法來多方面地提升整個移動流媒體系統(tǒng)的性能。而提升系統(tǒng)性能的前提是對目前系統(tǒng)性能可以進行準確地測試和評價。

             目前,對流媒體服務器的測試多關注與流媒體服務器的性能測試。流媒體服務器性能測試指標主要有最大并發(fā)流數(shù)目、帶寬波動、丟包率和平均響應時間等,其中最 大并發(fā)流數(shù)目是關注的最多的。最大并發(fā)流數(shù)目是指流媒體服務器能夠支持的有效的、能夠同時在線正常觀看節(jié)目的最大用戶數(shù)目。

            ……………………

            查看全文請點擊下載:http://www.51testing.com/html/56/n-811856.html

            3.3 RTP流的測試

            流媒體服務器通過RTP協(xié)議封裝音頻和視頻流。流媒體自動化測試系統(tǒng)通過捕獲發(fā)送的RTP流并分析這些RTP流來判斷流媒體服務器的性能。

             RTP流中封裝的是流媒體服務所需的音頻流和視頻流,其中音視頻都是通過特定的壓縮技術對音視頻流進行編碼,目前視頻流傳輸中最為重要的編解碼標準有國 際電聯(lián)的H.261、H.263,運動靜止圖像專家組的M-JPEG和國際標準化組織運動圖像專家組的MPEG系列標準。這些標準都采用幀作為每一幅畫面 的單位,為了支持多種協(xié)議的編碼格式,本文論述的流媒體自動化測試系統(tǒng)不直接按照各種協(xié)議分析幀數(shù)據(jù),而是對所有的協(xié)議采用統(tǒng)一的處理方法,這樣增加了測 試系統(tǒng)的通用性。

            具體的方法,按照PTS建立每一幀的索引,對每一幀的數(shù)據(jù)應用MD5算法產生信息摘要;然后對接收的媒體流與預存的媒體流中相同幀進行一次MD5校驗,從而得出結論當前幀是否完全。

            RTP流中另一個重要的指標為丟包率,由于流媒體服務器需要經過對流媒體數(shù)據(jù)的編碼和加密后將數(shù)據(jù)壓縮到RTP數(shù)據(jù)包中,所以測試系統(tǒng)無法從簡單的統(tǒng)計RTP包的個數(shù)中得到丟包率。本文論述的流媒體自動化測試系統(tǒng)根據(jù)RTP流中每個RTP包必須順序傳送來計算丟包率。

             具體的方法,根據(jù)當前RTP包的序號判斷下一個RTP包的序號,如果RTP包的序號不符合,則丟包加一;然后在根據(jù)新的RTP包的序號判斷下一個RTP 包的序號。在數(shù)據(jù)流結束時,根據(jù)丟包數(shù)與總的RTP包數(shù)計算丟包率。這樣丟包率數(shù)據(jù)同時也可以反映數(shù)據(jù)傳輸?shù)膩y序問題。

           流媒體自動化測試系統(tǒng)采用分級分析的策略,針對測試不同任務的需要,按照不同的分析級別給出不同詳細程度的測試結果分析。具體的,流媒體自動化測 試系統(tǒng)采用如下表的三層分級策略級別,即活躍級,探測級,完整級。其中完整級提供最詳細的RTP包分析結果,這一級對它所包含的全部幀數(shù)據(jù)進行信息分析, 可用于需要對流媒體服務器進行詳細的功能測試;探測按照設定的抽樣間隔對整個RTP流進行抽樣檢測,可用于性能測試及穩(wěn)定性測試等需要消耗較高資源的測試 任務;活躍級檢查RTP包的延時,丟包率,比特率等基本信息的分析,可用于壓力測試等消耗很高資源的測試任務。完整級與探測級需要使用預先設定的流媒體 源,這樣才能比較客戶端接收到的RTP流中的幀數(shù)據(jù)是否完全正確。

          級別

          功能

          粒度

          活躍級

          檢查RTP包的延時,丟包率,比特率等基本信息

          基本

          探測級

          需設定采樣率;除統(tǒng)計活躍級的信息外,還需要按照采樣率分析關鍵幀的數(shù)據(jù)。

          較詳細

          完整級

          除統(tǒng)計活躍級的信息外,還要對所有的幀進行分析。

          詳細

            3.4 性能測試

            性能測試主要是測試被測的流媒體服務器在預期用戶量或者打用戶量情況下系統(tǒng)的穩(wěn)定性、可靠性和響應時間。本測試系統(tǒng)通過逐漸增加并發(fā)流的數(shù)目的方法觀察各個性能參數(shù)的變化從而得出服務器的最大服務能力。

            目前本測試系統(tǒng)對于流媒體服務器的性能參數(shù)定義如下:

            1)最大并發(fā)流數(shù)目:流媒體服務器可以長時間支持的客戶端數(shù)目。

            2)聚合輸出帶寬:流媒體服務器發(fā)送的總的帶寬。

            3)請求響應時延:從用戶發(fā)出RTSP點播開始到接收第一個RTP數(shù)據(jù)包之間的時間間隔。

            4)丟包率:客戶端接收到的不連續(xù)的數(shù)據(jù)包的比率。

            測試系統(tǒng)通過多線程的客戶端以及可以配置多個客戶端這些靈活的方案實現(xiàn)對流媒體服務器的測試。

            4、流媒體自動化測試系統(tǒng)實現(xiàn)

            4.1 測試服務器的實現(xiàn)

            本文所述的測試服務器完成測試任務的管理與測試數(shù)據(jù)的統(tǒng)計分析工作。它由主線程、調度線程、配置線程、定時線程和輸 出線程組成。主線程完成其他線程的創(chuàng)建工作,然后輪詢是否有新的任務,如果監(jiān)測到新的任務,交由配置線程讀取新任務的各種配置參數(shù)。調度線程負責將新的測 試任務分配給某個測試客戶端進行執(zhí)行。定時線程會定時觸發(fā)分析線程讀取測試客戶端送上來的測試結果進行分析。最后交由輸出線程保存測試結果的磁盤文件中。

            分析線程需要根據(jù)測試任務的需要根據(jù)不同的測試級別進行分析,當進行完整級的測試分析時會消耗較大的CPU與內存資源,所以使用時間片強制使得分析線程讓出系統(tǒng)資源使得測試服務器可以響應外部的輸入,并且可以使用定時器使得分析線程在特定的時間繼續(xù)分析測試數(shù)據(jù)。

            測試服務器的內部線程實現(xiàn)如下圖所示

            ……………………

            查看全文請點擊下載:http://www.51testing.com/html/56/n-811856.html

            4.3 自動化測試系統(tǒng)的部署

            本文所述的流媒體自動化測試系統(tǒng),基于測試服務器與測試客戶端的實現(xiàn),能夠支持分布式的部署。在具體部署測試時,可以根據(jù)測試的流媒體服務器的能力進行靈活的部署配置。

            當測試的流媒體服務器系統(tǒng)可以支持多臺服務器同時提供流媒體服務,可以將測試服務器與測試客戶端部署在不同的硬件服務器,并且可以部署多個測試 客戶端用于測試不同的服務器。當測試的流媒體服務器為單服務器或者提供的并發(fā)負載能力較低時,可以將測試服務器與測試客戶端部署在同一個硬件服務器。由于 單個測試客戶端就可以支持與多個流媒體服務器建立流媒體服務會話連接,所以一般情況下,單臺測試服務器就可以支持對含有多個流媒體服務器的流媒體服務系統(tǒng) 進行測試。

            ……

            查看全文請點擊下載:http://www.51testing.com/html/56/n-811856.html

            本文收錄于《51測試天地》電子雜志第二十五期。

            版權聲明:本文出自51Testing軟件測試網電子雜志——《51測試天地》第二十五期。51Testing軟件測試網及相關內容提供者擁有51testing.com內容的全部版權,未經明確的書面許可,任何人或單位不得對本網站內容復制、轉載或進行鏡像,否則將追究法律責任

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

          5個常見的Rails開發(fā)誤區(qū)

          本文作者是一名Rails開發(fā)者,他總結了在Rails開發(fā)過程中的一些常見誤區(qū)。文章內容如下:

            我使用Rails已經有一段時間了,在這期間我看了大量的Rails項目,下面的這五個常見的誤區(qū),我?guī)缀踉诿恳粋€Rails代碼中都看到過。

            1、沒有 schema 規(guī)范的遷移

            數(shù)據(jù)模型是應用程序的核心。沒有schema的約束,你的數(shù)據(jù)會因為項目代碼上的bugs而慢慢變得糟糕,直到你無法相信庫中的任何字段。這里有一個 Concact Schema:

          1. create_table "contacts" do |t|  
          2.     t.integer  "user_id" 
          3.     t.string   "name" 
          4.     t.string   "phone" 
          5.     t.string   "email" 
          6. end

            上面哪些需要更改呢?通常一個Contact必須依附于User,并且會有一個name 屬性,這可以使用數(shù)據(jù)庫約束來確保。可以添加“:null => false”,這樣即使驗證代碼存在bugs,我們依然可以確保模型一致性,因為如果違反了null約束,數(shù)據(jù)庫并不會允許模型保存這些數(shù)據(jù)。

          1. create_table "contacts" do |t|  
          2.     t.integer  "user_id", :null => false 
          3.     t.string   "name", :null => false 
          4.     t.string   "phone" 
          5.     t.string   "email" 
          6. end

            TIPS:使用“:limit => N”規(guī)范你的string類型字段的大小。Strings 默認255個字符,而phone字段應該不需要這么長吧!

            2、面向對象編程

            大多數(shù)Rails開發(fā)人員并不寫面向對象的代碼。他們通常會在項目中寫面向MVC的Ruby代碼(把模型和控制器分開寫在合適的位置)。通常是在lib目錄下添加帶有類方法的工具模塊,僅此而已。但開發(fā)人員往往需要花費2-3年才能認識到“Rails就是Ruby。我完全可以創(chuàng)建一些簡單的對象,并且不一定按照Rails建議的方式去封裝它們。”

            TIPS:對你調用的第三方服務使用facade(外觀模式)。通過在測試中提供mock facade,你就不用在你的測試集中真的去調用這些第三方服務了。

            3、在 helpers中連接HTML

            如果你正在創(chuàng)建helper,恭喜,至少說明你正在試圖讓你的視圖層更整潔。但是開發(fā)人員經常不知道一些使用helpers創(chuàng)建標簽的常見方式,這就導致了槽糕的字符串連接或者糟糕的插值形式。

          1. str = "<li class='vehicle_list'> " 
          2. str += link_to("#{vehicle.title.upcase} Sale", show_all_styles_path(vehicle.id, vehicle.url_title))  
          3. str += " </li>" 
          4. str.html_safe

            看吧,相當糟糕,而且容易導致XSS安全漏洞!讓content_tag來拯救這些代碼吧。

          1. content_tag :li, :class => 'vehicle_list' do 
          2.   link_to("#{vehicle.title.upcase} Sale", show_all_styles_path(vehicle.id, vehicle.url_title))  
          3. end

            TIPS:現(xiàn)在就開始在helper中使用blocks(代碼塊)吧。當產生內嵌的HTML時,嵌入的blocks更自然、更貼切。

            4、Giant Queries(大查詢,比如載入整張表的查詢)會把一切都加載到內存

            如果你需要修正數(shù)據(jù),你只需要遍歷并且修正它,對嗎?

          1. User.has_purchased(true).each do |customer|  
          2.   customer.grant_role(:customer)  
          3. end

            假設你有個百萬級別客戶的電商網站,假設每個用戶對象需要500字節(jié),上面的代碼會在運行的時候消耗500M內存。

            下面是更好的方式:

          1. User.has_purchased(true).find_each do |customer|  
          2.   customer.grant_role(:customer)  
          3. end

            find_each使用 find_in_batches 每次取出1000條記錄,非常有效的降低了對內存的需求。

            TIPS:使用 update_all 或者原始 SQL 語句執(zhí)行大的更新操作。學習SQL可能需要花費點時間,不過帶來的好處是明顯的:你會看到100x的性能改善。

            5、代碼審查

             我猜你會使用GitHub,并且我進一步猜測你不會去pull requests(GitHub上的申請代碼合并操作)。如果你需要花費一到兩天去構建一個新特性,那么到一個分支上去做吧,然后發(fā)送一個 pull request。團隊會審查你的代碼,并且給出一些你沒有考慮到的改進或者最新特性的建議。我保證這樣會提高你的代碼質量。我們在TheClymb項目中 90%的改動都是通過這種方式完成的,并且這是100%值得去做的一個經驗。

            TIPS:不要沒有經過任何測試就合并你的pull request。測試對保證應用的穩(wěn)定性非常有價值,并且可以讓你踏實地睡一個好覺。

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

          僅列出標題
          共394頁: First 上一頁 325 326 327 328 329 330 331 332 333 下一頁 Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統(tǒng)計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 太仆寺旗| 成安县| 阿拉善盟| 鄢陵县| 安图县| 轮台县| 文昌市| 邳州市| 南澳县| 梁平县| 阳江市| 大港区| 分宜县| 隆昌县| 镇康县| 宁陵县| 南丹县| 吴川市| 乌兰察布市| 衢州市| 双桥区| 漳平市| 岱山县| 碌曲县| 延长县| 南乐县| 曲周县| 合山市| 龙江县| 略阳县| 鸡西市| 潼关县| 青浦区| 宿松县| 渭源县| 湖州市| 澄城县| 贺兰县| 山阴县| 烟台市| 六盘水市|