qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問 http://qaseven.github.io/

          我眼中的各種編程語(yǔ)言

           所有的編程語(yǔ)言我都討厭。曾經(jīng)我想自創(chuàng)一門語(yǔ)言,但我沒搞明白到底需要一門什么語(yǔ)言,所以也從未開始過。 許多時(shí)候,你沒法選擇使用哪種語(yǔ)言。不管我在用哪種語(yǔ)言,我都嘗試去接受它的優(yōu)點(diǎn)和缺點(diǎn)。
            Java
            喜歡Java的人肯定喜歡打字。我指的就是敲打鍵盤上的鍵。你得不斷地重復(fù)又重復(fù)。
            設(shè)計(jì)Java系統(tǒng)的人是個(gè)瘋子,他解決問題的方式就是,設(shè)計(jì)模式。如果你把設(shè)計(jì)模式看作是這個(gè)語(yǔ)言中解決問題的一種方式,那么你會(huì)發(fā)現(xiàn)Java里有許多這樣的設(shè)計(jì)模式。
            另一方面,Sun的這些家伙的確是費(fèi)了點(diǎn)心思在Java規(guī)范上的,這使得它能運(yùn)行在嵌入式系統(tǒng)上,所以這塊我們還是堅(jiān)持在使用它。我很難相信Python或者C在我的手機(jī)桌面系統(tǒng)上運(yùn)行。
            還有,那些個(gè)目錄又是怎么回事?我必須得使用Eclipse,因?yàn)橹挥兴涝趺刺^那1000個(gè)字長(zhǎng)的路徑名。如果我在應(yīng)用的同一個(gè)目錄下放10個(gè)類,會(huì)不會(huì) 傷害到某些人?
            C
            C是精確的。當(dāng)我用C寫程序的時(shí)候,如果搞定了,我知道它是靠譜的。它就像是用一把小刷子在畫一幅巨作。在這么詳細(xì)的層面上寫代碼需要一種不同的心態(tài)。當(dāng)你坐下來寫C的時(shí)候,在動(dòng)手之前你就得規(guī)劃好到底怎么寫。否則后面肯定得費(fèi)很多工夫去改。
            如果你的經(jīng)驗(yàn)足夠豐富,內(nèi)存泄露這種事就不太會(huì)找上門。它的第二特性——malloc/free總是形影不離。你不能忘了任何一個(gè)。否則就像是忘了沖水或者關(guān)燈。你就這么做就是了。
            有句話說得好,如果你打算給房子上漆,一把好刷子可遠(yuǎn)遠(yuǎn)不夠。我猜你肯定想要個(gè)大滾軸。如果讓我寫一整個(gè)應(yīng)用或者系統(tǒng),能不用C的話我肯定不用。
            C程序想要進(jìn)行改動(dòng)可得費(fèi)老勁了。當(dāng)我寫算法的時(shí)候,我知道第一遍肯定是不會(huì)對(duì)的,所以我通常都先用Python寫,搞定了之后再翻譯成C的。
            C++
            它就是個(gè)有string類的C。同時(shí)還有數(shù)組,列表,隊(duì)列等東西,你可以用它們來實(shí)現(xiàn)你想要的。一言以蔽之:別想著自創(chuàng)新模板。這太困難了。除了這個(gè),C++還改良了一下C,用C++你可以寫出非常不錯(cuò)的軟件。它這個(gè)額外的特性使得它可以用于一些大型系統(tǒng)上,只要大家都還遵循同樣的約束的話,難度還不算太大。
            JavaScript
            這是個(gè)沒人喜歡的語(yǔ)言。不過它喜歡你。當(dāng)你剛開始學(xué)習(xí)它的時(shí)候,你可能會(huì)寫出一些非常糟糕的代碼,把對(duì)象用作字典,別的對(duì)象作KEY,不過這樣也是OK的,因?yàn)檫@些代碼運(yùn)行起來也沒有什么問題,只要瀏覽器還支持JavaScript就好。
            JavaScript沒有連接器,因此所有的代碼都共享一個(gè)命名空間,不過還好大家都知道這一點(diǎn),所以還能一起和諧相處。
            CoffeeScirpt
            CoffeeScirpt是一個(gè)解釋器,它將那些長(zhǎng)得像Ruby的奇怪的語(yǔ)言逐行地翻譯成JavaScript。它是一個(gè)擁有所有外來語(yǔ)法的JavaScript——括號(hào),方括號(hào),額外關(guān)鍵字移除。只有代碼的基本含義還保留著。
            CoffeeScirpt挺不錯(cuò)的。如果你要寫很多代碼的時(shí)候,它能讓你提高至少25%的效率。你可以一次在屏幕上看到更多行的代碼。
            當(dāng)你用CoffeeScript寫代碼的時(shí)候,你得時(shí)刻記住這是要生成JavaScript的。問題就在這。你得先去學(xué)習(xí)JavaScript。項(xiàng)目來的新人都得先學(xué)JavaScript,然后才能學(xué)CoffeeScript,最后才能去學(xué)習(xí)項(xiàng)目代碼。
            node.js
            我也希望能愛上它。我覺得我給過它機(jī)會(huì)了。它的回調(diào)讓我無法忍受。我知道會(huì)有這么一天,因?yàn)槟硞€(gè)原因,其中一個(gè)回調(diào)并沒有出現(xiàn),然后我的應(yīng)用就會(huì)堵在那一直等待。真是要了命了。
            還有一點(diǎn)就是,它幾乎沒有內(nèi)建任何東西。如果你要做某件事情,總是會(huì)有一大堆模塊來實(shí)現(xiàn)這個(gè)功能的。該選哪個(gè)呢?如果出現(xiàn)問題了,哪個(gè)模塊會(huì)有人來支持?
            Scala
            Scala是一門函數(shù)式,強(qiáng)類型的語(yǔ)言,它會(huì)編譯成JVM代碼。
            我是在工作中學(xué)的Scala。有一家初創(chuàng)公司的生產(chǎn)系統(tǒng)用的是它,我是在后期才加入他們的。
            這讓我看到了Scala丑陋的一面:類型推導(dǎo)。類型推薦被它用到了極致。每個(gè)對(duì)象都有類型,不過想確定它是什么類型的,你得檢查不同分層上的好幾個(gè)文件才行。Scala也繼承了Java的文件夾的壞毛病,因此你要查找某個(gè)類型的話得進(jìn)入好幾層目錄才能找到對(duì)應(yīng)的那個(gè)文件。
            簡(jiǎn)而言之,Scala是極好的——對(duì)于那些最初的開發(fā)人員而言。新加入的成員為了熟悉現(xiàn)有的代碼,得有一個(gè)很長(zhǎng)的學(xué)習(xí)曲線。
           Erlang
            Erlang也是我曾經(jīng)想愛上的一位。我真的努力了。它是一門美麗的函數(shù)式語(yǔ)言,它可以寫出很精致的小模塊,它們以一種精確的方式進(jìn)行通信,你的系統(tǒng)可以運(yùn)行10年以上,因?yàn)樗芴幚砦粗獑栴},如果必要的話還會(huì)重啟,然后繼續(xù)運(yùn)行。
            不過它的結(jié)構(gòu)太復(fù)雜了。開發(fā)似乎要停留在伯克利發(fā)明socket的那個(gè)年代。當(dāng)前時(shí)代所需的東西幾乎一樣都沒有。為什么開發(fā)一個(gè)簡(jiǎn)單的WEB服務(wù)需要費(fèi)這么大的工夫?
            Go
            Go很容易學(xué)習(xí),對(duì)于新人而言也是如此。它使用40年前的語(yǔ)言概念來構(gòu)建一個(gè)健壯的異步系統(tǒng),但它讓你能像寫同步代碼一樣編程。你可以不費(fèi)吹灰之力寫出1000個(gè)可以安全工作的線程。
            在庫(kù)支持方面它仍需要改進(jìn)。當(dāng)我想做某事的時(shí)候,該用哪個(gè)庫(kù)——github上2011年的那個(gè),還是2013年開始的那個(gè)半成品?一個(gè)是官方主頁(yè)鏈接的,不過它的官方主頁(yè)看起來并不是最新的。好吧,我覺得我還是自己寫一個(gè)吧。。。
            還有,為什么追加元素到數(shù)組里也這么費(fèi)勁?
            Python
            在Python里,不管你想做什么都會(huì)有一個(gè)對(duì)應(yīng)的庫(kù),如果你用的是Linux,它絕對(duì)是不二選擇,因?yàn)樗梢砸绘I安裝。
            如果你想做些數(shù)字處理或者科學(xué)運(yùn)算,選擇Python吧,你值得擁有。
            Python中的字符串即可能是文本的也可能是二進(jìn)制的,因此你得上來就學(xué)習(xí)下文本編碼的東東。
            Python 3
            Python 3和Python有許多共同的特性,不過它卻是門不同的語(yǔ)言。由于它比較新,因此支持的并不是很好。我也想使用它,不過總會(huì)有那么一個(gè)庫(kù),它是只支持Python 2的。

          posted @ 2014-07-30 09:42 順其自然EVO 閱讀(176) | 評(píng)論 (0)編輯 收藏

          Lr11、QTP11破解時(shí)需要注意的問題

           雖然很早之前就成功裝過這兩個(gè)軟件了。但是前陣子重裝了系統(tǒng)再裝這兩個(gè)軟件時(shí)卻發(fā)現(xiàn)我又把破解的方法給忘了。后來從歷史文檔中搜索了好久才得到解決。想想這些還是需要總結(jié),事情多了,難免忘記。也分享給需要的童鞋們。
            LR11的破解方法
            1)退出程序,把下載文件中的lm70.dll和mlr5lprg.dll覆蓋掉..\HP\LoadRunner\bin下的這兩個(gè)文件
            2)注意,win7的話一定要以管理員身份運(yùn)行啟動(dòng)程序,啟動(dòng)后,點(diǎn)擊 configuration->loadrunner license,此時(shí)可能會(huì)有兩個(gè)許可證信息存在,退出程序,點(diǎn)擊deletelicense.exe文件,來刪除剛才得許可證信息(即時(shí)原來沒有l(wèi)isense最好也運(yùn)行一下)
            3)再次打開程序, configuration->loadrunner license->new license,在彈出的輸入框中輸入license序列號(hào)AEABEXFR-YTIEKEKJJMFKEKEKWBRAUNQJU-KBYGB,點(diǎn)擊確定,驗(yàn)證通過后,則破解成功!
            QTP11的破解方法
            1)安裝成功后,手工創(chuàng)建:C:\Program Files\Common Files\Mercury Interactive下,
            建立文件夾License Manager(這個(gè)很重要,必須要?jiǎng)?chuàng)建)
            2)拷貝破解文件mgn-mqt82.exe至第一步創(chuàng)建的目錄下。
            3)運(yùn)行破解文件,提示在C:\Program Files\Common Files\Mercury Interactive下創(chuàng)建了lservrc文件
            4)用記事本打開lservrc,拷貝第一個(gè)#號(hào)前的一大串字符串。運(yùn)行QTP,輸入這串字符
            5)安裝QTP的功能測(cè)試許可服務(wù)器安裝程序(打開qtp11的安裝包里邊的)
            6)刪掉SafeNet Sentinel目錄(C:\ProgramData\SafeNet Sentinel)
            7)運(yùn)行\(zhòng)HP\QuickTest Professional\bin中的instdemo.exe

          posted @ 2014-07-30 09:42 順其自然EVO 閱讀(169) | 評(píng)論 (0)編輯 收藏

          性能測(cè)試個(gè)人經(jīng)驗(yàn)小結(jié)

           性能測(cè)試定義:
            通過一定的工具結(jié)合相應(yīng)的測(cè)試方法,對(duì)部署的系統(tǒng)應(yīng)用進(jìn)行測(cè)試,發(fā)現(xiàn)系統(tǒng)應(yīng)用內(nèi)部存在的代碼邏輯問題及應(yīng)用部署的機(jī)器硬件資源瓶頸問題及應(yīng)用部署架構(gòu)存在架構(gòu)錯(cuò)誤問題,如:網(wǎng)絡(luò)端、客戶端、服務(wù)端搭建的架構(gòu)問題;
            負(fù)載測(cè)試:是一個(gè)分析軟件應(yīng)用程序和支撐架構(gòu)、模擬真實(shí)環(huán)境的使用,從而來確定能夠接收的性能過;
            壓力測(cè)試(Stress Testing):是通過確定一個(gè)系統(tǒng)的瓶頸或者不能接收的性能點(diǎn),來獲得系統(tǒng)能提供的最大服務(wù)級(jí)別的測(cè)試;
            性能測(cè)試的目的:
            性能測(cè)試的目的主要體現(xiàn)在三個(gè)方面:以真實(shí)的業(yè)務(wù)為依據(jù),選擇有代表性的、關(guān)鍵的業(yè)務(wù)操作設(shè)計(jì)測(cè)試案例,以評(píng)價(jià)系統(tǒng)的當(dāng)前性能;當(dāng)擴(kuò)展應(yīng)用程序的功能或者新的應(yīng)用程序?qū)⒁徊渴饡r(shí),負(fù)載測(cè)試會(huì)幫助確定系統(tǒng)是否還能夠處理期望的用戶負(fù)載,以預(yù)測(cè)系統(tǒng)的未來性能;通過模擬成百上千個(gè)用戶,重復(fù)執(zhí)行和運(yùn)行測(cè)試,可以確認(rèn)性能瓶頸并優(yōu)化和調(diào)整應(yīng)用,目的在于尋找到瓶頸問題;
            項(xiàng)目開發(fā)周期:初始時(shí)刻,項(xiàng)目更多關(guān)注的是功能實(shí)現(xiàn),此時(shí)功能測(cè)試顯得尤為重要,測(cè)試的提前介入,可以提前預(yù)測(cè)風(fēng)險(xiǎn),減少項(xiàng)目開發(fā)周期、節(jié)約開發(fā)成本;功能測(cè)試后的階段,個(gè)人認(rèn)為應(yīng)該是性能測(cè)試(試想,如果一個(gè)項(xiàng)目連功能都實(shí)現(xiàn)不了,更何談性能測(cè)試);在功能完畢之后,引入性能測(cè)試,通過性能測(cè)試對(duì)開發(fā)項(xiàng)目潛在的問題進(jìn)行排查(功能測(cè)試,僅僅是幾個(gè)人或者幾十個(gè)人簡(jiǎn)單的對(duì)應(yīng)用功能的一個(gè)測(cè)試,對(duì)于應(yīng)用真正上線后的大量用戶使用,應(yīng)用存在的潛在風(fēng)險(xiǎn),并不能做很好的預(yù)估,尤其是當(dāng)前空前的競(jìng)爭(zhēng)壓力下,應(yīng)用上線后的失敗,很可能導(dǎo)致整個(gè)項(xiàng)目的失敗;例如:12306訂票網(wǎng)站,使用量之大,可能全世界前所未有,調(diào)動(dòng)全國(guó)人力去測(cè)試應(yīng)用性能問題,肯定是不可能的。如果事先不經(jīng)過性能測(cè)試,貿(mào)然上線,在如此之多的用戶使用情況下,系統(tǒng)崩潰將是怎樣的一種后果。);
            案例分享:編者曾經(jīng)從事過一個(gè)項(xiàng)目,伴隨項(xiàng)目的始終。前期階段,由于測(cè)試提前介入,以及項(xiàng)目開發(fā)采用的敏捷開發(fā)方式,項(xiàng)目很快在不到半年的時(shí)間內(nèi),功能近乎完美完成。項(xiàng)目經(jīng)理本著穩(wěn)妥起見,引入性能測(cè)試,對(duì)項(xiàng)目潛在的風(fēng)險(xiǎn)進(jìn)行評(píng)估,然后就搭建了一套模擬環(huán)境,專用于性能測(cè)試,搭建的模擬環(huán)境30用戶并發(fā)運(yùn)行,項(xiàng)目一點(diǎn)問題沒有,進(jìn)一步提升并發(fā)用戶數(shù),各種問題接踵而來;經(jīng)過系統(tǒng)調(diào)優(yōu)后(發(fā)布的應(yīng)用系統(tǒng)參數(shù)等),部分問題解決;為了進(jìn)一步測(cè)試實(shí)際情況下存在問題,性能測(cè)試環(huán)境由模擬環(huán)境切到了生產(chǎn)環(huán)境上,此時(shí)是大量用戶下的并發(fā),部分業(yè)務(wù)是沒有問題的,但是更多的問題是集中在涉及到工作流的一些業(yè)務(wù)場(chǎng)景上,后臺(tái)日志各種報(bào)錯(cuò);通過抓取后臺(tái)日志,對(duì)問題進(jìn)行定位分析,很快排查解決了代碼開發(fā)中存在的一些邏輯問題;代碼修復(fù)后重新上線,問題已基本不存在了;項(xiàng)目也很快結(jié)束,大大的縮短了項(xiàng)目開發(fā)周期、節(jié)約了開發(fā)成功、更好的適用于用戶;
            性能測(cè)試注意點(diǎn):
            錄制腳本盡量模擬實(shí)際用戶操作,在場(chǎng)景設(shè)計(jì)時(shí),盡量與實(shí)際場(chǎng)景一致,對(duì)于用戶使用比較多的業(yè)務(wù),應(yīng)著重關(guān)注;
            性能測(cè)試盡可能在實(shí)際生產(chǎn)環(huán)境上進(jìn)行,普通模擬環(huán)境并不能真正發(fā)現(xiàn)實(shí)際生產(chǎn)環(huán)境下,應(yīng)用存在的問題,但是并非棄用模擬環(huán)境;
            性能測(cè)試,對(duì)于應(yīng)用系統(tǒng)部署的環(huán)境上,可能需要部署一些系統(tǒng)性能監(jiān)控軟件,在軟件的選取上,盡可能降低軟件自身運(yùn)行對(duì)系統(tǒng)性能的影響;
            性能測(cè)試,特別是應(yīng)用與數(shù)據(jù)庫(kù)交互的業(yè)務(wù)操作上,需要提前預(yù)制符合性能測(cè)試業(yè)務(wù)需求的數(shù)據(jù),在此基礎(chǔ)上,盡量讓環(huán)境測(cè)試環(huán)境可多次重復(fù)使用,這就要求數(shù)據(jù)、應(yīng)用可還原;
            性能測(cè)試技能掌握要求:
            測(cè)試環(huán)境搭建,環(huán)境搭建不僅僅是性能測(cè)試所需要具備的技能,也是測(cè)試人員所需要具備的基本技能;很多測(cè)試,包括應(yīng)用的安裝卸載,都需要測(cè)試人員具備這一技能;
            應(yīng)用搭建使用協(xié)議的了解,很多情況下,性能測(cè)試人員需要錄制測(cè)試腳本,這就要測(cè)試人員對(duì)應(yīng)用采用的協(xié)議有充分的了解;
            服務(wù)器架構(gòu)的了解,單一的一臺(tái)服務(wù)器、多臺(tái)服務(wù)器情況下的集群架構(gòu)等,了解服務(wù)器架構(gòu),可以為性能測(cè)試人員初期性能調(diào)優(yōu)提供幫助;
            操作系統(tǒng)機(jī)能的掌握,特別是Linux操作系統(tǒng)的了解,當(dāng)前大多數(shù)的應(yīng)用部署在Linux操作系統(tǒng)之上,性能測(cè)試人員需要掌握操作系統(tǒng)知識(shí)這一基礎(chǔ)技能;
            數(shù)據(jù)庫(kù)知識(shí),面對(duì)大數(shù)據(jù)時(shí)代,數(shù)據(jù)庫(kù)機(jī)能的掌握不僅僅可以為性能測(cè)試服務(wù),還可以為你今后的華麗轉(zhuǎn)型,提供良好保障,華麗的DBA;
            良好的編碼思量。基礎(chǔ)的編碼知識(shí),對(duì)于編碼的了解,可以為你今后沖擊高級(jí)性能測(cè)試工程師提供有力保障,一個(gè)高級(jí)性能測(cè)試工程師,應(yīng)當(dāng)具有性能調(diào)優(yōu)這一技能,編碼就顯得尤為重要;
            對(duì)于新技術(shù)、新思想的一種追求與掌握;

          posted @ 2014-07-30 09:38 順其自然EVO 閱讀(382) | 評(píng)論 (0)編輯 收藏

          Spring 數(shù)據(jù)庫(kù)連接整理

           1、數(shù)據(jù)庫(kù)連接jdbc.properties配置詳解
            jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
            jdbc.username=sa
            jdbc.password=
            jdbc.driver=不同的數(shù)據(jù)庫(kù)廠商驅(qū)動(dòng),此處不一一列舉
            接下來,詳細(xì)配置代碼如下:
            Spring連接池
          <beans>
          <!-- picks up and registers AppConfig as a bean definition -->
          <context:component-scan base-package="com.acme"/>
          <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>
          <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
          <property name="url" value="${jdbc.url}"/>
          <property name="username" value="${jdbc.username}"/>
          <property name="password" value="${jdbc.password}"/>
          </bean>
          </beans>
            DBCP連接池
          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
          <property name="driverClassName" value="${jdbc.driverClassName}" />
          <property name="url" value="${jdbc.url}" />
          <property name="username" value="${jdbc.username}" />
          <property name="password" value="${jdbc.password}" />
          </bean>
          C3P0
          <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
          <property name="driverClass" value="${jdbc.driverClassName}"/>
          <property name="jdbcUrl" value="${jdbc.url}"/>
          <property name="user" value="${jdbc.username}"/>
          <property name="password" value="${jdbc.password}"/>
          </bean>
          <context:property-placeholder location="jdbc.properties"/>
          proxool
          <bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource" destroy-method="close">
          <property name="driverClass" value="${jdbc.driverClassName}"/>
          <property name="jdbcUrl" value="${jdbc.url}"/>
          <property name="user" value="${jdbc.username}"/>
          <property name="password" value="${jdbc.password}"/>
          </bean>
          <context:property-placeholder location="jdbc.properties"/>
            當(dāng)然還有Druid 、DBPool 、Jakarta DBCP 等

          posted @ 2014-07-29 09:39 順其自然EVO 閱讀(182) | 評(píng)論 (0)編輯 收藏

          Linux自帶多路徑詳解

            一、多路徑解釋
            多路徑,顧名思義就是有多種選擇的路徑。在SAN或IPSAN環(huán)境,主機(jī)和存儲(chǔ)之間外加了光纖交換機(jī),這就導(dǎo)致主機(jī)和存儲(chǔ)之間交換速度和效率增強(qiáng),一條路徑肯定是不行的,也是不安全不穩(wěn)定的。多路徑就是要來解決從主機(jī)到磁盤之間最快,最高效的問題。主要實(shí)現(xiàn)如下幾個(gè)功能
            故障的切換和恢復(fù)
            IO流量的負(fù)載均衡
            磁盤的虛擬化
            多路徑之前一直是存儲(chǔ)廠商負(fù)責(zé)解決,竟來被拆分出來單獨(dú)賣錢了。
            構(gòu)架基本是這樣的:存儲(chǔ),多路徑軟件,光纖交換機(jī),主機(jī),主機(jī)系統(tǒng)。
            二、LINUX下的multipath
            1、查看是否自帶安裝?
            [root@web2 multipath]# rpm -qa|grep device
            device-mapper-1.02.39-1.el5
            device-mapper-1.02.39-1.el5
            device-mapper-multipath-0.4.7-34.el5
            device-mapper-event-1.02.39-1.el5
            [root@web2 multipath]#
            2、安裝
            rpm -ivh device-mapper-1.02.39-1.el5.rpm    #安裝映射包
            rpm -ivh device-mapper-multipath-0.4.7-34.el5.rpm  #安裝多路徑包
            外加加入開機(jī)啟動(dòng)
            chkconfig –level 2345 multipathd on          #設(shè)置成開機(jī)自啟動(dòng)multipathd
            lsmod |grep dm_multipath                      #來檢查安裝是否正常
            3、配置
          # on the default devices.
          blacklist {
          devnode "^(ram|raw|loop|fd|md|dm-|sr|sr|scd|st)[0-9]*"
          devnode "^hd[a-z]"
          }
          devices {
          device {
          vendor "HP"
          path_grouping_policy multibus
          features "1 queue_if_no_path"
          path_checker readsector()
          failback immediate
          }
          }<br><br>完整的配置如下:
          blacklist {
          devnode "^sda"
          }
          defaults {
          user_friendly_names no
          }
          multipaths {
          multipath {
          wwid                    14945540000000000a67854c6270b4359c66c272e2f356321
          alias                   iscsi-dm0
          path_grouping_policy    multibus
          path_checker            tur
          path_selector           "round-robin 0"
          }
          multipath {
          wwid                    14945540000000000dcca2eda91d70b81edbcfce2357f99ee
          alias                   iscsi-dm1
          path_grouping_policy    multibus
          path_checker            tur
          path_selector           "round-robin 0"
          }
          multipath {
          wwid                    1494554000000000020f763489c165561101813333957ed96
          alias                   iscsi-dm2
          path_grouping_policy    multibus
          path_checker            tur
          path_selector           "round-robin 0"
          }
          multipath {
          wwid                    14945540000000000919ca813020a195422ba3663e1f03cc3
          alias                   iscsi-dm3
          path_grouping_policy    multibus
          path_checker            tur
          path_selector           "round-robin 0"
          }
          }
          devices {
          device {
          vendor                  "iSCSI-Enterprise"
          product                 "Virtual disk"
          path_grouping_policy    multibus
          getuid_callout          "/sbin/scsi_id -g -u -s /block/%n"
          path_checker            readsector0
          path_selector           "round-robin 0"
          }
          }
           4、命令
          [root@web2 ~]# multipath -h
          multipath-tools v0.4.7 (03/12, 2006)
          Usage: multipath        [-v level] [-d] [-h|-l|-ll|-f|-F|-r]
          [-p failover|multibus|group_by_serial|group_by_prio]
          [device]
          -v level        verbosity level
          0                    no output
          1                    print created devmap names only
          2                    default verbosity
          3                    print debug information
          -h              print this usage text
          -b file         bindings file location
          -d              dry run, do not create or update devmaps
          -l              show multipath topology (sysfs and DM info)
          -ll             show multipath topology (maximum info)
          -f              flush a multipath device map
          -F              flush all multipath device maps
          -r              force devmap reload
          -p policy       force all maps to specified policy :
          failover             1 path per priority group
          multibus             all paths in 1 priority group
          group_by_serial      1 priority group per serial
          group_by_prio        1 priority group per priority lvl
          group_by_node_name   1 priority group per target node
          device          limit scope to the device's multipath
          (udev-style $DEVNAME reference, eg /dev/sdb
          or major:minor or a device map name)
          [root@web2 ~]#
            5、啟動(dòng)關(guān)閉
            # /etc/init.d/multipathd start      #開啟mulitipath服務(wù)
            service multipath start
            service multipath restart
            service multipath shutdown
            6、如何獲取wwid
            1、
            [root@vxfs01 ~]# cat /var/lib/multipath/bindings
            # Multipath bindings, Version : 1.0
            # NOTE: this file is automatically maintained by the multipath program.
            # You should not need to edit this file in normal circumstances.
            #
            # Format:
            # alias wwid
            #
            mpath0 36006016051d50e0035744871c912de11
            mpath1 36006016051d50e0034744871c912de11
            mpath2 36006016051d50e0032744871c912de11
            mpath3 36006016051d50e0039744871c912de11
            mpath4 36006016051d50e003a744871c912de11
            2、
            [root@vxfs01 ~]# multipath -v3 |grep 3600
            sdb: uid = 36006016051d50e003a744871c912de11 (callout)
            sdc: uid = 36006016051d50e003a744871c912de11 (callout)
            sdd: uid = 36006016051d50e003a744871c912de11 (callout)
            sde: uid = 36006016051d50e003a744871c912de11 (callout)
            36006016051d50e003a744871c912de11 1:0:0:0 sdb 8:16  0   [undef][ready] DGC,RAI
            36006016051d50e003a744871c912de11 1:0:1:0 sdc 8:32  1   [undef][ready] DGC,RAI
            36006016051d50e003a744871c912de11 2:0:0:0 sdd 8:48  1   [undef][ready] DGC,RAI
            36006016051d50e003a744871c912de11 2:0:1:0 sde 8:64  0   [undef][ready] DGC,RAI
            Found matching wwid [36006016051d50e003a744871c912de11] in bindings file.

          posted @ 2014-07-29 09:39 順其自然EVO 閱讀(3574) | 評(píng)論 (0)編輯 收藏

          Java訪問控制權(quán)限

           Java的訪問控制權(quán)限相比于C++等語(yǔ)言可能稍微復(fù)雜一點(diǎn),不過也不難理解。Java的訪問控制權(quán)限分為兩塊——“類或接口的訪問控制權(quán)限”與“變量和方法的訪問控制權(quán)限”。
            1.類或接口的訪問控制權(quán)限
            類或接口的訪問控制權(quán)限是指能不能用該類建立對(duì)象,接口能不能被實(shí)現(xiàn)等等。能夠修飾類或接口的訪問控制權(quán)限的修飾符(modifier)只有兩個(gè)——public和friendly.不過,值得一說的是friendly并不是Java的關(guān)鍵字,它只是一個(gè)習(xí)慣叫法,指的是“沒有寫訪問控制權(quán)限修飾符”的情況。
            public修飾的類或接口在同一個(gè)包中的任何一個(gè)類中都可以被訪問。不同包呢?當(dāng)然能訪問啦,否則引包機(jī)制不就失效了嘛(因?yàn)橐喈?dāng)于拿到了一個(gè)包的public類或接口)。
            friendly修飾的類或接口在同一個(gè)包中的任何一個(gè)類中都可以被訪問(和public相同),不能被不同包中的類訪問。
            總結(jié):類或接口的訪問控制權(quán)限分為“包中”和“包外”。無論修飾符(modifier)是什么,在“包中”均可訪問。對(duì)于“包外”,public修飾的類或接口可以被訪問,friendly修飾的類或接口不能被訪問。
            2.變量和方法的訪問控制權(quán)限
            變量和方法的訪問控制權(quán)限的修飾符(modifier)有四個(gè)——public,protected,friendly和private.
            變量和方法在本類(定義該變量或方法的類)中不論訪問控制權(quán)限修飾符是什么,均可被訪問(這里先不考慮“靜態(tài)”的情況)。那么接下來只研究類外。類外也分“包內(nèi)”和“包外”,接下來就從這兩方面說起,并且研究“包外”時(shí)只考慮引入的包中的public類,因?yàn)閒riendly的類連直接被訪問都做不到,何談訪問變量和方法。
            public修飾的變量和方法在“包內(nèi)”和“包外”均可被訪問。
            protected修飾的變量和方法在“包內(nèi)”可以被訪問,在“包外”只能被子類訪問。
            friendly修飾的變量和方法在“包內(nèi)”可以被訪問,在“包外”不能被訪問。
            private修飾的變量和方法在“包內(nèi)”或“包外”均不能被訪問。
            總結(jié):對(duì)于“類外”,public,protected,friendly和private的嚴(yán)格性逐漸遞增。public可以說沒限制,protected剝奪了“包外”非子類的訪問能力,friendly在protected基礎(chǔ)上進(jìn)一步剝奪了“包外”子類的訪問能力,至此“包外”的訪問能力全無;private更嚴(yán)格,它在friendly基礎(chǔ)上更是一下剝奪了“包內(nèi)”的訪問能力。
            總的來說,看某個(gè)成員能否被訪問要分兩步:1.根據(jù)所在類的訪問控制權(quán)限看該類能否被訪問;2.根據(jù)該成員的訪問控制權(quán)限判斷取得所在類后該成員能否被訪問。

          posted @ 2014-07-29 09:24 順其自然EVO 閱讀(191) | 評(píng)論 (0)編輯 收藏

          測(cè)試即是文檔

            文檔需要全面,實(shí)時(shí)更新,并且易懂。我說的全面是指除了介紹程序的功能外還應(yīng)該覆蓋到代碼中一些重要的地方。對(duì)很多人來說文檔的重要性不言而喻,但很難保持它的及時(shí)性和準(zhǔn)確性。糟糕的文檔的后果通常會(huì)浪費(fèi)更多的資源和時(shí)間。往往都是出于一些錯(cuò)誤的原因而編寫的文檔。
            要求文檔的一些原因
            有很多原因?qū)е挛覀冃枰帉懳臋n。團(tuán)隊(duì)經(jīng)常會(huì)由于一些制度上的要求而編寫文檔,或者就是純粹出于無知。下面是一些編寫文檔的錯(cuò)誤的理由:
            有人認(rèn)為文檔和項(xiàng)目的成敗息息相關(guān)。
            文檔能夠證明某些人的存在。
            需求方除了文檔也不知道要什么好
            要你提供文檔的人也就是求個(gè)安心,知道事情都OK了
            工作流程提示說,你該創(chuàng)建文檔了
            文檔都是過時(shí)的
            軟件文檔的一個(gè)主要的問題就是它通常都不是最新的。代碼的某個(gè)部分可能發(fā)生了改動(dòng),但是文檔卻體現(xiàn)不出這個(gè)情況。這句話適用于幾乎所有的文檔,影響最大的其實(shí)還是需求和測(cè)試用例。不管你多努力,文檔的過期無可避免。
            文檔對(duì)誰(shuí)有用?
            取決于不同的受眾,文檔的類型和格式也會(huì)相應(yīng)地有所不同。開發(fā)人員,測(cè)試人員,客戶,主管,最終用戶都是文檔的最大的潛在用戶。
            開發(fā)人員
            開發(fā)人員不應(yīng)該依賴于文檔,因?yàn)樗鼈兺ǔ6际沁^時(shí)的。除此之外,沒有什么文檔能比代碼本身更能提供詳細(xì)以及最新的信息了。如果你想知道某個(gè)方法做了些什么,看下這個(gè)方法吧。不確定某個(gè)類是干嘛的?看一眼它。通常只有代碼寫的太差了才需要給它添加文檔。
            使用代碼本身作為文檔,這并不代表不需要其它的文檔了。關(guān)鍵是要避免冗余。如果看一下代碼就能獲取到系統(tǒng)的詳細(xì)信息,那么還可以有一些其它的文檔來提供快速導(dǎo)讀以及更高層面的一個(gè)概述的功能。代碼本身的文檔是回答不了這個(gè)系統(tǒng)是干嘛的或者這個(gè)系統(tǒng)用到了什么技術(shù)啊這種類型的問題。大多數(shù)情況下,對(duì)于開發(fā)人員而言,一個(gè)簡(jiǎn)單的README.md就足夠他快速入門的了。像項(xiàng)目描述,環(huán)境配置,安裝,構(gòu)建及打包指令這些東西對(duì)項(xiàng)目的新成員來說非常有用。但那之后,代碼就是你的圣經(jīng)。產(chǎn)品代碼提供了所有需要的詳細(xì)信息,而測(cè)試代碼則是作為產(chǎn)品代碼的內(nèi)在意圖的一個(gè)描述。測(cè)試用例就是可執(zhí)行的文檔,而TDD(測(cè)試驅(qū)動(dòng)開發(fā))就是實(shí)現(xiàn)它的最常見的方式。
            假設(shè)你用了某種持續(xù)集成的方式,如果測(cè)試-文檔(這里測(cè)試就是文檔,文檔也是測(cè)試)中有一部分不對(duì)了,這個(gè)用例會(huì)執(zhí)行失敗,它將會(huì)很快得到修復(fù)。持續(xù)集成解決了測(cè)試-文檔不正確的問題,不過它不能保證所有功能都是有文檔的。由于這個(gè)原因(當(dāng)然也有其它原因)測(cè)試-文檔應(yīng)當(dāng)用TDD的方式來創(chuàng)建。如果在代碼開發(fā)前,所有的功能都定義成測(cè)試用例,那么測(cè)試用例就能作為開發(fā)人員的一個(gè)完備的最新的文檔了。
            那團(tuán)隊(duì)的其它成員怎么辦?測(cè)試人員,客戶,主管,還有其它非碼農(nóng)呢,他們可能無法從產(chǎn)品和測(cè)試的代碼中獲取到所需要的信息。
            測(cè)試人員
            最常見的兩種測(cè)試就是黑盒測(cè)試白盒測(cè)試。這個(gè)區(qū)分很重要,因?yàn)樗鼘y(cè)試人員也分成了兩類,一撥是知道怎么寫代碼的,至少是能讀懂代碼的(白盒測(cè)試),另一撥是不懂代碼的(黑盒測(cè)試)。有的時(shí)候測(cè)試人員也兩樣都干。不過一般而言,測(cè)試都是不懂代碼的,因此對(duì)開發(fā)人員有用的文檔對(duì)他們來說是沒意義的。如果說要從代碼中剝離出文檔的話,單元測(cè)試可不是什么合適的東西。這就是BDD(行為驅(qū)動(dòng)開發(fā),Behavior Driven Development)存在的價(jià)值了。它能為非開發(fā)人員提供所需的文檔,但同時(shí)還兼?zhèn)銽DD和自動(dòng)化的優(yōu)點(diǎn)。
            客戶
            客戶需要能夠給系統(tǒng)增加新的功能,同時(shí)他們也需要獲取到關(guān)于當(dāng)前系統(tǒng)的重要信息。給他們的文檔可不能太技術(shù)了(代碼當(dāng)然不行),同時(shí)也得是最新的。行為驅(qū)動(dòng)開發(fā)(BDD,Behavior Driven Development)的故事和場(chǎng)景應(yīng)該是提供這類文檔的最佳方式了。它能夠作為驗(yàn)收標(biāo)準(zhǔn)(在代碼開發(fā)前),還可以反復(fù)的執(zhí)行,同時(shí)還能用自然語(yǔ)言編寫,這使得BDD不僅僅能夠保證文檔是最新的,同時(shí)它對(duì)那些不想看代碼的人來說也非常有用。
            可執(zhí)行的文檔
            文檔是軟件不可或缺的一部分。正如軟件的其它部分一樣,它也得經(jīng)常進(jìn)行測(cè)試,這樣才能保證它是準(zhǔn)確的并且是最新的。實(shí)現(xiàn)這個(gè)最有效的方法就是將這個(gè)可執(zhí)行的文檔能夠集成到你的持續(xù)集成系統(tǒng)里面。TDD是這個(gè)方向的不二選擇。從較低層面來看的話,單元測(cè)試就非常適合作為這個(gè)文檔。另一方面來說的話,在功能層面來說BDD是一個(gè)很好的方式,它可以使用自然語(yǔ)言來進(jìn)行描述,這保證了文檔的可讀性。

          posted @ 2014-07-29 09:22 順其自然EVO 閱讀(195) | 評(píng)論 (0)編輯 收藏

          Web前沿—HTML5 Form Data 對(duì)象的使用

            XMLHttpRequest Level 2 添加了一個(gè)新的接口——FormData。利用 FormData 對(duì)象,我們可以通過 JavaScript 用一些鍵值對(duì)來模擬一系列表單控件,我們還可以使用 XMLHttpRequest 的 send() 方法來異步的提交表單。與普通的 Ajax 相比,使用 FormData 的最大優(yōu)點(diǎn)就是我們可以異步上傳二進(jìn)制文件。
            創(chuàng)建一個(gè)FormData對(duì)象
            你可以先創(chuàng)建一個(gè)空的 FormData 對(duì)象,然后使用 append() 方法向該對(duì)象里添加字段,如下:
          var oMyForm = new FormData();
          oMyForm.append("username", "Groucho");
          oMyForm.append("accountnum", 123456); // 數(shù)字123456被立即轉(zhuǎn)換成字符串"123456"
          // fileInputElement中已經(jīng)包含了用戶所選擇的文件
          oMyForm.append("userfile", fileInputElement.files[0]);
          var oFileBody = "<a id="a"><b id="b">hey!</b></a>"; // Blob對(duì)象包含的文件內(nèi)容
          var oBlob = new Blob([oFileBody], { type: "text/xml"});
          oMyForm.append("webmasterfile", oBlob);
          var oReq = new XMLHttpRequest();
          oReq.open("POST", "http://foo.com/submitform.php");
          oReq.send(oMyForm);
            注:字段 "userfile" 和 "webmasterfile" 的值都包含了一個(gè)文件。通過 FormData.append() 方法賦給字段 "accountnum" 的數(shù)字被自動(dòng)轉(zhuǎn)換為字符(字段的值可以是一個(gè) Blob 對(duì)象,F(xiàn)ile對(duì)象或者字符串,剩下其他類型的值都會(huì)被自動(dòng)轉(zhuǎn)換成字符串)。
            在該例子中,我們創(chuàng)建了一個(gè)名為 oMyForm 的 FormData 對(duì)象,該對(duì)象中包含了名為"username","accountnum","userfile" 以及 "webmasterfile" 的字段名,然后使用XMLHttpRequest的 send() 方法把這些數(shù)據(jù)發(fā)送了出去。"webmasterfile" 字段的值不是一個(gè)字符串,還是一個(gè) Blob 對(duì)象。
            使用HTML表單來初始化一個(gè)FormData對(duì)象
            可以用一個(gè)已有的 form 元素來初始化 FormData 對(duì)象,只需要把這個(gè) form 元素作為參數(shù)傳入 FormData 構(gòu)造函數(shù)即可:
            var newFormData = new FormData(someFormElement);
            例如:
            var formElement = document.getElementById("myFormElement");
            var oReq = new XMLHttpRequest();
            oReq.open("POST", "submitform.php");
            oReq.send(new FormData(formElement));
            你還可以在已有表單數(shù)據(jù)的基礎(chǔ)上,繼續(xù)添加新的鍵值對(duì),如下:
            var formElement = document.getElementById("myFormElement");
            formData = new FormData(formElement);
            formData.append("serialnumber", serialNumber++);
            oReq.send(formData);
            你可以通過這種方式添加一些不想讓用戶編輯的固定字段,然后再發(fā)送. 使用FormData對(duì)象發(fā)送文件
            你還可以使用 FormData 來發(fā)送二進(jìn)制文件.首先在 HTML 中要有一個(gè)包含了文件輸入框的 form 元素:
          <form enctype="multipart/form-data" method="post" name="fileinfo">
          <label>Your email address:</label>
          <input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
          <label>Custom file label:</label>
          <input type="text" name="filelabel" size="12" maxlength="32" /><br />
          <label>File to stash:</label>
          <input type="file" name="file" required />
          </form>
          <div id="output"></div>
          <a href="javascript:sendForm()">Stash the file!</a>
            然后你就可以使用下面的代碼來異步的上傳用戶所選擇的文件:
          function sendForm() {
          var oOutput = document.getElementById("output");
          var oData = new FormData(document.forms.namedItem("fileinfo"));
          oData.append("CustomField", "This is some extra data");
          var oReq = new XMLHttpRequest();
          oReq.open("POST", "stash.php", true);
          oReq.onload = function(oEvent) {
          if (oReq.status == 200) {
          oOutput.innerHTML = "Uploaded!";
          } else {
          oOutput.innerHTML = "Error " + oReq.status + " occurred uploading your file.<br \/>";
          }
          };
          oReq.send(oData);
          }
            你還可以不借助 HTML 表單,直接向 FormData 對(duì)象中添加一個(gè) File 對(duì)象或者一個(gè) Blob 對(duì)象:
            data.append("myfile", myBlob);
            如果 FormData 對(duì)象中的某個(gè)字段值是一個(gè) Blob 對(duì)象,則在發(fā)送 HTTP 請(qǐng)求時(shí),代表該 Blob 對(duì)象所包含文件的文件名的 "Content-Disposition" 請(qǐng)求頭的值在不同的瀏覽器下有所不同,F(xiàn)irefox使用了固定的字符串"blob",而 Chrome 使用了一個(gè)隨機(jī)字符串。
            你還可以使用 jQuery 來發(fā)送 FormData,但必須要正確的設(shè)置相關(guān)選項(xiàng):
          var fd = new FormData(document.getElementById("fileinfo"));
          fd.append("CustomField", "This is some extra data");
          $.ajax({
          url: "stash.php",
          type: "POST",
          data: fd,
          processData: false,  // 告訴jQuery不要去處理發(fā)送的數(shù)據(jù)
          contentType: false   // 告訴jQuery不要去設(shè)置Content-Type請(qǐng)求頭
          });
            瀏覽器兼容性

          posted @ 2014-07-29 09:21 順其自然EVO 閱讀(3539) | 評(píng)論 (1)編輯 收藏

          代碼覆蓋率淺談

          在做單元測(cè)試時(shí),代碼覆蓋率常常被拿來作為衡量測(cè)試好壞的指標(biāo),甚至,用代碼覆蓋率來考核測(cè)試任務(wù)完成情況,比如,代碼覆蓋率必須達(dá)到80%或 90%。于是乎,測(cè)試人員費(fèi)盡心思設(shè)計(jì)案例覆蓋代碼。用代碼覆蓋率來衡量,有利也有有弊。本文我們就代碼覆蓋率展開討論,也歡迎同學(xué)們踴躍評(píng)論。
            首先,讓我們先來了解一下所謂的“代碼覆蓋率”。我找來了所謂的定義:
            代碼覆蓋率 = 代碼的覆蓋程度,一種度量方式。
            上面簡(jiǎn)短精悍的文字非常準(zhǔn)確的描述了代碼覆蓋率的含義。而代碼覆蓋程度的度量方式是有很多種的,這里介紹一下最常用的幾種:
            1. 語(yǔ)句覆蓋(StatementCoverage)
            又稱行覆蓋(LineCoverage),段覆蓋(SegmentCoverage),基本塊覆蓋(BasicBlockCoverage),這是最常用也是最常見的一種覆蓋方式,就是度量被測(cè)代碼中每個(gè)可執(zhí)行語(yǔ)句是否被執(zhí)行到了。這里說的是“可執(zhí)行語(yǔ)句”,因此就不會(huì)包括像C++的頭文件聲明,代碼注釋,空行,等等。非常好理解,只統(tǒng)計(jì)能夠執(zhí)行的代碼被執(zhí)行了多少行。需要注意的是,單獨(dú)一行的花括號(hào){} 也常常被統(tǒng)計(jì)進(jìn)去。語(yǔ)句覆蓋常常被人指責(zé)為“最弱的覆蓋”,它只管覆蓋代碼中的執(zhí)行語(yǔ)句,卻不考慮各種分支的組合等等。假如你的上司只要求你達(dá)到語(yǔ)句覆蓋,那么你可以省下很多功夫,但是,換來的確實(shí)測(cè)試效果的不明顯,很難更多地發(fā)現(xiàn)代碼中的問題。
            這里舉一個(gè)不能再簡(jiǎn)單的例子,我們看下面的被測(cè)試代碼:
            int foo(int a, int b)
            {
            return  a / b;
            }
            假如我們的測(cè)試人員編寫如下測(cè)試案例:
            TeseCase: a = 10, b = 5
            測(cè)試人員的測(cè)試結(jié)果會(huì)告訴你,他的代碼覆蓋率達(dá)到了100%,并且所有測(cè)試案例都通過了。然而遺憾的是,我們的語(yǔ)句覆蓋率達(dá)到了所謂的100%,但是卻沒有發(fā)現(xiàn)最簡(jiǎn)單的Bug,比如,當(dāng)我讓b=0時(shí),會(huì)拋出一個(gè)除零異常。
            正因如此,假如上面只要求測(cè)試人員語(yǔ)句覆蓋率達(dá)到多少的話,測(cè)試人員只要鉆鉆空子,專門針對(duì)如何覆蓋代碼行編寫測(cè)試案例,就很容易達(dá)到主管的要求。當(dāng)然了,這同時(shí)說明了幾個(gè)問題:
            1.主管只使用語(yǔ)句覆蓋率來考核測(cè)試人員本身就有問題。
            2.測(cè)試人員的目的是為了測(cè)好代碼,鉆如此的空子是缺乏職業(yè)道德的。
            3.是否應(yīng)該采用更好的考核方式來考核測(cè)試人員的工作
            為了尋求更好的考核標(biāo)準(zhǔn),我們必須先了解完代碼覆蓋率到底還有哪些,如果你的主管只知道語(yǔ)句覆蓋,行覆蓋,那么你應(yīng)該主動(dòng)向他介紹還有更多的覆蓋方式。比如:
            2. 判定覆蓋(DecisionCoverage)
            又稱分支覆蓋(BranchCoverage),所有邊界覆蓋(All-EdgesCoverage),基本路徑覆蓋(BasicPathCoverage),判定路徑覆蓋(Decision-Decision-Path)。它度量程序中每一個(gè)判定的分支是否都被測(cè)試到了。這句話是需要進(jìn)一步理解的,應(yīng)該非常容易和下面說到的條件覆蓋混淆。因此我們直接介紹第三種覆蓋方式,然后和判定覆蓋一起來對(duì)比,就明白兩者是怎么回事了。
            3. 條件覆蓋(ConditionCoverage)
            它度量判定中的每個(gè)子表達(dá)式結(jié)果true和false是否被測(cè)試到了。為了說明判定覆蓋和條件覆蓋的區(qū)別,我們來舉一個(gè)例子,假如我們的被測(cè)代碼如下:
            int foo(int a, int b)
            {
            if (a < 10 || b < 10) // 判定
            {
            return 0; // 分支一
            }
            else
            {
            return 1; // 分支二
            }
            }
            設(shè)計(jì)判定覆蓋案例時(shí),我們只需要考慮判定結(jié)果為true和false兩種情況,因此,我們?cè)O(shè)計(jì)如下的案例就能達(dá)到判定覆蓋率100%:
            TestCaes1: a = 5, b = 任意數(shù)字  覆蓋了分支一
            TestCaes2: a = 15, b = 15          覆蓋了分支二
            設(shè)計(jì)條件覆蓋案例時(shí),我們需要考慮判定中的每個(gè)條件表達(dá)式結(jié)果,為了覆蓋率達(dá)到100%,我們?cè)O(shè)計(jì)了如下的案例:
            TestCase1: a = 5, b = 5       true,  true
            TestCase4: a = 15, b = 15   false, false
            通過上面的例子,我們應(yīng)該很清楚了判定覆蓋和條件覆蓋的區(qū)別。需要特別注意的是:條件覆蓋不是將判定中的每個(gè)條件表達(dá)式的結(jié)果進(jìn)行排列組合,而是只要每個(gè)條件表達(dá)式的結(jié)果true和false測(cè)試到了就OK了。因此,我們可以這樣推論:完全的條件覆蓋并不能保證完全的判定覆蓋。比如上面的例子,假如我設(shè)計(jì)的案例為:
            TestCase1: a = 5, b = 15  true,  false   分支一
            TestCase1: a = 15, b = 5  false, true    分支一
            我們看到,雖然我們完整的做到了條件覆蓋,但是我們卻沒有做到完整的判定覆蓋,我們只覆蓋了分支一。上面的例子也可以看出,這兩種覆蓋方式看起來似乎都不咋滴。我們接下來看看第四種覆蓋方式。
           4. 路徑覆蓋(PathCoverage)
            又稱斷言覆蓋(PredicateCoverage)。它度量了是否函數(shù)的每一個(gè)分支都被執(zhí)行了。 這句話也非常好理解,就是所有可能的分支都執(zhí)行一遍,有多個(gè)分支嵌套時(shí),需要對(duì)多個(gè)分支進(jìn)行排列組合,可想而知,測(cè)試路徑隨著分支的數(shù)量指數(shù)級(jí)別增加。比如下面的測(cè)試代碼中有兩個(gè)判定分支:
            int foo(int a, int b)
            {
            int nReturn = 0;
            if (a < 10)
            {// 分支一
            nReturn += 1;
            }
            if (b < 10)
            {// 分支二
            nReturn += 10;
            }
            return nReturn;
            }
            對(duì)上面的代碼,我們分別針對(duì)我們前三種覆蓋方式來設(shè)計(jì)測(cè)試案例:
            a. 語(yǔ)句覆蓋
            TestCase a = 5, b = 5   nReturn = 11
            語(yǔ)句覆蓋率100%
            b. 判定覆蓋
            TestCase1 a = 5,   b = 5     nReturn = 11
            TestCase2 a = 15, b = 15   nReturn = 0
            判定覆蓋率100%
            c. 條件覆蓋
            TestCase1 a = 5,   b = 15   nReturn = 1
            TestCase2 a = 15, b = 5     nReturn = 10
            條件覆蓋率100%
            我們看到,上面三種覆蓋率結(jié)果看起來都很酷!都達(dá)到了100%!主管可能會(huì)非常的開心,但是,讓我們?cè)偃プ屑?xì)的看看,上面被測(cè)代碼中,nReturn的結(jié)果一共有四種可能的返回值:0,1,10,11,而我們上面的針對(duì)每種覆蓋率設(shè)計(jì)的測(cè)試案例只覆蓋了部分返回值,因此,可以說使用上面任一覆蓋方式,雖然覆蓋率達(dá)到了100%,但是并沒有測(cè)試完全。接下來我們來看看針對(duì)路徑覆蓋設(shè)計(jì)出來的測(cè)試案例:
            TestCase1 a = 5,    b = 5     nReturn = 0
            TestCase2 a = 15,  b = 5     nReturn = 1
            TestCase3 a = 5,    b = 15   nReturn = 10
            TestCase4 a = 15,  b = 15   nReturn = 11
            路徑覆蓋率100%
            太棒了!路徑覆蓋將所有可能的返回值都測(cè)試到了。這也正是它被很多人認(rèn)為是“最強(qiáng)的覆蓋”的原因了。
            還有一些其他的覆蓋方式,如:循環(huán)覆蓋(LoopCoverage),它度量是否對(duì)循環(huán)體執(zhí)行了零次,一次和多余一次循環(huán)。剩下一些其他覆蓋方式就不介紹了。
            總結(jié)
            通過上面的學(xué)習(xí),我們?cè)倩仡^想想,覆蓋率數(shù)據(jù)到底有多大意義。我總結(jié)了如下幾個(gè)觀點(diǎn),歡迎大家討論:
            a. 覆蓋率數(shù)據(jù)只能代表你測(cè)試過哪些代碼,不能代表你是否測(cè)試好這些代碼。(比如上面第一個(gè)除零Bug)
            b. 不要過于相信覆蓋率數(shù)據(jù)。
            c. 不要只拿語(yǔ)句覆蓋率(行覆蓋率)來考核你的測(cè)試人員。
            d. 路徑覆蓋率 > 判定覆蓋 > 語(yǔ)句覆蓋
            e. 測(cè)試人員不能盲目追求代碼覆蓋率,而應(yīng)該想辦法設(shè)計(jì)更多更好的案例,哪怕多設(shè)計(jì)出來的案例對(duì)覆蓋率一點(diǎn)影響也沒有。

          posted @ 2014-07-29 09:12 順其自然EVO 閱讀(210) | 評(píng)論 (0)編輯 收藏

          淺談關(guān)于HP UFT中的GUI測(cè)試局限

          使用HP UFT 12.00版本(主要是GUI測(cè)試)一段時(shí)間,有些小想法,本來是打算回復(fù)給hp相關(guān)人員,奈何郵件一直遭拒,所以暫且先放在這里吧。
            關(guān)于HP 的UFT,簡(jiǎn)單做一下評(píng)價(jià),總體來說是一款很好的軟件,極容易上手和使用(這個(gè)也估計(jì)只是我沒有往深入研究),測(cè)試流程和思路也很清晰,重點(diǎn)是和HP一些其他自動(dòng)化工具,比如Loadrunner,QC可以結(jié)合起來用,堪稱完美。拍完馬屁說點(diǎn)實(shí)際的。
            其實(shí)對(duì)于目前所在公司的項(xiàng)目,我一直很猶豫要不要引進(jìn)HP的這款軟件,首先我對(duì)于這款軟件不是很熟悉,當(dāng)然現(xiàn)在這個(gè)理由是可以排除的,對(duì)于這個(gè)軟件的效果怎么樣,我也不確定,之前公司沒有使用這個(gè)軟件,所以也沒有什么積累,一切都要從零開始。明確知道這個(gè)軟件可能在后期的回歸測(cè)試會(huì)減少點(diǎn)人力,但是前期的的腳本錄制,調(diào)試,以及維護(hù),感覺也不是一個(gè)小工程。
            學(xué)習(xí)使用HP UFT軟件的過程不算很艱難,網(wǎng)上的資料還算是比較多的,加上采用錄制的模式,只需點(diǎn)點(diǎn)點(diǎn)的就可以了,使用起來還是很輕松的,當(dāng)然也會(huì)遇到一些問題,不過在網(wǎng)上查查資料基本上可以解決大部分。底層的腳本錄制基本上解決的差不多了,開始關(guān)注整個(gè)測(cè)試流程框架,也就是在這個(gè)地方,突然間發(fā)現(xiàn)HPUFT的GUI測(cè)試不靈活,感覺有些死板。
            簡(jiǎn)單說就是動(dòng)作Action的執(zhí)行順序只能按你設(shè)定好的跑,由于之前本人是測(cè)試android產(chǎn)品的,有使用過Monkeyrunner相關(guān)的測(cè)試工具,對(duì)于這種按設(shè)定路線走的自動(dòng)化測(cè)試工具有些不是很習(xí)慣。于是乎,突發(fā)奇思妙想,要是HPUFT的GUI測(cè)試也可以做到這種隨機(jī)的測(cè)試就好了,當(dāng)然了也不是像Monkeyrunner那樣。
            初步的想法是將各個(gè)Action進(jìn)行封裝,采用隨機(jī)調(diào)用的方式執(zhí)行測(cè)試,調(diào)用的次數(shù)可以是隨機(jī)的也可以設(shè)定,這個(gè)整體架構(gòu)的改變會(huì)對(duì)Action的錄制有相應(yīng)的要求,比如說執(zhí)行完一個(gè)Action,它的出口和入口要一致,各個(gè)Action的要在同一級(jí)別,比如在同一頁(yè)面。如此可能會(huì)出現(xiàn)多個(gè)層次,比如一個(gè)Action中又可以劃分出多個(gè)Action,這個(gè)需要采用分層的思想進(jìn)行解決,至于要分多少層,使用者可以按照自己的軟件的特點(diǎn)進(jìn)行劃分。
            說的好像又些復(fù)雜了,簡(jiǎn)單的說就是按照一定的要求錄制Action,采用隨機(jī)的方式執(zhí)行Action。此方案可以檢測(cè)出不同功能之間因調(diào)用順序的不同而出現(xiàn)的BUG,實(shí)際測(cè)試也證明這種BUG是存在的,同時(shí),這種模式也使得該軟件的使用更為靈活。
            暫且想法就這些,后續(xù)有再補(bǔ)上。

          posted @ 2014-07-29 09:08 順其自然EVO 閱讀(1898) | 評(píng)論 (1)編輯 收藏

          僅列出標(biāo)題
          共394頁(yè): First 上一頁(yè) 76 77 78 79 80 81 82 83 84 下一頁(yè) Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 尼木县| 绵竹市| 泰州市| 泸水县| 静乐县| 沐川县| 龙泉市| 榕江县| 临猗县| 松滋市| 常德市| 名山县| 天峻县| 南通市| 抚松县| 金乡县| 永康市| 邓州市| 莱芜市| 温州市| 吉安市| 开鲁县| 焉耆| 黔东| 井研县| 勃利县| 社会| 中方县| 鄂伦春自治旗| 长沙县| 土默特左旗| 扎囊县| 微山县| 新津县| 扎赉特旗| 青神县| 丹巴县| 彭水| 女性| 临猗县| 河曲县|